浏览代码

Merge remote-tracking branch 'origin/developerA' into developerB

# Conflicts:
#	src/main/resources/config/dev/application-dev.yml
zhengjinyi 3 年之前
父节点
当前提交
b602b98a91
共有 85 个文件被更改,包括 5146 次插入6 次删除
  1. 98 0
      backup.sql
  2. 1 1
      src/main/java/com/caimei/www/controller/BaseController.java
  3. 8 0
      src/main/java/com/caimei/www/controller/GenerateApi.java
  4. 14 0
      src/main/java/com/caimei/www/controller/authorized/supplier/SupplierPageController.java
  5. 187 0
      src/main/java/com/caimei/www/controller/unlimited/EncyclopediaController.java
  6. 47 0
      src/main/java/com/caimei/www/mapper/BaikeDao.java
  7. 17 0
      src/main/java/com/caimei/www/mapper/BaseDao.java
  8. 6 0
      src/main/java/com/caimei/www/mapper/ProductDao.java
  9. 31 0
      src/main/java/com/caimei/www/pojo/baike/BaikeHotSearch.java
  10. 128 0
      src/main/java/com/caimei/www/pojo/baike/BaikeProduct.java
  11. 53 0
      src/main/java/com/caimei/www/pojo/baike/BaikeProductParam.java
  12. 51 0
      src/main/java/com/caimei/www/pojo/baike/BaikeProductQuestion.java
  13. 24 0
      src/main/java/com/caimei/www/pojo/baike/BaikeType.java
  14. 4 0
      src/main/java/com/caimei/www/service/generate/GenerateHtml.java
  15. 56 0
      src/main/java/com/caimei/www/service/generate/impl/GenerateHtmlImpl.java
  16. 17 1
      src/main/java/com/caimei/www/service/page/BaseService.java
  17. 36 0
      src/main/java/com/caimei/www/service/page/ProductService.java
  18. 17 0
      src/main/java/com/caimei/www/service/page/impl/BaseServiceImpl.java
  19. 67 0
      src/main/java/com/caimei/www/service/page/impl/ProductServiceImpl.java
  20. 3 0
      src/main/resources/mapper/ArticleMapper.xml
  21. 55 0
      src/main/resources/mapper/BaikeMapper.xml
  22. 16 0
      src/main/resources/mapper/BaseMapper.xml
  23. 31 0
      src/main/resources/mapper/ProductMapper.xml
  24. 11 0
      src/main/resources/static/css/encyclopedia/base.css
  25. 94 0
      src/main/resources/static/css/encyclopedia/common.css
  26. 40 0
      src/main/resources/static/css/encyclopedia/contact.css
  27. 100 0
      src/main/resources/static/css/encyclopedia/detail.css
  28. 105 0
      src/main/resources/static/css/encyclopedia/index.css
  29. 28 0
      src/main/resources/static/css/encyclopedia/map.css
  30. 35 0
      src/main/resources/static/css/encyclopedia/normalize.css
  31. 34 0
      src/main/resources/static/css/encyclopedia/pagination.css
  32. 50 0
      src/main/resources/static/css/supplier-center/article/article-edit.css
  33. 36 0
      src/main/resources/static/css/supplier-center/article/article-list.css
  34. 680 0
      src/main/resources/static/css/supplier-center/article/table.css
  35. 二进制
      src/main/resources/static/img/encyclopedia/contact.png
  36. 二进制
      src/main/resources/static/img/encyclopedia/h5-nav-close-btn.png
  37. 二进制
      src/main/resources/static/img/encyclopedia/h5-page-title-bg.png
  38. 二进制
      src/main/resources/static/img/encyclopedia/icon-icp@2x.png
  39. 二进制
      src/main/resources/static/img/encyclopedia/icon.png
  40. 二进制
      src/main/resources/static/img/encyclopedia/icon_m.png
  41. 二进制
      src/main/resources/static/img/encyclopedia/logo.png
  42. 二进制
      src/main/resources/static/img/encyclopedia/pc-icon-empty.png
  43. 二进制
      src/main/resources/static/img/encyclopedia/pc-page-title-bg.png
  44. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-0.png
  45. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-1.png
  46. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-2.png
  47. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-3.png
  48. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-4.png
  49. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-5.png
  50. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-6.png
  51. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-7.png
  52. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-8.png
  53. 二进制
      src/main/resources/static/img/encyclopedia/title-bg-9.png
  54. 36 0
      src/main/resources/static/js/base.js
  55. 30 0
      src/main/resources/static/js/common/serviceapi/encyclopedia.service.js
  56. 77 0
      src/main/resources/static/js/common/serviceapi/supplier.service.js
  57. 391 0
      src/main/resources/static/js/encyclopedia/common.js
  58. 81 0
      src/main/resources/static/js/encyclopedia/detail.js
  59. 90 0
      src/main/resources/static/js/encyclopedia/index.js
  60. 66 0
      src/main/resources/static/js/encyclopedia/moreFloor.js
  61. 105 0
      src/main/resources/static/js/encyclopedia/search.js
  62. 214 0
      src/main/resources/static/js/supplier-center/article/article-edit.js
  63. 227 0
      src/main/resources/static/js/supplier-center/article/article-list.js
  64. 158 0
      src/main/resources/static/js/supplier-center/article/formMixin.js
  65. 37 0
      src/main/resources/static/js/supplier-center/article/uploadMixin.js
  66. 1 1
      src/main/resources/static/js/supplier-center/setting/information.js
  67. 1 1
      src/main/resources/static/js/supplier-center/setting/password.js
  68. 2 1
      src/main/resources/static/js/utils.js
  69. 15 0
      src/main/resources/static/lib/wangEditor.min.js
  70. 1 0
      src/main/resources/templates/article/components/article-header.html
  71. 35 0
      src/main/resources/templates/encyclopedia/about.html
  72. 16 0
      src/main/resources/templates/encyclopedia/components/footer.html
  73. 44 0
      src/main/resources/templates/encyclopedia/components/header.html
  74. 59 0
      src/main/resources/templates/encyclopedia/contact.html
  75. 222 0
      src/main/resources/templates/encyclopedia/instrument-detail.html
  76. 93 0
      src/main/resources/templates/encyclopedia/instrument.html
  77. 125 0
      src/main/resources/templates/encyclopedia/map.html
  78. 93 0
      src/main/resources/templates/encyclopedia/more.html
  79. 203 0
      src/main/resources/templates/encyclopedia/product-detail.html
  80. 93 0
      src/main/resources/templates/encyclopedia/product.html
  81. 92 0
      src/main/resources/templates/encyclopedia/search.html
  82. 18 0
      src/main/resources/templates/index.html
  83. 175 0
      src/main/resources/templates/supplier-center/article/article-edit.html
  84. 160 0
      src/main/resources/templates/supplier-center/article/article-list.html
  85. 6 1
      src/main/resources/templates/supplier-center/components/tableft.html

+ 98 - 0
backup.sql

@@ -124,3 +124,101 @@ ALTER TABLE `cm_product_archive_file`
     ADD COLUMN `waterOssUrl` TEXT NULL COMMENT '水印oss链接' AFTER `ossUrl`;
 
 -- =================================== 2021年10月 呵呵优惠券 end =====================================
+-- =================================== 2021年11月 采美百科 start =====================================
+ALTER TABLE `info`
+    ADD COLUMN `publishSource` INT NULL DEFAULT 1 COMMENT '文章发布来源:1采美365网,2供应商' AFTER `source`,
+    ADD COLUMN `shopId` INT NULL COMMENT '供应商id,publishSource为2时才有值' AFTER `publishSource`,
+    ADD COLUMN `auditStatus` INT NULL DEFAULT 2 COMMENT '供应商文章审核状态:1待审核,2审核通过,3审核失败' AFTER `priorityIndex`,
+    ADD COLUMN `failReason` TEXT NULL COMMENT '审核失败理由' AFTER `auditStatus`;
+
+CREATE TABLE `cm_baike_hot_search` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `keyWord` VARCHAR(15) NULL COMMENT '热搜词',
+    `jumpType` INT NULL COMMENT '跳转方式:1仅搜索,2产品,3仪器,4链接',
+    `productId` INT NULL COMMENT '产品/仪器id',
+    `jumpLink` TEXT NULL COMMENT '跳转链接',
+    `sort` INT NULL COMMENT '排序值',
+    `status` INT NULL COMMENT '状态:0停用,1启用',
+    `addTime` DATETIME NULL COMMENT '添加时间',
+    `addBy` INT NULL COMMENT '添加人',
+    PRIMARY KEY (`id`));
+
+CREATE TABLE `cm_baike_banner` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `productPcBanner` TEXT NULL COMMENT '产品pc端banner',
+    `productAppBanner` TEXT NULL COMMENT '产品移动端banner',
+    `instrumentPcBanner` TEXT NULL COMMENT '仪器pc端banner',
+    `instrumentAppBanner` TEXT NULL COMMENT '仪器移动端banner',
+    `productLink` TEXT NULL COMMENT '产品banner跳转链接',
+    `instrumentLink` TEXT NULL COMMENT '仪器banner跳转链接',
+    `productStatus` INT NULL COMMENT '产品banner状态:0停用,1启用',
+    `instrumentStatus` INT NULL COMMENT '仪器banner状态:0停用,1启用',
+    PRIMARY KEY (`id`))
+    COMMENT = '采美百科产品仪器banner图';
+
+INSERT INTO `cm_baike_banner` (`id`) VALUES ('1');
+
+CREATE TABLE `cm_baike_type` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `typeSort` INT NULL COMMENT '分类类型:1产品,2仪器',
+    `name` VARCHAR(30) NULL COMMENT '分类名称',
+    `sort` INT NULL COMMENT '排序',
+    `status` INT NULL COMMENT '状态:0停用,1启用',
+    `addTime` DATETIME NULL COMMENT '添加时间',
+    `addBy` INT NULL COMMENT '添加人',
+    PRIMARY KEY (`id`))
+    COMMENT = '采美百科产品/仪器分类';
+
+CREATE TABLE `cm_baike_product` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `commodityType` INT NULL COMMENT '商品分类:1产品,2仪器',
+    `name` VARCHAR(50) NULL COMMENT '名称',
+    `alias` VARCHAR(50) NULL COMMENT '别名',
+    `discription` VARCHAR(300) NULL COMMENT '描述',
+    `seoKeyword` VARCHAR(50) NULL COMMENT 'seo关键词',
+    `image` TEXT NULL COMMENT '图片',
+    `authLink` TEXT NULL COMMENT '认证链接',
+    `authQrCode` TEXT NULL COMMENT '认证二维码',
+    `advantage` VARCHAR(500) NULL COMMENT '优点',
+    `disadvantage` VARCHAR(500) NULL COMMENT '缺点',
+    `principle` VARCHAR(500) NULL COMMENT '原理',
+    `brand` VARCHAR(50) NULL COMMENT '品牌',
+    `producePlace` VARCHAR(50) NULL COMMENT '产地',
+    `marketTime` DATETIME NULL COMMENT '上市时间',
+    `company` VARCHAR(50) NULL COMMENT '公司/供应商',
+    `nmpaTime` DATETIME NULL COMMENT 'NMPA认证时间',
+    `adaptiveMan` VARCHAR(500) NULL COMMENT '适应人群',
+    `unAdaptiveMan` VARCHAR(500) NULL COMMENT '不适应人群',
+    `aroundOperation` VARCHAR(500) NULL COMMENT '术前术后',
+    `publishTime` DATETIME NULL COMMENT '发布时间',
+    `basePv` INT NULL COMMENT '基础浏览量',
+    `actualPv` INT NULL COMMENT '实际浏览量',
+    `typeId` INT NULL COMMENT '分类id',
+    `topPosition` INT NULL COMMENT '置顶位',
+    `status` INT NULL COMMENT '状态:0停用,1启用',
+    `addTime` DATETIME NULL COMMENT '添加时间',
+    PRIMARY KEY (`id`))
+    COMMENT = '采美百科产品/仪器表';
+
+CREATE TABLE `cm_baike_product_param` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `productId` INT NULL COMMENT '产品/仪器id' ,
+    `name` VARCHAR(15) NULL COMMENT '参数名称',
+    `content` VARCHAR(50) NULL COMMENT '参数内容' ,
+    PRIMARY KEY (`id`))
+    COMMENT = '产品/仪器参数';
+
+CREATE TABLE `cm_baike_product_image` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `productId` INT NULL COMMENT '产品/仪器id',
+    `type` INT NULL COMMENT '图片类型:1产品/仪器认证,2效果展示',
+    `image` TEXT NULL COMMENT '图片',
+    PRIMARY KEY (`id`));
+
+CREATE TABLE `cm_baike_product_question` (
+    `id` int NOT NULL AUTO_INCREMENT,
+    `productId` int DEFAULT NULL COMMENT '产品/仪器id',
+    `question` varchar(150) COMMENT '问题',
+    `answer` varchar(45) COMMENT '答案',
+    PRIMARY KEY (`id`))
+-- =================================== 2021年11月 采美百科 end =====================================

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

@@ -32,7 +32,7 @@ public class BaseController {
     /** 错误页面 */
 	private static final String ERROR_PATH = "error/404";
 
-    private BaseService baseService;
+    public BaseService baseService;
     @Autowired
     public void setBaseService(BaseService baseService) {
         this.baseService = baseService;

+ 8 - 0
src/main/java/com/caimei/www/controller/GenerateApi.java

@@ -46,6 +46,14 @@ public class GenerateApi {
         return generateHtml.generateStaticFiles();
     }
 
+    /**
+     * 生成采美百科产品仪器页面
+     */
+    @PostMapping("/generate/baike/page")
+    public  String generateBaikePage(ServerWebExchange exchange,Integer commodityType) {
+        return generateHtml.generateBaikePage(exchange, commodityType);
+    }
+
 
 //    @PostMapping("/product/img/repair")
 //    public String repairProductImg() {

+ 14 - 0
src/main/java/com/caimei/www/controller/authorized/supplier/SupplierPageController.java

@@ -62,6 +62,10 @@ public class SupplierPageController extends BaseController {
     private static final String MESSAGE = "supplier-center/message/list";
     /** 供应商维修详情 */
     private static final String REPAIR_DETAIL = "supplier-center/repair/detail";
+    /** 供应商文章列表 */
+    private static final String ARTICLE_LIST = "supplier-center/article/article-list";
+    /** 供应商文章编辑页面 */
+    private static final String ARTICLE_EDIT = "supplier-center/article/article-edit";
 
 
     /** 我的采美 */
@@ -211,5 +215,15 @@ public class SupplierPageController extends BaseController {
         return REPAIR_DETAIL;
     }
 
+    /** 供应商文章列表 */
+    @GetMapping("/supplier/article/list.html")
+    public String supplierArticleList() {
+        return ARTICLE_LIST;
+    }
 
+    /** 供应商文章编辑页面 */
+    @GetMapping("/supplier/article/edit.html")
+    public String supplierArticleEdit() {
+        return ARTICLE_EDIT;
+    }
 }

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

@@ -0,0 +1,187 @@
+package com.caimei.www.controller.unlimited;
+
+import com.alibaba.fastjson.JSONArray;
+import com.caimei.www.controller.BaseController;
+import com.caimei.www.pojo.JsonModel;
+import com.caimei.www.pojo.baike.BaikeHotSearch;
+import com.caimei.www.pojo.baike.BaikeProduct;
+import com.caimei.www.pojo.baike.BaikeType;
+import com.caimei.www.pojo.page.ImageLink;
+import com.caimei.www.service.page.BaseService;
+import com.caimei.www.service.page.ProductService;
+import com.google.gson.JsonArray;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 采美文库
+ *
+ * @author : yuwenjun1997
+ * @date : 2021/11/23
+ */
+@Controller
+@RequestMapping("/encyclopedia")
+public class EncyclopediaController extends BaseController {
+
+    private static final String PRODUCT_LIST = "encyclopedia/product";
+    private static final String PRODUCT_DETAIL = "encyclopedia/product-detail";
+    private static final String INSTRUMENT_LIST = "encyclopedia/instrument";
+    private static final String INSTRUMENT_DETAIL = "encyclopedia/instrument-detail";
+    private static final String MORE_LIST = "encyclopedia/more";
+    private static final String SEARCH_PAGE = "encyclopedia/search";
+    private static final String CONTACT = "encyclopedia/contact";
+    private static final String ABOUT_US = "encyclopedia/about";
+    private static final String MAP = "encyclopedia/map";
+
+    private ProductService productService;
+
+    @Autowired
+    public void setProductService(ProductService productService) {
+        this.productService = productService;
+    }
+
+    /**
+     * 产品列表
+     */
+    @GetMapping("/product.html")
+    public String getProductList(final Model model) {
+        Integer commodityType = 1;
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        // banner图
+        ImageLink banner = baseService.getBaikeBannerImage(commodityType);
+        model.addAttribute("banner", banner);
+        // 分类列表
+        List<BaikeType> typeList = baseService.getBaikeTypeList(commodityType);
+        model.addAttribute("typeList", typeList);
+        // 产品仪器分类数据
+        JSONArray typeData = productService.getBaikeTypeJson(commodityType);
+        model.addAttribute("typeData", typeData);
+        return PRODUCT_LIST;
+    }
+
+    /**
+     * 产品详情
+     */
+    @GetMapping("/product-{id}.html")
+    public String getProductDetail(final Model model, @PathVariable("id") Integer productId) {
+        BaikeProduct baikeProduct = productService.getBaikeProductDetail(productId);
+        if (baikeProduct == null) {
+            return super.errorPath();
+        }
+        // 增加浏览量
+        productService.encyclopediaPv(productId);
+        model.addAttribute("baikeProduct", baikeProduct);
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        return PRODUCT_DETAIL;
+    }
+
+    /**
+     * 仪器列表
+     */
+    @GetMapping("/instrument.html")
+    public String getInstrumentList(final Model model) {
+        Integer commodityType = 2;
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        // banner图
+        ImageLink banner = baseService.getBaikeBannerImage(commodityType);
+        model.addAttribute("banner", banner);
+        // 分类列表
+        List<BaikeType> typeList = baseService.getBaikeTypeList(commodityType);
+        model.addAttribute("typeList", typeList);
+        // 产品仪器分类数据
+        JSONArray typeData = productService.getBaikeTypeJson(commodityType);
+        model.addAttribute("typeData", typeData);
+        return INSTRUMENT_LIST;
+    }
+
+    /**
+     * 仪器详情
+     */
+    @GetMapping("/instrument-{id}.html")
+    public String getInstrumentDetail(final Model model, @PathVariable("id") Integer productId) {
+        BaikeProduct baikeInstrument = productService.getBaikeProductDetail(productId);
+        if (baikeInstrument == null) {
+            return super.errorPath();
+        }
+        // 增加浏览量
+        productService.encyclopediaPv(productId);
+        model.addAttribute("baikeInstrument", baikeInstrument);
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        return INSTRUMENT_DETAIL;
+    }
+
+    /**
+     * 查看更多
+     */
+    @GetMapping("/more-{typeId}-{pageNum}-{pageSize}.html")
+    public String getMoreList(final Model model, @PathVariable("typeId") Integer typeId, @PathVariable("pageNum") Integer pageNum, @PathVariable("pageSize") Integer pageSize) {
+        BaikeType baikeType = productService.getBaikeType(typeId);
+        Map<String, Object> moreData = productService.getBaikeMoreJson(typeId, pageNum, pageSize);
+        moreData.put("typeId", typeId);
+        moreData.put("typeName", baikeType.getName());
+        model.addAttribute("moreData", moreData);
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        return MORE_LIST;
+    }
+
+    /**
+     * 搜索列表
+     */
+    @GetMapping("/search.html")
+    public String getSearchPage(final Model model) {
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        return SEARCH_PAGE;
+    }
+
+    /**
+     * 联系我们
+     */
+    @GetMapping("/contact.html")
+    public String getContact(final Model model) {
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        return CONTACT;
+    }
+
+    /**
+     * 关于我们
+     */
+    @GetMapping("/about.html")
+    public String getAboutUs(final Model model) {
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        model.addAttribute("searchHotWord", searchHotWord);
+        return ABOUT_US;
+    }
+
+    /**
+     * 关于我们位置定位
+     */
+    @GetMapping("/map.html")
+    public String getMap() {
+        return MAP;
+    }
+
+}

+ 47 - 0
src/main/java/com/caimei/www/mapper/BaikeDao.java

@@ -0,0 +1,47 @@
+package com.caimei.www.mapper;
+
+import com.caimei.www.pojo.baike.BaikeProduct;
+import com.caimei.www.pojo.baike.BaikeProductParam;
+import com.caimei.www.pojo.baike.BaikeProductQuestion;
+import com.caimei.www.pojo.baike.BaikeType;
+import com.caimei.www.pojo.classify.Bigtype;
+import com.caimei.www.pojo.classify.SmallType;
+import com.caimei.www.pojo.order.CartItem;
+import com.caimei.www.pojo.page.Parameter;
+import com.caimei.www.pojo.page.ProductDetail;
+import com.caimei.www.pojo.page.ProductList;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Aslee
+ * @date : 2021/11/25
+ */
+@Mapper
+public interface BaikeDao {
+    /**
+     * 查询采美百科产品/仪器详情数据
+     */
+    BaikeProduct getBaikeProductDetail(Integer productId);
+
+    List<BaikeProductParam> findParamList(Integer id);
+
+    /**
+     * 查询图片列表
+     *
+     * @param productId
+     * @param imageType 图片类型:1产品/仪器认证,2效果展示
+     * @return
+     */
+    List<String> findImageList(@Param("productId") Integer productId, @Param("imageType") int imageType);
+
+    List<BaikeProductQuestion> findQuestionList(Integer productId);
+
+    void encyclopediaPv(Integer id);
+
+    BaikeType getBaikeType(Integer typeId);
+}

+ 17 - 0
src/main/java/com/caimei/www/mapper/BaseDao.java

@@ -1,5 +1,7 @@
 package com.caimei.www.mapper;
 
+import com.caimei.www.pojo.baike.BaikeHotSearch;
+import com.caimei.www.pojo.baike.BaikeType;
 import com.caimei.www.pojo.page.*;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -42,4 +44,19 @@ public interface BaseDao {
      */
     List<BaseLink> getFriendLinks();
 
+    /**
+     * 采美百科搜索关键词
+     * @return
+     */
+    List<BaikeHotSearch> getBaikeSearchHotWord();
+
+    /**
+     * 采美百科banner图
+     */
+    ImageLink getBaikeBannerImage(Integer commodityType);
+
+    /**
+     * 采美百科分类列表
+     */
+    List<BaikeType> getBaikeTypeList(Integer commodityType);
 }

+ 6 - 0
src/main/java/com/caimei/www/mapper/ProductDao.java

@@ -3,6 +3,7 @@ package com.caimei.www.mapper;
 import com.caimei.www.pojo.classify.Bigtype;
 import com.caimei.www.pojo.classify.SmallType;
 import com.caimei.www.pojo.order.CartItem;
+import com.caimei.www.pojo.baike.BaikeProduct;
 import com.caimei.www.pojo.page.Parameter;
 import com.caimei.www.pojo.page.ProductDetail;
 import com.caimei.www.pojo.page.ProductList;
@@ -71,4 +72,9 @@ public interface ProductDao {
      * 修复商品图片(临时)
      */
     List<String> getProductInfo();
+
+    /**
+     * 查询采美百科产品/仪器详情数据
+     */
+    BaikeProduct getBaikeProductDetail(Integer productId);
 }

+ 31 - 0
src/main/java/com/caimei/www/pojo/baike/BaikeHotSearch.java

@@ -0,0 +1,31 @@
+package com.caimei.www.pojo.baike;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ *
+ * @author : Aslee
+ * @date : 2020/11/30
+ */
+@Data
+public class BaikeHotSearch implements Serializable {
+    /**
+     * 热搜关键词
+     */
+    private String keyWord;
+    /**
+     * 跳转方式:1仅搜索,2产品,3仪器,4链接
+     */
+    private Integer jumpType;
+    /**
+     * 跳转商品id
+     */
+    private Integer productId;
+    /**
+     * 跳转链接
+     */
+    private String jumpLink;
+}

+ 128 - 0
src/main/java/com/caimei/www/pojo/baike/BaikeProduct.java

@@ -0,0 +1,128 @@
+package com.caimei.www.pojo.baike;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Aslee
+ * @date : 2021/11/25
+ */
+@Data
+public class BaikeProduct implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer productId;
+
+    /**
+     * 产品/仪器图片
+     */
+    private String image;
+
+    /**
+     * 产品/仪器名称
+     */
+    private String name;
+
+    /**
+     * 概述
+     */
+    private String discription;
+    /**
+     * 概述
+     */
+    private String seoKeyword;
+    /**
+     * 认证链接
+     */
+    private String authLink;
+    /**
+     * 认证二维码
+     */
+    private String authQrCode;
+    /**
+     * 别名
+     */
+    private String alias;
+    /**
+     * 优点
+     */
+    private String advantage;
+    /**
+     * 缺点
+     */
+    private String disadvantage;
+    /**
+     * 原理
+     */
+    private String principle;
+    /**
+     * 品牌
+     */
+    private String brand;
+    /**
+     * 产地
+     */
+    private String producePlace;
+    /**
+     * 上市时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date marketTime;
+    /**
+     * 公司/厂商
+     */
+    private String company;
+    /**
+     * NMPA认证时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date nmpaTime;
+    /**
+     * 适应人群
+     */
+    private String adaptiveMan;
+    /**
+     * 不适应人群
+     */
+    private String unAdaptiveMan;
+    /**
+     * 术前术后
+     */
+    private String aroundOperation;
+    /**
+     * 发布时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date publishTime;
+    /**
+     * 是否置顶标识:0否,1是
+     */
+    private Integer topFlag;
+    /**
+     * 分类名称
+     */
+    private String typeName;
+    /**
+     * 参数列表
+     */
+    private List<BaikeProductParam> paramList;
+    /**
+     * 产品认证图片列表
+     */
+    private List<String> authImageList;
+    /**
+     * 效果展示图片列表
+     */
+    private List<String> displayImageList;
+    /**
+     * 问题列表
+     */
+    private List<BaikeProductQuestion> questionList;
+}

+ 53 - 0
src/main/java/com/caimei/www/pojo/baike/BaikeProductParam.java

@@ -0,0 +1,53 @@
+package com.caimei.www.pojo.baike;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 采美百科商品参数
+ * @author Aslee
+ * @date : 2021/11/25
+ */
+@Data
+public class BaikeProductParam implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	/**
+	 * 采美百科商品Id
+	 */
+	private Integer productId;
+	/**
+	 * 参数名称
+	 */
+	private String name;
+	/**
+	 * 参数信息
+	 */
+	private String content;
+
+	public Integer getProductId() {
+		return productId;
+	}
+
+	public void setProductId(Integer productId) {
+		this.productId = productId;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+}

+ 51 - 0
src/main/java/com/caimei/www/pojo/baike/BaikeProductQuestion.java

@@ -0,0 +1,51 @@
+package com.caimei.www.pojo.baike;
+
+
+import java.io.Serializable;
+
+/**
+ * 采美百科商品问题
+ * @author Aslee
+ * @date : 2021/11/25
+ */
+public class BaikeProductQuestion implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	/**
+	 * 采美百科商品Id
+	 */
+	private Integer productId;
+	/**
+	 * 问题
+	 */
+	private String question;
+	/**
+	 * 回答
+	 */
+	private String answer;
+
+
+	public Integer getProductId() {
+		return productId;
+	}
+
+	public void setProductId(Integer productId) {
+		this.productId = productId;
+	}
+
+	public String getQuestion() {
+		return question;
+	}
+
+	public void setQuestion(String question) {
+		this.question = question;
+	}
+
+	public String getAnswer() {
+		return answer;
+	}
+
+	public void setAnswer(String answer) {
+		this.answer = answer;
+	}
+}

+ 24 - 0
src/main/java/com/caimei/www/pojo/baike/BaikeType.java

@@ -0,0 +1,24 @@
+package com.caimei.www.pojo.baike;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Aslee
+ * @date : 2020/11/25
+ */
+@Data
+public class BaikeType implements Serializable {
+    /**
+     * 分类id
+     */
+    private Integer typeId;
+    /**
+     * 分类名称
+     */
+    private String name;
+}

+ 4 - 0
src/main/java/com/caimei/www/service/generate/GenerateHtml.java

@@ -26,4 +26,8 @@ public interface GenerateHtml {
      */
     String generateStaticFiles();
 
+    /**
+     * 生成采美百科产品仪器页面
+     */
+    String generateBaikePage(ServerWebExchange exchange, Integer commodityType);
 }

+ 56 - 0
src/main/java/com/caimei/www/service/generate/impl/GenerateHtmlImpl.java

@@ -2,6 +2,8 @@ package com.caimei.www.service.generate.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.caimei.www.pojo.baike.BaikeHotSearch;
+import com.caimei.www.pojo.baike.BaikeType;
 import com.caimei.www.pojo.page.BaseLink;
 import com.caimei.www.pojo.page.ImageLink;
 import com.caimei.www.pojo.page.TopMenu;
@@ -118,6 +120,33 @@ public class GenerateHtmlImpl implements GenerateHtml {
         }
     }
 
+    /**
+     * 生成采美百科产品仪器页面
+     */
+    @Override
+    public String generateBaikePage(ServerWebExchange exchange, Integer commodityType) {
+        // 上下文
+        SpringWebFluxContext context = new SpringWebFluxContext(exchange);
+        // 设置页面数据
+        context.setVariables(setStaticBaikePage(commodityType));
+        // 输出流  /product/type-287.html
+        File dest = new File(destPath + "/encyclopedia", 1 == commodityType ? "product.html" : "instrument.html");
+        if (dest.exists()) {
+            boolean delete = dest.delete();
+        }
+        String commodityName = 1 == commodityType ? "产品" : "仪器";
+        try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) {
+            // 生成html
+            templateEngine.process("product/instrument", context, writer);
+            log.info("[静态页服务]:生成静态采美百科" + commodityName + "页成功! ^_^");
+            return "[静态页服务]:生成静态采美百科" + commodityName + "页成功! ^_^";
+        } catch (Exception e) {
+            boolean delete = dest.delete();
+            log.error("[静态页服务]:生成静态采美百科" + commodityName + "页异常!", e);
+            return "[静态页服务]:生成静态采美百科" + commodityName + "页异常!"+e.toString();
+        }
+    }
+
     /**
      * 拷贝静态资源文件
      */
@@ -224,6 +253,33 @@ public class GenerateHtmlImpl implements GenerateHtml {
         return map;
     }
 
+    private Map<String, Object> setStaticBaikePage(Integer commodityType) {
+        Map<String, Object> map = new HashMap<>();
+        // 环境变量,(2:正式环境,1:测试环境,0:开发环境)
+        map.put("siteEnv", siteEnv);
+        map.put("agent", "");
+        // 静态文件版本号
+        map.put("version", buildTime);
+        // spi服务器地址
+        map.put("coreServer", coreServer);
+        // 搜索热门关键字
+        List<BaikeHotSearch> searchHotWord = baseService.getBaikeSearchHotWord();
+        map.put("searchHotWord", searchHotWord);
+        // banner图
+        ImageLink banner = baseService.getBaikeBannerImage(commodityType);
+        map.put("banner", banner);
+        // 分类列表
+        List<BaikeType> typeList = baseService.getBaikeTypeList(commodityType);
+        map.put("typeList", typeList);
+        // 产品仪器分类数据
+        JSONArray typeData = productService.getBaikeTypeJson(commodityType);
+        map.put("typeData", typeData);
+
+        log.debug(map.toString());
+
+        return map;
+    }
+
     /**
      * 资源清单获取并拷贝
      */

+ 17 - 1
src/main/java/com/caimei/www/service/page/BaseService.java

@@ -1,12 +1,13 @@
 package com.caimei.www.service.page;
 
 import com.alibaba.fastjson.JSONObject;
+import com.caimei.www.pojo.baike.BaikeHotSearch;
+import com.caimei.www.pojo.baike.BaikeType;
 import com.caimei.www.pojo.page.BaseLink;
 import com.caimei.www.pojo.page.ImageLink;
 import com.caimei.www.pojo.page.TopMenu;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * Description
@@ -40,4 +41,19 @@ public interface BaseService {
      * 分类菜单
      */
     List<JSONObject> getClassifyJson();
+
+    /**
+     * 采美百科热搜关键词
+     */
+    List<BaikeHotSearch> getBaikeSearchHotWord();
+
+    /**
+     * 采美百科banner图
+     */
+    ImageLink getBaikeBannerImage(Integer commodityType);
+
+    /**
+     * 采美百科分类列表
+     */
+    List<BaikeType> getBaikeTypeList(Integer commodityType);
 }

+ 36 - 0
src/main/java/com/caimei/www/service/page/ProductService.java

@@ -2,6 +2,9 @@ package com.caimei.www.service.page;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.caimei.www.pojo.JsonModel;
+import com.caimei.www.pojo.baike.BaikeProduct;
+import com.caimei.www.pojo.baike.BaikeType;
 import com.caimei.www.pojo.page.ProductDetail;
 
 import java.util.Map;
@@ -57,4 +60,37 @@ public interface ProductService {
      * @param params
      */
     JSONObject getProductListJson(String params);
+
+    /**
+     * 获取采美百科产品/仪器列表数据
+     */
+    JSONArray getBaikeTypeJson(Integer commodityType);
+
+    /**
+     * 获取采美百科产品/仪器详情数据
+     */
+    BaikeProduct getBaikeProductDetail(Integer productId);
+
+    /**
+     * 增加采美百科浏览量
+     * @param id  产品/仪器id
+     * @return
+     */
+    JsonModel encyclopediaPv(Integer id);
+
+    /**
+     * 更多页面数据
+     * @param typeId    分类id
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    Map<String, Object> getBaikeMoreJson(Integer typeId, Integer pageNum, Integer pageSize);
+
+    /**
+     * 根据分类id获取百科分类
+     * @param typeId    分类id
+     * @return
+     */
+    BaikeType getBaikeType(Integer typeId);
 }

+ 17 - 0
src/main/java/com/caimei/www/service/page/impl/BaseServiceImpl.java

@@ -3,6 +3,8 @@ package com.caimei.www.service.page.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.caimei.www.mapper.BaseDao;
+import com.caimei.www.pojo.baike.BaikeHotSearch;
+import com.caimei.www.pojo.baike.BaikeType;
 import com.caimei.www.pojo.page.*;
 import com.caimei.www.service.page.BaseService;
 import com.caimei.www.utils.RequestUtil;
@@ -122,4 +124,19 @@ public class BaseServiceImpl implements BaseService {
         }
     }
 
+    @Override
+    public List<BaikeHotSearch> getBaikeSearchHotWord() {
+        List<BaikeHotSearch> searchHotword = baseDao.getBaikeSearchHotWord();
+        return searchHotword;
+    }
+
+    @Override
+    public ImageLink getBaikeBannerImage(Integer commodityType) {
+        return baseDao.getBaikeBannerImage(commodityType);
+    }
+
+    @Override
+    public List<BaikeType> getBaikeTypeList(Integer commodityType) {
+        return baseDao.getBaikeTypeList(commodityType);
+    }
 }

+ 67 - 0
src/main/java/com/caimei/www/service/page/impl/ProductServiceImpl.java

@@ -2,7 +2,13 @@ package com.caimei.www.service.page.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.caimei.www.mapper.BaikeDao;
 import com.caimei.www.mapper.ProductDao;
+import com.caimei.www.pojo.JsonModel;
+import com.caimei.www.pojo.baike.BaikeProduct;
+import com.caimei.www.pojo.baike.BaikeProductParam;
+import com.caimei.www.pojo.baike.BaikeProductQuestion;
+import com.caimei.www.pojo.baike.BaikeType;
 import com.caimei.www.pojo.page.ProductDetail;
 import com.caimei.www.service.page.ProductService;
 import com.caimei.www.utils.ImageUtil;
@@ -14,6 +20,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.List;
 import java.util.Map;
 
 
@@ -32,6 +39,8 @@ public class ProductServiceImpl implements ProductService {
     private String coreServer;
     @Resource
     private ProductDao productDao;
+    @Resource
+    private BaikeDao baikeDao;
 
     /**
      * 根据商品Id获取详情
@@ -170,4 +179,62 @@ public class ProductServiceImpl implements ProductService {
         }
     }
 
+    @Override
+    public JSONArray getBaikeTypeJson(Integer commodityType) {
+        String dataUrl = coreServer + "/commodity/baike/page?commodityType=" + commodityType;
+        try {
+            String classifyResult = RequestUtil.sendGet(dataUrl);
+            log.info(classifyResult);
+            Map<String, Object> classifyMap = JSONObject.parseObject(classifyResult, Map.class);
+            return (JSONArray) classifyMap.get("data");
+        } catch (Exception e) {
+            log.error("try-catch:",e);
+            return null;
+        }
+    }
+
+    @Override
+    public Map<String, Object> getBaikeMoreJson(Integer typeId, Integer pageNum, Integer pageSize) {
+        String dataUrl = coreServer + "/commodity/baike/type?typeId=" + typeId + "&pageNum=" + pageNum + "&pageSize=" + pageSize;
+        try {
+            String moreResult = RequestUtil.sendGet(dataUrl);
+            log.debug(moreResult);
+            Map<String, Object> moreMap = JSONObject.parseObject(moreResult, Map.class);
+            return JSONObject.parseObject(String.valueOf(moreMap.get("data")), Map.class);
+        } catch (Exception e) {
+            log.error("try-catch:",e);
+            return null;
+        }
+    }
+
+    @Override
+    public BaikeType getBaikeType(Integer typeId) {
+        return baikeDao.getBaikeType(typeId);
+    }
+
+    @Override
+    public BaikeProduct getBaikeProductDetail(Integer productId) {
+        BaikeProduct baikeProduct = baikeDao.getBaikeProductDetail(productId);
+        if (null != baikeProduct) {
+            // 参数列表
+            List<BaikeProductParam> paramList = baikeDao.findParamList(productId);
+            baikeProduct.setParamList(paramList);
+            // 产品/仪器认证图片列表
+            List<String> authImageList = baikeDao.findImageList(productId, 1);
+            baikeProduct.setAuthImageList(authImageList);
+            // 效果展示图片列表
+            List<String> displayImageList = baikeDao.findImageList(productId, 2);
+            baikeProduct.setDisplayImageList(displayImageList);
+            // 问题列表
+            List<BaikeProductQuestion> questionList = baikeDao.findQuestionList(productId);
+            baikeProduct.setQuestionList(questionList);
+        }
+        return baikeProduct;
+    }
+
+    @Override
+    public JsonModel encyclopediaPv(Integer id) {
+        baikeDao.encyclopediaPv(id);
+        return JsonModel.success();
+    }
 }

+ 3 - 0
src/main/resources/mapper/ArticleMapper.xml

@@ -30,6 +30,7 @@
 		from info a
 		where a.recommendStatus = 1
 		and a.enabledStatus = 1
+		and a.auditStatus = 2
 		and NOW() >= a.pubdate
 		<if test="typeId != null and typeId != ''">
 			and a.typeId = #{typeId}
@@ -61,6 +62,7 @@
 			</if>
 			and NOW() >= a.pubdate
 			and a.enabledStatus = 1
+        	and a.auditStatus = 2
 		</where>
 		order by a.pubdate desc
 	</select>
@@ -122,6 +124,7 @@
 		WHERE
 		  a.id = #{id}
 		  AND a.enabledStatus = 1
+		  and a.auditStatus = 2
 	</select>
 	<select id="findLabelIdsByName" resultType="java.lang.Integer">
 		select id

+ 55 - 0
src/main/resources/mapper/BaikeMapper.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.caimei.www.mapper.BaikeDao">
+	<update id="encyclopediaPv">
+		update cm_baike_product set actualPv = actualPv + 1 where id = #{id}
+	</update>
+	<select id="getBaikeProductDetail" resultType="com.caimei.www.pojo.baike.BaikeProduct">
+		select a.id              AS "id",
+			   a.commodityType   AS "commodityType",
+			   a.name            AS "name",
+			   a.alias           AS "alias",
+			   a.discription     AS "discription",
+			   a.seoKeyword      AS "seoKeyword",
+			   a.image           AS "image",
+		       a.authLink 		 AS "authLink",
+		       a.authQrCode      AS "authQrCode",
+			   a.advantage       AS "advantage",
+			   a.disadvantage    AS "disadvantage",
+			   a.principle       AS "principle",
+			   a.brand           AS "brand",
+			   a.producePlace    AS "producePlace",
+			   a.marketTime      AS "marketTime",
+			   a.company         AS "company",
+			   a.nmpaTime        AS "nmpaTime",
+			   a.adaptiveMan     AS "adaptiveMan",
+			   a.unAdaptiveMan   AS "unAdaptiveMan",
+			   a.aroundOperation AS "aroundOperation",
+			   a.publishTime     AS "publishTime",
+			   a.basePv          AS "basePv",
+			   a.actualPv        AS "actualPv",
+			   a.typeId          AS "typeId",
+			   a.topPosition     AS "topPosition",
+			   a.status          AS "status",
+			   a.addTime         AS "addTime",
+			   cbt.name          as "typeName"
+		from cm_baike_product a
+				 left join cm_baike_type cbt on a.typeId = cbt.id
+		where a.id = #{productId} and a.status = 1 and NOW() > publishTime;
+	</select>
+
+	<select id="findParamList" resultType="com.caimei.www.pojo.baike.BaikeProductParam">
+		select productId, name, content from cm_baike_product_param where productId = #{id}
+	</select>
+	<select id="findImageList" resultType="java.lang.String">
+		select image from cm_baike_product_image where productId = #{productId} and type = #{imageType}
+	</select>
+	<select id="findQuestionList" resultType="com.caimei.www.pojo.baike.BaikeProductQuestion">
+		select productId, question, answer
+		from cm_baike_product_question
+		where productId = #{productId}
+	</select>
+	<select id="getBaikeType" resultType="com.caimei.www.pojo.baike.BaikeType">
+		select name from cm_baike_type where id = #{typeId}
+	</select>
+</mapper>

+ 16 - 0
src/main/resources/mapper/BaseMapper.xml

@@ -53,4 +53,20 @@
 		from new_page_friendship_link
 		where delFlag = 0 order by id
     </select>
+    <select id="getBaikeSearchHotWord" resultType="com.caimei.www.pojo.baike.BaikeHotSearch">
+        select keyWord,jumpType,productId,jumpLink from cm_baike_hot_search where status = 1 order by -sort desc,addTime desc
+    </select>
+    <select id="getBaikeBannerImage" resultType="com.caimei.www.pojo.page.ImageLink">
+        select id,
+               if(#{commodityType} = 1, productPcBanner, instrumentPcBanner) as image,
+               if(#{commodityType} = 1, productLink, instrumentLink)         as link
+        from cm_baike_banner
+        where if(#{commodityType} = 1,productStatus,instrumentStatus) = 1
+    </select>
+    <select id="getBaikeTypeList" resultType="com.caimei.www.pojo.baike.BaikeType">
+        select id as typeId, name
+        from cm_baike_type
+        where if(#{commodityType} = 1, typeSort = 1, typeSort = 2) and status = 1
+        order by -sort desc,addTime desc
+    </select>
 </mapper>

+ 31 - 0
src/main/resources/mapper/ProductMapper.xml

@@ -123,5 +123,36 @@
     <select id="getProductInfo" resultType="java.lang.String">
         select detailinfo from productdetailinfo where detailinfo like '%img-b.caimei365.com%'
 	</select>
+    <select id="getBaikeProductDetail" resultType="com.caimei.www.pojo.baike.BaikeProduct">
+		select a.id              AS "id",
+			   a.commodityType   AS "commodityType",
+			   a.name            AS "name",
+			   a.alias           AS "alias",
+			   a.discription     AS "discription",
+			   a.image           AS "image",
+			   a.advantage       AS "advantage",
+			   a.disadvantage    AS "disadvantage",
+			   a.principle       AS "principle",
+			   a.brand           AS "brand",
+			   a.producePlace    AS "producePlace",
+			   a.marketTime      AS "marketTime",
+			   a.company         AS "company",
+			   a.nmpaTime        AS "nmpaTime",
+			   a.adaptiveMan     AS "adaptiveMan",
+			   a.unAdaptiveMan   AS "unAdaptiveMan",
+			   a.aroundOperation AS "aroundOperation",
+			   a.publishTime     AS "publishTime",
+			   a.basePv          AS "basePv",
+			   a.actualPv        AS "actualPv",
+			   a.typeId          AS "typeId",
+			   a.topPosition     AS "topPosition",
+			   a.status          AS "status",
+			   a.addTime         AS "addTime",
+			   cbt.name          as "typeName"
+		from cm_baike_product a
+				 left join cm_baike_type cbt on a.typeId = cbt.id
+		where id = #{productId};
+
+	</select>
 
 </mapper>

+ 11 - 0
src/main/resources/static/css/encyclopedia/base.css

@@ -0,0 +1,11 @@
+@charset "UTF-8";
+html{font-size:16px}
+body{background:#f5f5f5;color:#4a4f58}
+h1,h2,h3,h4,h5,h6{margin:0;font-size:16px;font-weight:normal}
+ul{margin:0;padding:0;list-style:none}
+dl,dt,dd{margin:0;padding:0}
+p{margin:0;font-size:16px}
+a{color:#4a4f58;text-decoration:none;transition:all 0.2s}
+img{display:block}
+input{outline:none}
+em{font-style:normal}

+ 94 - 0
src/main/resources/static/css/encyclopedia/common.css

@@ -0,0 +1,94 @@
+@charset "UTF-8";
+@media screen and (min-width:768px){
+::-webkit-scrollbar{width:8px;height: 8px; background-color:#f5f5f5}
+::-webkit-scrollbar-thumb{border-radius:10px;background-color:#999}
+.icon{display:block;width:20px;height:20px;background-image:url(/img/encyclopedia/icon.png);background-repeat:no-repeat}
+.icon.arrowdown{background-position:-277px -413px}
+.icon.arrowup{background-position:-308px -413px}
+.flex-between-center,.navbar .nav li a,.navbar .nav,.navbar .container{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}
+.container{width:1200px;margin:0 auto}
+body{padding-top:80px;min-height: 100vh;}
+.navbar{width:100%;background:#fff;position:fixed;top:0;left:0;z-index:99998;-webkit-box-shadow:0 0 5px rgba(0,0,0,0.1);box-shadow:0 0 5px rgba(0,0,0,0.1)}
+.navbar .logo{width:136px;height:56px;overflow:hidden}
+.navbar .logo .menu-btn{display:none}
+.navbar .logo h1{font-size:0;margin:0}
+.navbar .nav li{height:80px;-webkit-box-sizing:border-box;box-sizing:border-box;border-color:#fff}
+.navbar .nav li.active{border-bottom:2px solid #e15616;background:#fef6f3}
+.navbar .nav li.active a{color:#e15616}
+.navbar .nav li a{height:80px;padding:0 28px}
+.navbar .nav li a:hover{color:#e15616}
+.navbar .search .search-control form{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.navbar .search .search-control .search-input{display:block;width:272px;height:36px;padding:8px 16px;border:1px solid #e15616;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:2px 0 0 2px;color:#4a4f58}
+.navbar .search .search-control .search-input::-webkit-input-placeholder{color:#9aa5b5;font-size:14px}
+.navbar .search .search-control .search-input::-moz-placeholder{color:#9aa5b5;font-size:14px}
+.navbar .search .search-control .search-input:-ms-input-placeholder{color:#9aa5b5;font-size:14px}
+.navbar .search .search-control .search-input::-ms-input-placeholder{color:#9aa5b5;font-size:14px}
+.navbar .search .search-control .search-input::placeholder{color:#9aa5b5;font-size:14px}
+.navbar .search .search-control .search-btn{display:block;width:64px;height:36px;border:0;background:#e15616;border-radius:0px 2px 2px 0px;cursor:pointer;font-size:14px;color:#ffffff}
+.navbar .search .search-control .hot-keyword{display:none}
+.navbar .search .keywords{width:336px;font-size:12px;margin-top:4px;color:#ffb496;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space: nowrap;}
+.navbar .search .keywords .close-btn{display:none}
+.navbar .search .keywords a{color:#ffb496}
+.navbar .search .keywords a:hover{color:#e15616}
+.navbar .search .keywords em{margin:0 4px}
+.copyright{padding:24px 0;margin-top:24px;background:#2c3038}
+.copyright p{text-align:center;line-height:36px;color:#f1f1f1;font-size:14px}
+.copyright p .icp{display:inline-block;vertical-align:middle}
+.copyright p a{color:#f1f1f1}
+.copyright p a:hover{color:#fff}
+.navigate{position:fixed;right:20px;top:50%;z-index:9;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:88px;background:#fff;-webkit-box-shadow:0px 4px 8px rgba(74,79,88,0.16);box-shadow:0px 4px 8px rgba(74,79,88,0.16)}
+.navigate li{line-height:40px;height:40px;text-align:center}
+.navigate li.active a{color:#e15616;background:#fef6f3}
+.navigate li a{display:block;font-size:12px;color:#4a4f58}
+.navigate li a:hover{color:#e15616;background:#fef6f3}
+}
+@media screen and (max-width:768px){
+.flex,.flex-start-center,.navbar .search .search-control form,.flex-between-center,.navbar .search .search-control,.flex-center,.navbar .search .search-control .search-btn,.navbar .search .search-control .hot-keyword,.navbar .logo .menu-btn,.navbar .logo,.navbar .nav{display:-webkit-box;display:-ms-flexbox;display:flex}
+.flex-center,.navbar .search .search-control .search-btn,.navbar .search .search-control .hot-keyword,.navbar .logo .menu-btn,.navbar .logo,.navbar .nav{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-between-center,.navbar .search .search-control{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-start-center,.navbar .search .search-control form{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.icon{display:inline-block;width:6.4vw;height:6.4vw;background:url(/img/encyclopedia/icon_m.png) no-repeat;background-size:100vw auto}
+.icon.menu{display:block;background-position:0 0}
+.icon.close{display:block;background-position:-84.3vw -53vw}
+.icon.arrowdown{background-position:-42vw 0;-webkit-transform:rotateZ(180deg);-ms-transform:rotate(180deg);transform:rotateZ(180deg)}
+.icon.arrowup{background-position:-42vw 0;-webkit-transform:rotateZ(0deg);-ms-transform:rotate(0deg);transform:rotateZ(0deg)}
+.icon.arrowright{background-position:-42vw 0;-webkit-transform:rotateZ(90deg);-ms-transform:rotate(90deg);transform:rotateZ(90deg)}
+.icon.arrowleft{background-position:-42vw 0;-webkit-transform:rotateZ(-90deg);-ms-transform:rotate(-90deg);transform:rotateZ(-90deg)}
+.clearfix::after{content:"";display:block;width:0;clear:both}
+body{-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:29.5vw}
+.navbar{position:fixed;top:0;z-index:99998;width:100vw;height:29.5vw;background-color:#fff}
+.navbar .nav{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;z-index:99999;height:100vh;width:100vw;background:rgba(0,0,0,0.7);-webkit-box-sizing:border-box;box-sizing:border-box;display:none}
+.navbar .nav li{width:70.2vw;height:12.8vw;line-height:12.8vw;text-align:center;border-top:1px solid rgba(255,255,255,0.4)}
+.navbar .nav li.active a{color:#e15616}
+.navbar .nav li:first-child{border-top:0}
+.navbar .nav li a{display:block;color:#fff;font-size:4.2vw}
+.navbar .nav li .nav-close{display:inline-block;width:5.3vw;height:5.3vw;background:url(/img/encyclopedia/h5-nav-close-btn.png) no-repeat center;background-size:5.3vw}
+.navbar .logo{position:relative;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:100vw;height:13.5vw}
+.navbar .logo .menu-btn{position:absolute;left:0;top:0;width:13.5vw;height:13.5vw;cursor:pointer;-webkit-transition:all 0.4s;-o-transition:all 0.4s;transition:all 0.4s}
+.navbar .logo .menu-btn .active{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}
+.navbar .logo h1{font-size:0}
+.navbar .logo img{height:9.8vw}
+.navbar .search .search-control{height:16vw;padding:0 4vw}
+.navbar .search .search-control .search-input{display:block;width:53.8vw;height:9.6vw;background:#ffffff;border:1px solid #e15616;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;border-right:0;border-radius:0.2vw 0 0 0.2vw;padding:2.6vw 2.2vw}
+.navbar .search .search-control .search-input::-webkit-input-placeholder{font-size:3.4vw;color:#bec2c9}
+.navbar .search .search-control .search-input::-moz-placeholder{font-size:3.4vw;color:#bec2c9}
+.navbar .search .search-control .search-input:-ms-input-placeholder{font-size:3.4vw;color:#bec2c9}
+.navbar .search .search-control .search-input::-ms-input-placeholder{font-size:3.4vw;color:#bec2c9}
+.navbar .search .search-control .search-input::placeholder{font-size:3.4vw;color:#bec2c9}
+.navbar .search .search-control .search-btn,.navbar .search .search-control .hot-keyword{border:0;width:17.2vw;height:9.6vw;border-radius:0px 0.2vw 0.2vw 0px;font-size:3.4vw;color:#fff}
+.navbar .search .search-control .search-btn{background:#e15616}
+.navbar .search .search-control .hot-keyword{background:#f94b4b}
+.navbar .search .keywords{display:none;position:absolute;top:29.5vw;width:100vw;padding:4vw 8vw 1.4vw 4vw;-webkit-box-sizing:border-box;box-sizing:border-box;background:#fff;border-radius:0 0 1.6vw 1.6vw;}
+.navbar .search .keywords::after{content:"";display:block;width:0;clear:both}
+.navbar .search .keywords em,.navbar .search .keywords span{display:none}
+.navbar .search .keywords .close-btn{position:absolute;display:block;top:4vw;right:4vw;width:6vw;height:6vw;text-align:center;line-height:6vw}
+.navbar .search .keywords a{display:block;float:left;height:5.9vw;padding:0 2.4vw;margin-right:2.6vw;margin-bottom:2.6vw;line-height:5.9vw;background:#f94b4b;opacity:1;border-radius:2px;font-size:3.2vw;color:#fff}
+.navbar .search .keywords a:nth-of-type(2n){opacity:0.8}
+.navbar .search .keywords a:nth-of-type(3n){opacity:0.6}
+.navigate{display:none}
+.copyright{width:100vw;margin-top:2.4vw;background:#2c3038;-webkit-box-sizing:border-box;box-sizing:border-box;padding:5vw 4vw;text-align:center}
+.copyright p{font-size:2.9vw;color:#eee;line-height:6vw}
+.copyright p img{display:inline-block;vertical-align:top}
+.copyright p a{color:#eee}
+.copyright p span.br{display:block}
+}

+ 40 - 0
src/main/resources/static/css/encyclopedia/contact.css

@@ -0,0 +1,40 @@
+@charset "UTF-8";
+@media screen and (min-width:768px){
+.page-title{width:100%;height:240px;background:url(/img/encyclopedia/pc-page-title-bg.png) no-repeat center;background-size:auto 240px;overflow:hidden}
+.page-title .title{margin-top:55px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.page-title .title h2{color:#fff;width:124px;font-size:30px}
+.page-title .title .line{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;margin-left:7px;height:1px;background:rgba(255,255,255,0.2)}
+.page-title .title .line::after{content:"";display:inline-block;width:16px;height:2px;background:#ffffff;opacity:0.72}
+.page-title .subtitle{margin-top:8px;font-size:12px;color:#ffffff;opacity:0.6;text-transform: uppercase;}
+.page-title .subtitle span{display:inline-block;width:38px;height:1px;background:#ffffff;vertical-align:middle;margin-right:8px}
+.contact{position:relative;height:630px}
+.contact .content{height:713px;padding:40px 55px;background:#ffffff;border-radius:2px;-webkit-transform:translateY(-80px);-ms-transform:translateY(-80px);transform:translateY(-80px);-webkit-box-shadow:0 0 16px rgba(0,0,0,0.1);box-shadow:0 0 16px rgba(0,0,0,0.1);-webkit-box-sizing:border-box;box-sizing:border-box}
+.contact .content h2{font-size:18px;font-weight:bold}
+.contact .content p{margin-top:24px;font-size:14px;color:#93979f;text-align:justify;line-height:24px}
+.contact .content .address{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;margin:60px 0 50px}
+.contact .content .address .line{height:56px;width:1px;background:#e3e6eb}
+.contact .content .address .col:nth-of-type(3){width:460px}
+.contact .content .address .col .dt{font-size:14px;color:#93979f}
+.contact .content .address .col .dd{margin-top:12px;font-size:16px;font-weight:bold}
+.contact .content .map{height:354px;margin-top:24px;background:#93979f}
+}
+@media screen and (max-width:768px){
+.flex-center,.page-title .container .subtitle,.page-title .container .title .line,.page-title .container,.page-title,.flex-center-between,.page-title .container .title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-center-between,.page-title .container .title{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}
+.page-title{width:100vw;height:28vw;background:url(/img/encyclopedia/h5-page-title-bg.png) no-repeat;background-size:100vw 28vw;-webkit-box-sizing:border-box;box-sizing:border-box;padding:4vw}
+.page-title .container{width:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}
+.page-title .container .title{width:100%}
+.page-title .container .title h2{font-size:5.3vw;color:#ffffff}
+.page-title .container .title .line{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;width:66vw;height:0.2vw;background:rgba(255,255,255,0.2)}
+.page-title .container .title .line::after{content:"";display:inline-block;width:3vw;height:0.4vw;background:#ffffff;opacity:0.6}
+.page-title .container .subtitle{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;margin-top:2vw;font-size:2vw;color:#ffffff;opacity:0.6}
+.page-title .container .subtitle span{display:block;width:6.8vw;height:0.2vw;margin-right:2vw;background:#ffffff}
+.contact .content{padding:4vw;background:#fff}
+.contact .content h2{font-size:3.6vw;font-weight:bold}
+.contact .content p{margin-top:3.2vw;font-size:3vw;line-height:5.6vw;color:#93979f;text-align: justify;}
+.contact .content .address .col{margin:4vw 0}
+.contact .content .address .col .dt{font-size:3vw;color:#93979f}
+.contact .content .address .col .dd{margin-top:1.6vw;font-size:3.2vw;font-weight:bold;color:#4a4f58}
+.contact .content .map{width:92vw;height:60vw}
+.copyright{margin-top:0}
+}

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

@@ -0,0 +1,100 @@
+@charset "UTF-8";
+.viewer-container{z-index: 99999 !important}
+img{cursor: pointer;}
+@media screen and (min-width:768px){
+.flex-between-center,.article .section.description .content{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}
+.container,.article{width:1200px;margin:0 auto}
+.article{margin-top:16px;background:#fff}
+.article .section{padding:24px}
+.article .section .title h2{font-size:20px;font-weight:bold;color:#4a4f58}
+.article .section .title .line{width:100%;height:1px;background:#e3e6eb;margin-top:4px}
+.article .section .title .line::before{content:"";display:block;width:20px;height:1px;background:#e15616}
+.article .section .content{padding-top:24px;word-break: break-all;}
+.article .section .content .row{margin:16px 0}
+.article .section .content p{color:#4a4f58;font-size:14px;line-height:24px}
+.article .section .content h1,.article .section .content h2,.article .section .content h3,.article .section .content h4,.article .section .content h5,.article .section .content h6{margin:16px 0;font-weight:bold}
+.article .section.description .content{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}
+.article .section.description .content .content-left{width:986px}
+.article .section.description .content .content-left .desc{text-align:justify;font-size:14px;line-height:24px}
+.article .section.description .content .content-left .names{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;line-height: 26px}
+.article .section.description .content .content-left .names .name{max-width: 60%;}
+.article .section.description .content .content-left .names .alias{ flex: 1;}
+.article .section.description .content .content-left .alias{color:#93979f;margin-left:40px}
+.article .section.description .content .cover{width:120px;height:120px;border:1px dashed #93979f;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}
+.article .section.description .content .cover img{width:120px;height:120px}
+.article .section.params .tr{width:100%;text-align:center;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-sizing:border-box;box-sizing:border-box;border-left:1px solid #e3e6eb;flex-wrap: wrap;}
+.article .section.params .tr:first-child{border-top:1px solid;border-left:1px solid;border-color:#e3e6eb}
+.article .section.params .tr .group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:50%}
+.article .section.params .tr .th,.article .section.params .tr .td{line-height:40px;font-size:14px;height:40px;border-right:1px solid;border-bottom:1px solid;border-color:#e3e6eb;-webkit-box-sizing:border-box;box-sizing:border-box}
+.article .section.params .tr .th a,.article .section.params .tr .td a{color:#e15616}
+.article .section.params .tr .th{background:#f4f5f8;width: 30%;}
+.article .section.params .tr .td{background:#ffffff;width: 70%; overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}
+.article .section.approve .content .name{font-size:14px;line-height:24px}
+.article .section.approve .content a{color:#e15616}
+.article .section.approve .content .img-list{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.article .section.approve .content .img-list img{width:120px;height:120px;border:1px dashed #93979f;-webkit-box-sizing:border-box;box-sizing:border-box;margin:16px 16px 0 0}
+.article .section.effect .content img{display:block;width:100%}
+.article .section.question .content .collapse{margin-bottom:12px}
+.article .section.question .content .collapse dt,.article .section.question .content .collapse dd{position:relative;font-size:14px;line-height:24px;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 32px;text-align:justify}
+.article .section.question .content .collapse dt span,.article .section.question .content .collapse dd span{display:inline-block;width:20px;height:20px;margin-right:8px;text-align:center;line-height:20px;border-radius:2px;color:#fff;font-size:12px;position:absolute;top:2px;left:0}
+.article .section.question .content .collapse dt{font-weight:bold}
+.article .section.question .content .collapse dt span{background:#ffa457}
+.article .section.question .content .collapse dt .icon{position:absolute;right:0;top:2px;cursor:pointer}
+.article .section.question .content .collapse dd{padding-right:0;margin-top:4px;}
+.article .section.question .content .collapse dd span{background:#34cc8c}
+.contact-popup{display: none; position:fixed;top: 50%;left: 50%;z-index: 99999; transform: translate(-50%,-50%); width:314px;height:418px;overflow:hidden;background:url(/img/encyclopedia/contact.png) no-repeat center}
+.contact-popup .close{position:absolute;display:block;width:30px;height:30px;text-align:center;line-height:30px;top:10px;right:20px;font-size:28px;color:#2c3038;cursor:pointer}
+.contact-popup .content{margin-top:130px}
+.contact-popup .content p{font-size:16px;text-align:center;line-height:32px;color:#9aa5b5;margin:0}
+.contact-popup .content p.tel{color:#e15616}
+.contact-popup .content p.time{color:#2c3038}
+}
+@media screen and (max-width:768px){
+img{max-width: 100%;}
+.flex,.flex-start-center,.article .section.approve .img-list,.article .section.params .tr .group,.flex-between-center,.flex-center{display:-webkit-box;display:-ms-flexbox;display:flex}
+.flex-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-between-center{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-start-center,.article .section.approve .img-list,.article .section.params .tr .group{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+body{padding-top:40.3vw}
+.navigate{display:block;background:#fff;top:29.5vw;position:fixed;-webkit-box-shadow:1vw 0 2vw rgba(0,0,0,0.1);box-shadow:1vw 0 2vw rgba(0,0,0,0.1)}
+.navigate ul{overflow-x:scroll;width:100vw;height:10.8vw;padding:4vw 4vw 0;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}
+.navigate ul::-webkit-scrollbar{display:none}
+.navigate ul li{position:relative;display:inline-block;height:6.8vw;margin-right:5.6vw}
+.navigate ul li:last-child{margin-right:0}
+.navigate ul li::after{content:"";position:absolute;left:50%;bottom:0.4vw;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);display:block;width:8.8vw;height:0.4vw;background:#fff}
+.navigate ul li a{display:block;font-size:3.2vw;line-height:5vw;color:#9498a0}
+.navigate ul li.active a{color:#e15616}
+.navigate ul li.active::after{background:#e15616}
+.article{padding:4vw;margin-top:2.4vw;background:#fff;-webkit-box-sizing:border-box;box-sizing:border-box}
+.article .section .title h2{font-size:3.6vw;font-weight:bold}
+.article .section .title .line{width:100%;height:1px;margin-top:1vw;background:#e3e6eb}
+.article .section .title .line::before{content:"";display:block;width:3.5vw;height:0.2vw;background:#e15616}
+.article .section .content{padding:3.2vw 0; word-break: break-all;}
+.article .section .content h1,.article .section .content h2,.article .section .content h3,.article .section .content h4,.article .section .content h5,.article .section .content h6{font-weight:bold;margin:3.2vw 0}
+.article .section .content p{font-size:3.2vw;line-height:5.6vw;text-align:justify;margin:1.6vw 0}
+.article .section.description .names{font-size:3.2vw;line-height:5.6vw}
+.article .section.description .names .alias{color:#93979f}
+.article .section.description .desc{text-align:justify;font-size:3.2vw;line-height:5.6vw;margin:3.2vw 0}
+.article .section.description .cover img{display:block;width:23.6vw;height:23.6vw;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px dashed #e3e6eb}
+.article .section.params .tr{line-height:5.6vw}
+.article .section.params .tr .group{font-size:3.2vw;margin:1.6vw 0}
+.article .section.params .tr .group .th::after{content:":"}
+.article .section.params .tr .group .td>a{ color: #e15616;}
+.article .section.approve .name{font-size:3.2vw}
+.article .section.approve .img-list{ overflow-x:scroll;}
+.article .section.approve .img-list img{display:block;/*width:23.6vw;*/height:23.6vw;border:1px dashed #e3e6eb;-webkit-box-sizing:border-box;box-sizing:border-box;margin-right:2.4vw;margin-top:2.4vw}
+.article .section.effect img{display:block;max-width:100%}
+.article .section.question .collapse dt,.article .section.question .collapse dd{font-size:3.2vw}
+.article .section.question .collapse dt span,.article .section.question .collapse dd span{display:inline-block;vertical-align:middle;width:4vw;height:4vw;border-radius:0.2vw;text-align:center;line-height:4vw;color:#fff;margin-right:2.4vw}
+.article .section.question .collapse dt{position:relative;padding-right:6.4vw;height:6.4vw;line-height:6.4vw;margin:1.6vw 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}
+.article .section.question .collapse dt span{background:#ffa457}
+.article .section.question .collapse dt .icon{position:absolute;right:0;top:0}
+.article .section.question .collapse dd{line-height:5.6vw;margin:1.6vw 0;text-align:justify}
+.article .section.question .collapse dd span{background:#34cc8c}
+.contact-popup{display: none; position:fixed;top: 50%;left: 50%;z-index: 99999; transform: translate(-50%,-50%); width:80vw;height:100vw;overflow:hidden;background:url(/img/encyclopedia/contact.png) no-repeat center;background-size:80vw auto}
+.contact-popup .close{position:absolute;display:block;width:8vw;height:8vw;text-align:center;line-height:8vw;top:0;right:5vw;font-size:8vw;color:#2c3038;cursor:pointer}
+.contact-popup .content{margin-top:30vw}
+.contact-popup .content p{font-size:4.2vw;text-align:center;line-height:8vw;color:#9aa5b5;margin:0}
+.contact-popup .content p.tel{color:#e15616}
+.contact-popup .content p.time{color:#2c3038}
+}

+ 105 - 0
src/main/resources/static/css/encyclopedia/index.css

@@ -0,0 +1,105 @@
+@charset "UTF-8";
+@media screen and (min-width:768px){
+.color0{ color: #EB2F96 !important;}
+.color1{ color: #9254DE !important;}
+.color2{ color: #00BE6F !important;}
+.color3{ color: #FD8321 !important;}
+.color4{ color: #EB2F96 !important;}
+.color5{ color: #9254DE !important;}
+.color6{ color: #FF4D4F !important;}
+.color7{ color: #40A9FF !important;}
+.color8{ color: #FCC004 !important;}
+.color9{ color: #3AD0CA !important;}
+.flex-between-center,.floor .article .section .content .footer,.floor .emtyp,.category .name,.category{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}
+.banner{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;overflow:hidden}
+.banner img{width:1920px;height:510px}
+.category{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;width:1200px;height:56px;background:#fff;padding:0 24px;margin-top:32px;line-height:56px;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}
+.category .name{width:120px;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}
+.category .name em{display:block;width:1px;height:24px;background:#e3e6eb;margin-right:30px;margin-top:16px;-webkit-transition:all 0.4s;-o-transition:all 0.4s;transition:all 0.4s}
+.category .category-list{-webkit-box-flex:1;-ms-flex:1;flex:1}
+.category .category-list ul{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}
+.category .category-list ul li{padding-right:40px}
+.category .category-list ul li.active a{color:#e15616}
+.category .category-list ul li a:hover{color:#e15616}
+.category .collapse{font-size:14px;color:#93979f;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer}
+.category .collapse span{display:block}
+.floor{overflow:hidden}
+.floor .emtyp{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:1200px;height:812px;margin-top:24px;background:#ffffff;border-radius:2px}
+.floor .emtyp p{margin-top:24px;color:#4a4f58}
+.floor .search-title{margin-top:24px}
+.floor .search-title span{color:#e15616}
+.floor .floor-title{position:relative;width:1200px;margin:24px auto 0;height:56px;background:#f0f5ff;border-radius:2px}
+.floor .floor-title .h5-more-btn{display:none}
+.floor .floor-title h2{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:100px;line-height:56px;font-size:20px;font-weight:bold;color:#597ef7;z-index:9}
+.floor .floor-title img{position:absolute;width:100%;height:100%;left:0;top:0;z-index:8}
+.floor .article::after{content:"";display:block;visibility:hidden;width:0;clear:both}
+.floor .article .section{float:left;width:384px;height:546px;margin:24px 24px 0 0;background:#ffffff;border-radius:2px;overflow:hidden;-webkit-transition:all 0.6s;-o-transition:all 0.6s;transition:all 0.6s}
+.floor .article .section:hover{-webkit-transform:translateY(-10px);-ms-transform:translateY(-10px);transform:translateY(-10px)}
+.floor .article .section:hover h3{color:#e15616}
+.floor .article .section:nth-child(3n){margin-right:0}
+.floor .article .section .cover{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;height:260px}
+.floor .article .section .cover img{width:246px;height:246px}
+.floor .article .section .content{padding:16px 16px 0;-webkit-box-sizing:border-box;box-sizing:border-box;}
+.floor .article .section .content h3{-webkit-transition:all 0.4s;-o-transition:all 0.4s;transition:all 0.4s;font-weight:bold;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;}
+.floor .article .section .content .title{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;height:52px;color:#4a4f58;margin-top:12px;line-height:26px;text-align:justify;word-break:break-all}
+.floor .article .section .content .question{margin:12px 0;height:78px}
+.floor .article .section .content .question p{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;color:#93979f;line-height:26px;font-size:14px}
+.floor .article .section .content .question p:nth-child(3)~p{display: none}
+.floor .article .section .content .tag-list{height:24px}
+.floor .article .section .content .tag-list .tag{display:inline-block;height:24px;line-height:24px;background:#fef6f3;border-radius:2px;font-size:12px;color:#e15616;padding:0 8px;margin-right:8px}
+.floor .article .section .content .dashed-line{margin-top:12px;height:0px;border-bottom:1px dashed #b8bfca}
+.floor .article .section .content .footer{height:50px;line-height:50px;font-size:14px;color:#93979f}
+.floor .more{padding:32px 0 16px}
+.floor .more .more-btn{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:98px;height:32px;margin:0 auto;border:1px solid #cccccc;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:14px;color:#909090;cursor:pointer}
+.floor .more .more-btn:hover{color:#e15616;border-color:#e15616}
+}
+@media screen and (max-width:768px){
+.flex,.flex-start-center,.floor .article .section .content .tag-list,.flex-between-center,.floor .article .section .content .footer,.floor .article .section a,.floor .floor-title,.flex-center,.banner{display:-webkit-box;display:-ms-flexbox;display:flex}
+.flex-center,.banner{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-between-center,.floor .article .section .content .footer,.floor .article .section a,.floor .floor-title{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.flex-start-center,.floor .article .section .content .tag-list{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.banner{width:100vw;height:51vw;overflow:hidden}
+.banner img{display:block;height:51vw}
+.navigate{display:none !important}
+.category{height:10.8vw}
+.category .name,.category .collapse{display:none}
+.category .category-list{background:#fff}
+.category .category-list.fixed{top:29.5vw;position:fixed;z-index:9999;-webkit-box-shadow:0 0.2vw 3vw rgba(0,0,0,0.1);box-shadow:0 0.2vw 3vw rgba(0,0,0,0.1)}
+.category .category-list ul{overflow-x:scroll;width:100vw;height:10.8vw;padding:4vw 4vw 0;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}
+.category .category-list ul::-webkit-scrollbar{display:none}
+.category .category-list ul li{position:relative;display:inline-block;height:6.8vw;margin-right:5.6vw}
+.category .category-list ul li:last-child{margin-right:0}
+.category .category-list ul li::after{content:"";position:absolute;left:50%;bottom:0.4vw;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);display:block;width:8.8vw;height:0.4vw;background:#fff}
+.category .category-list ul li a{display:block;font-size:3.8vw;line-height:5vw;color:#9498a0}
+.category .category-list ul li.active a{color:#e15616}
+.category .category-list ul li.active::after{background:#e15616}
+.floor{padding:4vw;margin-top:2.4vw;background:#fff}
+.floor .floor-title{line-height:6.4vw;height:6.4vw;padding-bottom:1.6vw}
+.floor .floor-title img{display:none}
+.floor .floor-title h2{width:64vw;font-size:3.6vw}
+.floor .floor-title .h5-more-btn span{margin-right:-2vw;font-size:2.6vw;color:#93979f}
+.floor .floor-title .h5-more-btn .icon{margin-right:-2vw;vertical-align:middle}
+.floor .article .section{padding-top:4vw;border-top:1px solid rgba(0,0,0,0.1)}
+.floor .article .section a{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}
+.floor .article .section .cover{margin-right:2.4vw}
+.floor .article .section .cover img{display:block;width:30.4vw;height:30.4vw;border:1px solid #e1e1e1}
+.floor .article .section .content {flex: 1;}
+.floor .article .section .content h3{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;line-height:4vw;height:4vw;font-size:3.6vw;font-weight:bold;word-break: break-all;}
+.floor .article .section .content .title{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-top:1.6vw;font-size:3.2vw;line-height:4.6vw;text-align:justify;height:9.2vw; word-break: break-all;}
+.floor .article .section .content .question{height:10vw;margin:2.4vw 0}
+.floor .article .section .content .question p{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;font-size:2.6vw;line-height:5vw;color:#93979f}
+.floor .article .section .content .question p:nth-child(2)~p{display: none}
+.floor .article .section .content .tag-list{height:4.8vw;-ms-flex-wrap:wrap;flex-wrap:wrap}
+.floor .article .section .content .tag-list .tag{height:4.8vw;padding:0 1.2vw;margin-right:1.6vw;background:#fef6f3;border-radius:0.2vw;font-size:2.6vw;color:#e15616;line-height:4.8vw}
+.floor .article .section .content .tag-list .tag:last-child{display:none}
+.floor .article .section .content .dashed-line{display:none}
+.floor .article .section .content .footer{height:8vw;font-size:2.6vw;color:#93979f;line-height:8vw}
+.floor .more{display:none}
+.search-floor{margin-top:0;padding:0}
+.search-floor .search-title{position:fixed;top:29.5vw;left:0;z-index:999;width:100vw;line-height:10vw;padding:0 4vw;background:#f5f5f5;font-size:3.6vw;-webkit-box-sizing:border-box;box-sizing:border-box}
+.search-floor .search-title span{color:#e15616}
+.search-floor .emtyp{display: flex; padding:10vw 0 4vw;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:75vh}
+.search-floor .emtyp p{margin-top:5vw;font-size:3.2vw;color:#4a4f58}
+.search-floor .article{padding:10vw 4vw 0}
+.search-floor .article .section:first-child{border-top:0}
+}

+ 28 - 0
src/main/resources/static/css/encyclopedia/map.css

@@ -0,0 +1,28 @@
+@charset "UTF-8";
+@media screen and (min-width:768px){body{margin:0;font:13px/1.5 "Microsoft YaHei","Helvetica Neue","Sans-Serif";min-height:354px;min-width:1090px}
+.my-map{margin:0 auto;width:1090px;height:354px}
+.my-map .icon{background:url(//a.amap.com/lbs-dev-yuntu/static/web/image/tools/creater/marker.png) no-repeat}
+.my-map .icon-twig{height:27px;width:30px}
+.my-map .icon-twig-red{background-position:-187px -5px}
+.amap-container{height:100%}
+.amap-info-content{background:-o-linear-gradient(299deg,#f28f31 0%,#e15616 100%);background:linear-gradient(151deg,#f28f31 0%,#e15616 100%);border:0;-webkit-box-shadow:unset;box-shadow:unset}
+.amap-info-close{color:#fff}
+.amap-info-sharp{width:0;height:0 !important;border-style:solid;border-width:24px 24px 0 0;border-color:#e76b20 transparent transparent transparent;background:transparent}
+.myinfowindow{width:240px;min-height:50px}
+.myinfowindow h5{color:#fff;margin:0;height:20px;line-height:20px;overflow:hidden;font-size:14px;font-weight:bold;width:220px;-o-text-overflow:ellipsis;text-overflow:ellipsis;word-break:break-all;white-space:nowrap}
+.myinfowindow div{margin-top:10px;line-height:20px;font-size:13px;color:#fff}
+}
+
+@media screen and (max-width:768px){body{margin:0;font:13px/1.5 "Microsoft YaHei","Helvetica Neue","Sans-Serif"}
+.my-map{margin:0 auto;width:100vw;height:60vw}
+.my-map .icon{background:url(//a.amap.com/lbs-dev-yuntu/static/web/image/tools/creater/marker.png) no-repeat}
+.my-map .icon-twig{height:27px;width:30px}
+.my-map .icon-twig-red{background-position:-187px -5px}
+.amap-container{height:100%}
+.amap-info-content{background:-o-linear-gradient(299deg,#f28f31 0%,#e15616 100%);background:linear-gradient(151deg,#f28f31 0%,#e15616 100%);border:0;-webkit-box-shadow:unset;box-shadow:unset}
+.amap-info-close{color:#fff}
+.amap-info-sharp{width:0;height:0 !important;border-style:solid;border-width:24px 24px 0 0;border-color:#e76b20 transparent transparent transparent;background:transparent}
+.myinfowindow{width:240px;min-height:50px}
+.myinfowindow h5{color:#fff;margin:0;height:20px;line-height:20px;overflow:hidden;font-size:14px;font-weight:bold;width:220px;-o-text-overflow:ellipsis;text-overflow:ellipsis;word-break:break-all;white-space:nowrap}
+.myinfowindow div{margin-top:10px;line-height:20px;font-size:13px;color:#fff}
+}

+ 35 - 0
src/main/resources/static/css/encyclopedia/normalize.css

@@ -0,0 +1,35 @@
+@charset "UTF-8";
+html{line-height:1.15;-webkit-text-size-adjust:100%}
+body{margin:0}
+main{display:block}
+h1{font-size:2em;margin:0.67em 0}
+hr{box-sizing:content-box;height:0;overflow:visible}
+pre{font-family:monospace,monospace;font-size:1em}
+a{background-color:transparent}
+abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}
+b,strong{font-weight:bolder}
+code,kbd,samp{font-family:monospace,monospace;font-size:1em}
+small{font-size:80%}
+sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
+sub{bottom:-0.25em}
+sup{top:-0.5em}
+img{border-style:none}
+button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}
+button,input{overflow:visible}
+button,select{text-transform:none}
+button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}
+button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}
+button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}
+fieldset{padding:0.35em 0.75em 0.625em}
+legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}
+progress{vertical-align:baseline}
+textarea{overflow:auto}
+[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}
+[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}
+[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}
+[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
+::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}
+details{display:block}
+summary{display:list-item}
+template{display:none}
+[hidden]{display:none}

+ 34 - 0
src/main/resources/static/css/encyclopedia/pagination.css

@@ -0,0 +1,34 @@
+@media screen and (min-width:768px){
+.pagination-container{width:100%;margin-top: 24px; display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.pagination-container ul.pagination,.pagination-container .tool,.pagination-container .tool .total,.pagination-container .tool .jump{display:inline-block}
+.pagination-container ul.pagination{padding:0;margin:0}
+.pagination-container ul.pagination li{display:inline}
+.pagination-container ul.pagination li span,.pagination-container ul.pagination li a{-webkit-box-sizing:border-box;box-sizing:border-box;display:inline-block;width:20px;height:40px;line-height:40px;font-size:16px;color:#2d3036;border-radius:2px;text-align:center}
+.pagination-container ul.pagination li a{width:40px;margin:0 5px;border:1px solid #ebecef;background:#fff}
+.pagination-container ul.pagination li a:hover{background-color:#e15616;color:white}
+.pagination-container ul.pagination li.active a{background-color:#e15616;color:white}
+.pagination-container .tool{height:40px;line-height:40px;margin-left:5px;color:#93979f;font-size:14px}
+.pagination-container .tool .total,.pagination-container .tool .jump{display:inline-block;overflow:hidden}
+.pagination-container .tool .total span{color:#2d3036}
+.pagination-container .tool .jump{margin-left:5px}
+.pagination-container .tool .jump .pagenum-input{display:inline-block;margin-right:5px}
+.pagination-container .tool .jump .pagenum-input input{-webkit-box-sizing:border-box;box-sizing:border-box;width:80px;height:40px;color:#2d3036;margin:0 5px;line-height:40px;font-size:16px;border:1px solid #ebecef;outline:none;border-radius:2px;text-align:center}
+.pagination-container .tool .jump .jump-btn{display:inline-block;color:#e15616}
+}
+@media screen and (max-width:768px){
+.pagination-container{width:100%;margin-top: 2.4vw;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.pagination-container ul.pagination,.pagination-container .tool,.pagination-container .tool .total,.pagination-container .tool .jump{display:inline-block}
+.pagination-container ul.pagination{padding:0;margin:0}
+.pagination-container ul.pagination li{display:inline;line-height:6.8vw}
+.pagination-container ul.pagination li span,.pagination-container ul.pagination li a{display:inline-block;width:3.4vw;height:6.8vw;line-height:6.8vw;font-size:2.6vw;color:#2d3036;border-radius:2px;text-align:center}
+.pagination-container ul.pagination li a{width:6.8vw;margin:0 0.4vw;border:1px solid #ebecef;background:#fff}
+.pagination-container ul.pagination li a:hover{background-color:#e15616;color:white}
+.pagination-container ul.pagination li.active a{background-color:#e15616;color:white}
+.pagination-container .tool{display:none;height:6.8vw;line-height:6.8vw;margin-left:1vw;color:#93979f;font-size:2.4vw}
+.pagination-container .tool .total,.pagination-container .tool .jump{display:inline-block;overflow:hidden}
+.pagination-container .tool .total span{color:#2d3036}
+.pagination-container .tool .jump{margin-left:5px}
+.pagination-container .tool .jump .pagenum-input{display:inline-block;margin-right:5px}
+.pagination-container .tool .jump .pagenum-input input{-webkit-box-sizing:border-box;box-sizing:border-box;width:13.4vw;height:6.8vw;color:#2d3036;margin:0 1vw;line-height:6.8vw;font-size:2.6vw;border:1px solid #ebecef;outline:none;border-radius:2px;text-align:center}
+.pagination-container .tool .jump .jump-btn{display:inline-block;color:#e15616}
+}

+ 50 - 0
src/main/resources/static/css/supplier-center/article/article-edit.css

@@ -0,0 +1,50 @@
+@charset "UTF-8";
+input[hidden]{display:none !important}
+textarea{resize: none;}
+.form{width:500px;margin:0 auto;color:#22272E}
+.form .form-item{width:100%;position:relative;padding-bottom:24px;margin-top:16px}
+.form .form-label{display:block;line-height:26px;font-size:14px;color:#627386}
+.form .form-label em{display:none;color:#FF2A2A;font-style:normal;margin-right:2px}
+.form .form-item[required] .form-label em{display:inline}
+.form .form-item .errTips{position:absolute;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center;line-height:24px;white-space:nowrap;color:red;font-size:12px}
+.form .form-item .errTips::before{content:"×";font-size:12px;display:block;width:14px;height:14px;margin-right:2px;line-height:14px;background:#FF2A2A;color:#fff;border-radius:50%;text-align:center}
+.form .form-control::-webkit-input-placeholder{font-size:14px;color:#9AA5B5}
+.form .form-control::-moz-placeholder{font-size:14px;color:#9AA5B5}
+.form .form-control:-ms-input-placeholder{font-size:14px;color:#9AA5B5}
+.form .form-control::-ms-input-placeholder{font-size:14px;color:#9AA5B5}
+.form .form-control::placeholder{font-size:14px;color:#9AA5B5}
+.form .form-control{outline:none;display:block;width:100%;padding:8px 16px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#FFFFFF;border:1px solid #B8BFCA;border-radius:2px}
+.form .form-select{color:#627386}
+.form .control-group{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}
+.form .control-group .form-control{width:auto}
+.form .form-button{padding:0 16px;height:36px;line-height:36px;background:#FFE6DC;border:1px solid #E15616;border-radius:2px;font-size:14px;color:#E15616;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}
+.form .upload-control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100px;height:100px;background:#FFFFFF;border:1px solid #E2E7EF;border-radius:2px;color:#9AA5B5;cursor:pointer}
+.form .upload-control span:first-child{font-size:38px}
+.form .upload-control span:last-child{font-size:14px}
+.form .radio-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.form .radio-control input[type="radio"]{display:none}
+.form .radio-control label.radio{position:relative;padding-left:26px;cursor:pointer;font-size:14px;color:#22272E}
+.form .radio-control label.radio::before{content:"";position:absolute;left:0;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);display:block;width:18px;height:18px;border:1px solid #B8BFCA;border-radius:50%;-webkit-box-sizing:border-box;box-sizing:border-box}
+.form .radio-control label.radio::after{content:"";display:block;opacity:0;position:absolute;left:5px;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:8px;height:8px;background:#E15616;border-radius:50%}
+.form .radio-control input[type="radio"]:checked + label.radio{color:#E15616}
+.form .radio-control input[type="radio"]:checked + label.radio::before{border-color:#E15616}
+.form .radio-control input[type="radio"]:checked + label.radio::after{opacity:1}
+.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}
+.form .btn.break{background:#FFE6DC;border:1px solid #E15616;border-radius:2px;color:#E15616}
+.form .btn.submit{background:#E15616;color:#FFFFFF}
+.article-edit{}
+.article-edit .navLayout .right{width:auto}
+.article-edit .navLayout .right-box{width:968px}
+.article-edit .row{-webkit-box-sizing:border-box;box-sizing:border-box;padding:24px 0;background:#FFFFFF;-webkit-box-shadow:0 3px 6px rgba(0,0,0,0.07);box-shadow:0 3px 6px rgba(0,0,0,0.07)}
+.article-edit .top-tip{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:60px;text-align:center;font-size:12px;line-height:20px;color:#E15616;background:-webkit-gradient(linear,left top,right top,from(#FFFFFF),color-stop(50%,rgba(225,86,22,0.1)),to(#FFFFFF));background:-o-linear-gradient(left,#FFFFFF 0%,rgba(225,86,22,0.1) 50%,#FFFFFF 100%);background:linear-gradient(90deg,#FFFFFF 0%,rgba(225,86,22,0.1) 50%,#FFFFFF 100%)}
+.article-edit .tag-list{width:100%;padding-bottom:32px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}
+.article-edit .tag-list .tag{position:relative;padding:0 6px;margin:8px 8px 0 0;height:28px;line-height:28px;background:#FFF3E5;border-radius:2px;font-size:14px;font-weight:400;color:#4A4F58;cursor:pointer;border:1px solid #FFF3E5}
+.article-edit .tag-list .tag.active{color:#E15616;background:#FFE6DC;border-color:#E15616}
+.article-edit .tag-list .tag .close{display:none;position:absolute;top:-8px;right:-8px;width:16px;height:16px;background:#F94B4B;border-radius:50%;font-size:10px;line-height:16px;text-align:center;color:#fff;cursor:pointer}
+.article-edit .radio-group .form-label{width:80px}
+.article-edit .control-group{padding-bottom:24px}
+.article-edit .control-group .tagName{width:388px}
+.article-edit .control-group .addTag{width:90px}
+.article-edit .radio-control{margin-right:32px}
+.article-edit .btns{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}
+.article-edit .btns .btn{margin:0 16px}

+ 36 - 0
src/main/resources/static/css/supplier-center/article/article-list.css

@@ -0,0 +1,36 @@
+@charset "UTF-8";.top-row{width:968px;padding:12px 0 12px 236px;margin:0 auto;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}
+.top-row .crumbs{width:auto;padding:0;margin:0}
+.top-row .hot-tip{font-size:12px;color:#E15616}
+.form-section{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;-ms-flex-wrap:wrap;flex-wrap:wrap}
+.form-section .form-item{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;padding-bottom:18px}
+.form-section .form-item .form-label{margin-right:8px;font-size:14px;color:#627386}
+.form-section .form-item .form-control{outline:none;width:210px;height:36px;padding:8px 12px;background:#FFFFFF;border:1px solid #B8BFCA;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box}
+.form-section .form-item .form-control::-webkit-input-placeholder{font-size:14px;color:#9AA5B5}
+.form-section .form-item .form-control::-moz-placeholder{font-size:14px;color:#9AA5B5}
+.form-section .form-item .form-control:-ms-input-placeholder{font-size:14px;color:#9AA5B5}
+.form-section .form-item .form-control::-ms-input-placeholder{font-size:14px;color:#9AA5B5}
+.form-section .form-item .form-control::placeholder{font-size:14px;color:#9AA5B5}
+.form-section .form-item .form-select{color:#627386}
+.form-section .form-item .form-button{height:36px;padding:0 30px;margin-left:16px;font-size:14px;line-height:36px;border-radius:2px;cursor:pointer}
+.form-section .buttons{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}
+.form-section .form-item .form-button.search{color:#FFFFFF;background:#E15616}
+.form-section .form-item .form-button.add{background:#FFE6DC;border:1px solid #E15616;color:#E15616}
+.navLayout{min-height:500px}
+.article-list{}
+.article-list .row{width:100%;padding:18px 20px 0;margin-bottom:16px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#fff;-webkit-box-shadow:0px 3px 6px rgba(0,0,0,0.07);box-shadow:0px 3px 6px rgba(0,0,0,0.07)}
+.article-list .table,.table tr,.table th,.table td{border:0}
+.article-list .table{width:100%}
+.article-list .table th{font-size:14px;color:#627386;padding-bottom:16px;border-bottom:1px solid #E2E7EF}
+.article-list .table td{font-size:12px;color:#22272E;text-align:center}
+.article-list .table td{padding:16px 0}
+.article-list .table .title,.article-list .table .time,.article-list .table .option{width:100px}
+.article-list .table .title{white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis}
+.article-list .table .reason{display:inline-block;width:14px;height:14px;background:#FF2A2A;color:#fff;border-radius:50%;vertical-align:middle;line-height:14px;text-align:center;margin-left:2px;cursor: help;}
+.article-list .table .option .form-button{width:40px;height:22px;margin:2px 0;line-height:22px;text-align:center;background:#FFE6DC;border:1px solid #E15616;border-radius:2px;font-size:12px;color:#E15616;cursor:pointer}
+.article-list .table .cover{display:inline-block;width:48px;height:48px;border:1px dashed #E2E7EF}
+.article-list .state{color:#22272E}
+.article-list .state.success{color:#34CC8C}
+.article-list .state.warning{color:#F9A94B}
+.article-list .state.danger{color:#F94B4B}
+.article-list .state.primary{color:#1890F9}
+.article-list .pageWrap{width:100% !important}

+ 680 - 0
src/main/resources/static/css/supplier-center/article/table.css

@@ -0,0 +1,680 @@
+@charset "UTF-8";
+/*!
+ * Generated using the Bootstrap Customizer (https://v3.bootcss.com/customize/)
+ */
+/*!
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+    font-family: sans-serif;
+    -ms-text-size-adjust: 100%;
+    -webkit-text-size-adjust: 100%;
+}
+
+body {
+    margin: 0;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+    display: block;
+}
+
+audio,
+canvas,
+progress,
+video {
+    display: inline-block;
+    vertical-align: baseline;
+}
+
+audio:not([controls]) {
+    display: none;
+    height: 0;
+}
+
+[hidden],
+template {
+    display: none;
+}
+
+a {
+    background-color: transparent;
+}
+
+a:active,
+a:hover {
+    outline: 0;
+}
+
+abbr[title] {
+    border-bottom: none;
+    text-decoration: underline;
+    text-decoration: underline dotted;
+}
+
+b,
+strong {
+    font-weight: bold;
+}
+
+dfn {
+    font-style: italic;
+}
+
+h1 {
+    font-size: 2em;
+    margin: 0.67em 0;
+}
+
+mark {
+    background: #ff0;
+    color: #000;
+}
+
+small {
+    font-size: 80%;
+}
+
+sub,
+sup {
+    font-size: 75%;
+    line-height: 0;
+    position: relative;
+    vertical-align: baseline;
+}
+
+sup {
+    top: -0.5em;
+}
+
+sub {
+    bottom: -0.25em;
+}
+
+img {
+    border: 0;
+}
+
+svg:not(:root) {
+    overflow: hidden;
+}
+
+figure {
+    margin: 1em 40px;
+}
+
+hr {
+    -webkit-box-sizing: content-box;
+    -moz-box-sizing: content-box;
+    box-sizing: content-box;
+    height: 0;
+}
+
+pre {
+    overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp {
+    font-family: monospace, monospace;
+    font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+    color: inherit;
+    font: inherit;
+    margin: 0;
+}
+
+button {
+    overflow: visible;
+}
+
+button,
+select {
+    text-transform: none;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+    -webkit-appearance: button;
+    cursor: pointer;
+}
+
+button[disabled],
+html input[disabled] {
+    cursor: default;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+    border: 0;
+    padding: 0;
+}
+
+input {
+    line-height: normal;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    box-sizing: border-box;
+    padding: 0;
+}
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+    height: auto;
+}
+
+input[type="search"] {
+    -webkit-appearance: textfield;
+    -webkit-box-sizing: content-box;
+    -moz-box-sizing: content-box;
+    box-sizing: content-box;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+    -webkit-appearance: none;
+}
+
+fieldset {
+    border: 1px solid #c0c0c0;
+    margin: 0 2px;
+    padding: 0.35em 0.625em 0.75em;
+}
+
+legend {
+    border: 0;
+    padding: 0;
+}
+
+textarea {
+    overflow: auto;
+}
+
+optgroup {
+    font-weight: bold;
+}
+
+table {
+    border-collapse: collapse;
+    border-spacing: 0;
+}
+
+td,
+th {
+    padding: 0;
+}
+
+* {
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    box-sizing: border-box;
+}
+
+*:before,
+*:after {
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    box-sizing: border-box;
+}
+
+html {
+    font-size: 10px;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+body {
+    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+    font-size: 14px;
+    line-height: 1.42857143;
+    color: #333333;
+    background-color: #ffffff;
+}
+
+input,
+button,
+select,
+textarea {
+    font-family: inherit;
+    font-size: inherit;
+    line-height: inherit;
+}
+
+a {
+    color: #337ab7;
+    text-decoration: none;
+}
+
+a:hover,
+a:focus {
+    color: #23527c;
+    text-decoration: underline;
+}
+
+a:focus {
+    outline: 5px auto -webkit-focus-ring-color;
+    outline-offset: -2px;
+}
+
+figure {
+    margin: 0;
+}
+
+img {
+    vertical-align: middle;
+}
+
+.img-responsive {
+    display: block;
+    max-width: 100%;
+    height: auto;
+}
+
+.img-rounded {
+    border-radius: 6px;
+}
+
+.img-thumbnail {
+    padding: 4px;
+    line-height: 1.42857143;
+    background-color: #ffffff;
+    border: 1px solid #dddddd;
+    border-radius: 4px;
+    -webkit-transition: all 0.2s ease-in-out;
+    -o-transition: all 0.2s ease-in-out;
+    transition: all 0.2s ease-in-out;
+    display: inline-block;
+    max-width: 100%;
+    height: auto;
+}
+
+.img-circle {
+    border-radius: 50%;
+}
+
+hr {
+    margin-top: 20px;
+    margin-bottom: 20px;
+    border: 0;
+    border-top: 1px solid #eeeeee;
+}
+
+.sr-only {
+    position: absolute;
+    width: 1px;
+    height: 1px;
+    padding: 0;
+    margin: -1px;
+    overflow: hidden;
+    clip: rect(0, 0, 0, 0);
+    border: 0;
+}
+
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+    position: static;
+    width: auto;
+    height: auto;
+    margin: 0;
+    overflow: visible;
+    clip: auto;
+}
+
+[role="button"] {
+    cursor: pointer;
+}
+
+table {
+    background-color: transparent;
+}
+
+table col[class*="col-"] {
+    position: static;
+    display: table-column;
+    float: none;
+}
+
+table td[class*="col-"],
+table th[class*="col-"] {
+    position: static;
+    display: table-cell;
+    float: none;
+}
+
+caption {
+    padding-top: 8px;
+    padding-bottom: 8px;
+    color: #777777;
+    text-align: left;
+}
+
+th {
+    text-align: left;
+}
+
+.table {
+    width: 100%;
+    max-width: 100%;
+    margin-bottom: 20px;
+}
+
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+    padding: 8px;
+    line-height: 1.42857143;
+    vertical-align: top;
+    border-top: 1px solid #dddddd;
+}
+
+.table > thead > tr > th {
+    vertical-align: bottom;
+    border-bottom: 2px solid #dddddd;
+}
+
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+    border-top: 0;
+}
+
+.table > tbody + tbody {
+    border-top: 2px solid #dddddd;
+}
+
+.table .table {
+    background-color: #ffffff;
+}
+
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+    padding: 5px;
+}
+
+.table-bordered {
+    border: 1px solid #dddddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+    border: 1px solid #dddddd;
+}
+
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+    border-bottom-width: 2px;
+}
+
+.table-striped > tbody > tr:nth-of-type(odd) {
+    background-color: #f9f9f9;
+}
+
+.table-hover > tbody > tr:hover {
+    background-color: #f5f5f5;
+}
+
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+    background-color: #f5f5f5;
+}
+
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+    background-color: #e8e8e8;
+}
+
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+    background-color: #dff0d8;
+}
+
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+    background-color: #d0e9c6;
+}
+
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+    background-color: #d9edf7;
+}
+
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+    background-color: #c4e3f3;
+}
+
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+    background-color: #fcf8e3;
+}
+
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+    background-color: #faf2cc;
+}
+
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+    background-color: #f2dede;
+}
+
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+    background-color: #ebcccc;
+}
+
+.table-responsive {
+    min-height: .01%;
+    overflow-x: auto;
+}
+
+@media screen and (max-width: 767px) {
+    .table-responsive {
+        width: 100%;
+        margin-bottom: 15px;
+        overflow-y: hidden;
+        -ms-overflow-style: -ms-autohiding-scrollbar;
+        border: 1px solid #dddddd;
+    }
+
+    .table-responsive > .table {
+        margin-bottom: 0;
+    }
+
+    .table-responsive > .table > thead > tr > th,
+    .table-responsive > .table > tbody > tr > th,
+    .table-responsive > .table > tfoot > tr > th,
+    .table-responsive > .table > thead > tr > td,
+    .table-responsive > .table > tbody > tr > td,
+    .table-responsive > .table > tfoot > tr > td {
+        white-space: nowrap;
+    }
+
+    .table-responsive > .table-bordered {
+        border: 0;
+    }
+
+    .table-responsive > .table-bordered > thead > tr > th:first-child,
+    .table-responsive > .table-bordered > tbody > tr > th:first-child,
+    .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+    .table-responsive > .table-bordered > thead > tr > td:first-child,
+    .table-responsive > .table-bordered > tbody > tr > td:first-child,
+    .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+        border-left: 0;
+    }
+
+    .table-responsive > .table-bordered > thead > tr > th:last-child,
+    .table-responsive > .table-bordered > tbody > tr > th:last-child,
+    .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+    .table-responsive > .table-bordered > thead > tr > td:last-child,
+    .table-responsive > .table-bordered > tbody > tr > td:last-child,
+    .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+        border-right: 0;
+    }
+
+    .table-responsive > .table-bordered > tbody > tr:last-child > th,
+    .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+    .table-responsive > .table-bordered > tbody > tr:last-child > td,
+    .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+        border-bottom: 0;
+    }
+}
+
+.clearfix:before,
+.clearfix:after {
+    display: table;
+    content: " ";
+}
+
+.clearfix:after {
+    clear: both;
+}
+
+.center-block {
+    display: block;
+    margin-right: auto;
+    margin-left: auto;
+}
+
+.pull-right {
+    float: right !important;
+}
+
+.pull-left {
+    float: left !important;
+}
+
+.hide {
+    display: none !important;
+}
+
+.show {
+    display: block !important;
+}
+
+.invisible {
+    visibility: hidden;
+}
+
+.text-hide {
+    font: 0/0 a;
+    color: transparent;
+    text-shadow: none;
+    background-color: transparent;
+    border: 0;
+}
+
+.hidden {
+    display: none !important;
+}
+
+.affix {
+    position: fixed;
+}

二进制
src/main/resources/static/img/encyclopedia/contact.png


二进制
src/main/resources/static/img/encyclopedia/h5-nav-close-btn.png


二进制
src/main/resources/static/img/encyclopedia/h5-page-title-bg.png


二进制
src/main/resources/static/img/encyclopedia/icon-icp@2x.png


二进制
src/main/resources/static/img/encyclopedia/icon.png


二进制
src/main/resources/static/img/encyclopedia/icon_m.png


二进制
src/main/resources/static/img/encyclopedia/logo.png


二进制
src/main/resources/static/img/encyclopedia/pc-icon-empty.png


二进制
src/main/resources/static/img/encyclopedia/pc-page-title-bg.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-0.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-1.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-2.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-3.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-4.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-5.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-6.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-7.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-8.png


二进制
src/main/resources/static/img/encyclopedia/title-bg-9.png


+ 36 - 0
src/main/resources/static/js/base.js

@@ -60,6 +60,16 @@ var globalHead = new Vue({
         isFiexd:false,
         classifyIndex:1
     },
+    watch:{
+        isFiexd: function(nVal,oVal){
+            // 防止跳动
+            if(nVal && isPC){
+                $("body").css('paddingTop', $("#globalHead").height() + "px");
+            }else{
+                $("body").css('paddingTop', "0px");
+            }
+        }
+    },
     methods: {
         changeClassify: function(value){
             this.classifyIndex=value;
@@ -767,3 +777,29 @@ function dialog(txt,callback) {
     });
 }
 
+
+/** 时间格式化
+ * @param {Date} date 标准时间格式 -> new Date()
+ * @param {string} format 时间格式化的格式 'yyyy-MM-dd hh:mm:ss'
+ * @returns {string} 格式化后的时间  '2017-01-01 01:00:00'
+ */
+function dateFormat(date = new Date(), format = 'yyyy-MM-dd hh:mm:ss') {
+	var o = {
+		'M+': date.getMonth() + 1, // month
+		'd+': date.getDate(), // day
+		'h+': date.getHours(), // hour
+		'm+': date.getMinutes(), // minute
+		's+': date.getSeconds(), // second
+		'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
+		S: date.getMilliseconds(), // millisecond
+	};
+	if (/(y+)/.test(format)) {
+		format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
+	}
+	for (var k in o) {
+		if (new RegExp('(' + k + ')').test(format)) {
+			format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
+		}
+	}
+	return format
+}

+ 30 - 0
src/main/resources/static/js/common/serviceapi/encyclopedia.service.js

@@ -0,0 +1,30 @@
+/*
+* 采美百科api
+* */
+
+var EncyclopediaApi = {
+    /* 根据关键词搜索商品or仪器 */
+    FetchListByKeyword: function (params, callback) {
+        Http.AjaxService({
+            url: '/commodity/search/query/baike/keyword',
+            type: 'GET',
+            data: params,
+            json: false,
+        })
+            .then(function (res) {
+                callback(res);
+            });
+    },
+    /* 更多商品or仪器楼层 */
+    FetchMoreFloorData: function (params, callback) {
+        Http.AjaxService({
+            url: '/commodity/baike/type',
+            type: 'GET',
+            data: params,
+            json: false,
+        })
+            .then(function (res) {
+                callback(res);
+            });
+    }
+};

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

@@ -4,6 +4,83 @@
  * auther ZHJY
  */
 var SupplierApi = {
+        UploadFile: function(params, callback){ // 供应商文章上传图片
+            Http.AjaxService({
+                url:'/tools/image/upload/ckeditor',
+                type:'post',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
+        GetArticleList: function(params, callback){ //供应商文章列表
+            Http.AjaxService({
+                url:'/user/shop/article/list',
+                type:'get',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
+        GetArticleForm: function(params, callback){ //供应商文章信息回显
+            Http.AjaxService({
+                url:'/user/shop/article/form',
+                type:'get',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
+        ArticleSubmitSave: function(params, callback){ //供应商文章保存
+            Http.AjaxService({
+                url:'/user/shop/article/save',
+                type:'post',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
+        ArticleStatusChange: function(params, callback){ //供应商文章状态修改
+            Http.AjaxService({
+                url:'/user/shop/article/status/update',
+                type:'post',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
+        ArticleRemove: function(params, callback){ //供应商文章状态修改
+            Http.AjaxService({
+                url:'/user/shop/article/delete',
+                type:'post',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
+        ArticleCategory: function(params, callback){
+            Http.AjaxService({
+                url:'/user/shop/article/type/list',
+                type:'get',
+                data:params,
+                json:false,
+            })
+            .then(function(res){
+                callback(res);
+            });
+        },
         GetSearchShopList:function (params, callback) {//搜索供应商列表查询
             Http.AjaxService({
                 url:'/commodity/search/query/shop',

+ 391 - 0
src/main/resources/static/js/encyclopedia/common.js

@@ -0,0 +1,391 @@
+"use strict";
+
+var scrollFlag = false;
+var navbarIndex = 0;
+var isPC = true;
+
+/**
+ * 防抖
+ * @param {*} func 执行数
+ * @param {*} wait 等待时间
+ * @param {*} immediate 是否立即执行
+ * @returns
+ */
+
+function debounce(func, wait, immediate) {
+    var timeout, result;
+    return function () {
+        var context = this;
+        var args = arguments;
+        if (timeout) clearTimeout(timeout);
+
+        if (immediate) {
+            var callNow = !timeout;
+            timeout = setTimeout(function () {
+                timeout = null;
+            }, wait);
+            if (callNow) result = func.apply(context, args);
+        } else {
+            timeout = setTimeout(function () {
+                func.apply(context, args);
+            }, wait);
+        }
+
+        return result;
+    };
+} // 还原滚动状态
+
+
+var resetScrollFlag = debounce(function () {
+    scrollFlag = false;
+}, 200);
+
+/**
+ * 监听视窗大小
+ * @param {*} size 视窗断点大小
+ * @param {*} callback 回调
+ */
+
+function responseScreen(size, callback) {
+    var isPc = isPC = $(window).width() > size; // callback(isPc)
+
+    $(window).resize(function () {
+        if (!isPc && $(this).width() > size) {
+            isPc = true;
+            callback(isPc);
+        } else if (isPc && $(this).width() < size) {
+            isPc = false;
+            callback(isPc);
+        }
+    });
+}
+
+/**
+ * 菜单栏折叠展开 父子容器
+ * @param {*} bindEl 触发事件的元素
+ * @param {*} eventName 触发折叠的事件名
+ * @param {*} callback 事件触发后的回调
+ * 需要添加指向父标签的 data-collapse-parent-target="id" 属性
+ * 需要添加指向子标签的 data-collapse-children-target="id" 属性
+ */
+
+
+function collapseToggle(bindEl, eventName, callback) {
+    var isCollapse = false; // 获取元素
+
+    bindEl = $(bindEl);
+    var parent = $(bindEl.attr('data-collapse-parent-target'));
+    var children = $(bindEl.attr('data-collapse-children-target'));
+    parent.css('transition', 'height 0.4s'); // 获取父子容器高度
+
+    var parentHeight = parent.height();
+    var childrenHeight = children.height();
+    if (parentHeight >= childrenHeight) return bindEl.hide(); // 绑定点击事件
+
+    bindEl.on(eventName, function () {
+        var height = isCollapse ? parentHeight : childrenHeight;
+        parent.height(height); //为父元素重新设置高度
+
+        isCollapse = !isCollapse; // 执行回调
+
+        callback({
+            bindEl: bindEl,
+            parent: parent,
+            children: children,
+            height: height,
+            isCollapse: isCollapse
+        });
+    });
+}
+
+/**
+ * 设置高亮
+ * @param {*} selector 节点选择器
+ * @param {*} index 被标记高亮的节点索引
+ */
+
+
+var activeCategory = debounce(function (selector, index) {
+    if (!selector || typeof index !== 'number') return;
+    var activeWidth = 0;
+    var selectorList = selector.split(',');
+    $('.navigate li, .category-list li').removeClass('active');
+    selectorList.forEach(function (el) {
+        $(el.trim()).eq(index).addClass('active');
+        activeWidth = $(el.trim()).eq(index).width();
+    });
+    var offset = ($(window).width() - activeWidth) / 2;
+    categoryScrollTo('#category ul', 0, offset);
+}, 200);
+
+/**
+ *
+ * @param {*} el 监听的元素
+ * @param {*} callback 回调
+ */
+
+function stickyResponse(el) {
+    var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
+    var callback = arguments.length > 2 ? arguments[2] : undefined;
+    $(window).scroll(function () {
+        var scrollTop = $(this).scrollTop();
+
+        if (scrollTop >= offset) {
+            callback({
+                sticky: true,
+                scrollTop: scrollTop
+            });
+        } else {
+            callback({
+                sticky: false,
+                scrollTop: scrollTop
+            });
+        }
+    });
+}
+
+/**
+ *
+ * @param {*} offsetEls 需要获取的元素列表
+ */
+
+
+function getScrollOffset(offsetEl) {
+    if (typeof offsetEl === 'string') {
+        return $(offsetEl).height();
+    }
+
+    var height = 0;
+    offsetEl.forEach(function (el) {
+        height += $(el).height();
+    });
+    return height;
+}
+
+/**
+ * 侧边栏点击跳转
+ * @param {*} selector 侧边栏节点选择器
+ * @param {*} floorEl 绑定的楼层节点选择器
+ * @param {*} offset 滚动偏移
+ * @param {*} callback 跳转后的回调
+ */
+
+
+function bindCategory(selector, floorEl) {
+    var offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
+    var callback = arguments.length > 3 ? arguments[3] : undefined;
+    $(selector).on('click', function () {
+        scrollFlag = true;
+        resetScrollFlag();
+        var index = $(this).index();
+        var floor = $(floorEl).eq(index);
+        if (!floor.length) return;
+        var floorTop = floor.offset().top - offset;
+        $('html ,body').animate({
+            scrollTop: floorTop
+        }, 400, 'linear', function () {
+            callback(index);
+        });
+    });
+}
+
+/**
+ * 监听页面滚动并观察元素是否在滚动区间
+ * @param {*} selector 被观察的元素节点选择器
+ * @param {*} offset 滚动偏移
+ * @param {*} callback 观察命中的回调
+ */
+
+
+function pageScrollObserve(selector) {
+    var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
+    var callback = arguments.length > 2 ? arguments[2] : undefined;
+    $(window).scroll(function () {
+        if (scrollFlag) return;
+        var scrollTop = $(this).scrollTop();
+
+        if (scrollTop < $(selector).eq(0).offset().top - offset) {
+            callback(null, -1);
+        }
+
+        $(selector).each(function (index, el) {
+            var offsetTop = $(el).offset().top - offset;
+            var height = $(el).height();
+
+            if (scrollTop >= offsetTop && scrollTop < offsetTop + height) {
+                callback(el, index);
+            }
+        });
+    });
+}
+
+/**
+ * 动态生成侧边导航
+ * @param {*} selector 从该节点元素中获取文本
+ * @param {*} bindEl 生成的导航要挂载的节点
+ */
+
+
+function makeNavigate(selector, bindEl) {
+    var ul = document.createElement('ul');
+    $(selector).each(function (index, el) {
+        var li = document.createElement('li');
+        var a = document.createElement('a');
+        a.innerText = $(el).text();
+        a.setAttribute('href', '#' + $(el).text());
+        li.appendChild(a);
+        if (index === 0) li.classList.add('active');
+        ul.appendChild(li);
+    });
+    $(bindEl).append(ul);
+}
+
+/**
+ * 可折叠楼层
+ * @param {*} options
+ * root: '.floor', // 根节点元素
+ * collapse: '.article', //可折叠元素节点
+ * item: '.section', // 子元素节点
+ * touch: '.more-btn', // 事件绑定元素节点
+ * size: 6, // 每页最多显示的子元素个数
+ * col: 3, // 每列最多显示的子元素个数
+ * minHeight: $('.floor').find('.section').height() + 24, // 单个子元素的高度
+ * open: function(floor){}
+ * close: function(floor){}
+ */
+
+
+function makeFloorList(options) {
+    var row = options.size / options.col; //每列显示的个数
+
+    var floorMap = [];
+    var minHeight = options.minHeight; // 最小高度
+
+    $(options.root).each(function (index, el) {
+        var floorInfo = floorMap[index] = Object.create(null);
+        var selector = floorInfo.$floor = $(el); // 当前楼层对象
+
+        floorInfo.count = selector.find(options.item).length; // 总数
+
+        floorInfo.step = Math.ceil(floorInfo.count / options.size); // 可展开步数
+
+        floorInfo.current = 1; // 当前步数
+
+        floorInfo.hasMore = floorInfo.count > options.size; // 是否还有更多
+        // 初始化高度,只有在可展开时设置初始高度
+
+        if (floorInfo.hasMore) {
+            floorInfo.height = minHeight * row * floorInfo.current;
+            selector.find(options.collapse).height(floorInfo.height);
+            selector.find(options.collapse).css({
+                overflow: 'hidden',
+                transition: 'height .4s'
+            });
+        }
+    }); // 为按钮绑定事件
+
+    floorMap.forEach(function (floor) {
+        if (!floor.hasMore) return floor.$floor.find(options.touch).parent().hide();
+        floor.$floor.find(options.touch).on('click', function () {
+            moreClick(floor);
+        });
+    }); // 查看更多
+
+    function moreClick(floor) {
+        if (floor.current === floor.step) return closeMore(floor); // 剩下的个数
+
+        var lastCount = floor.count - options.size * floor.current;
+        floor.current++;
+        floor.hasMore = floor.current < floor.step; // 如果还有更多
+
+        if (floor.hasMore || lastCount > 3) {
+            floor.$floor.find(options.collapse).height(minHeight * row * floor.current);
+        } else {
+            floor.$floor.find(options.collapse).height(minHeight * row * (floor.current - 1) + minHeight);
+        } // 展开回调
+
+
+        options.open(floor);
+    } // 全部收起
+
+
+    function closeMore(floor) {
+        floor.current = 1;
+        floor.hasMore = true;
+        floor.$floor.find(options.collapse).height(floor.height); // 收起回调
+
+        options.close(floor);
+    }
+} // 激活导航栏
+
+
+function activeNavbar(selector) {
+    var baseHref = window.location.href;
+    navbarIndex = localStorage.getItem('navbarIndex') || 0;
+    selector = $(selector);
+    selector.each(function (index, el) {
+        $(el).removeClass('active');
+
+        if ($(el).find('a').length > 0) {
+            var href = $(el).find('a').attr('href');
+            href = href.split('?')[0].split('#')[0];
+
+            if (baseHref.indexOf(href) > -1) {
+                navbarIndex = index;
+                localStorage.setItem('navbarIndex', navbarIndex);
+            }
+        }
+    });
+    selector.eq(navbarIndex).addClass('active');
+}
+
+/**
+ * 将导航滚动到激活位置
+ * @param {*} selector 导航元素
+ * @param {*} scrollLeft 指定位置
+ * @param {*} offset 偏移
+ * @returns
+ */
+
+
+function categoryScrollTo(selector, scrollLeft) {
+    var offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
+    if ($(window).width <= 768) return;
+    selector = $(selector);
+    var sub = selector.children().eq(0).offset().left + offset;
+    scrollLeft = Math.ceil(selector.find('.active').offset().left - sub);
+    $(selector).animate({
+        scrollLeft: scrollLeft
+    }, 200, 'linear');
+} // 移动端绑定滑动事件
+
+
+function slideBarHandle(selector) {
+    var display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'block';
+    if ($(window).width() > 768) return;
+    selector = $(selector);
+    var target = $(selector.attr('data-target'));
+    selector.on('click', function () {
+        target.slideDown();
+        target.css('display', display);
+    });
+    target.on('click', function () {
+        target.slideUp();
+    });
+}
+
+$(function () {
+    activeNavbar('.navbar .nav li');
+    slideBarHandle('#menuBtn', 'flex');
+    slideBarHandle('#hotKeyword');
+    responseScreen(768, function () {
+        window.location.reload();
+    });
+    // 搜索框内容为空时阻止表单提交
+    $('form').submit(function(){
+        const searchKeyword =  $('#searchKeyword');
+        const val = searchKeyword.val().trim();
+        searchKeyword.val(val);
+        if(!val) return false;
+    });
+});

+ 81 - 0
src/main/resources/static/js/encyclopedia/detail.js

@@ -0,0 +1,81 @@
+"use strict";
+
+function initPreviewImage() {
+    var imageGroup = {};
+    var imageEls = document.querySelectorAll('.content');
+    if (imageEls.length <= 0) return;
+    imageEls.forEach(function (imageEl, index) {
+        imageGroup['cm-images-' + index] = new Viewer(imageEl);
+    });
+    console.log('初始化图片预览成功')
+}
+
+$(function () {
+    // 页面滚动偏移
+    var offset = 0;
+    var windowWidth = $(window).width();
+    var timer = null; // 定时器
+    var middleScreenWidth = 1450;
+    // 生成导航
+    makeNavigate('.section h2', '.navigate');
+    if (windowWidth > 768) {
+        offset = getScrollOffset('.navbar') + 10;
+    } else {
+        offset = getScrollOffset(['.navbar', '.navigate']) + 10;
+    }
+    // 侧边导航跳转
+    bindCategory('.navigate li', '.section', offset, function (index) {
+        activeCategory('.navigate li', index);
+    });
+    // 页面滚动观测
+    pageScrollObserve('.section', offset, function (el, index) {
+        if (index > -1) {
+            activeCategory('.navigate li', index);
+        }
+    });
+    // 常见问题展开收起
+    $('[data-toggle="collapse"]').each(function (index, el) {
+        var targetEl = $(el).attr('data-target');
+        if (!targetEl) return;
+        $(targetEl).hide();
+        $(el).on('click', function () {
+            $(targetEl).toggle();
+            $(el).toggleClass('arrowup');
+        });
+    });
+
+    $('#contactPopupBtn').on('click', function () {
+        $('#contactPopup').show();
+    });
+    $('#contactPopupClose').on('click', function () {
+        $('#contactPopup').hide();
+    });
+
+    // 切换显示侧边导航
+    function toggleNavigate(selector, time, maxWidth, offset) {
+        selector = $(selector);
+        if (windowWidth <= middleScreenWidth) {
+            selector.hide();
+        }
+        // 鼠标移动事件
+        $('body').on('mousemove', function (e) {
+            var width = $(this).width();
+            if (!(e.clientX > width - offset && width <= maxWidth)) return;
+            clearTimeout(timer);
+            selector.fadeIn();
+            timer = setTimeout(function () {
+                selector.fadeOut();
+            }, time)
+        });
+        // 窗口大小改变
+        $(window).resize(function () {
+            if ($(this).width() <= maxWidth) {
+                selector.hide();
+            } else {
+                selector.show();
+            }
+        });
+    }
+    initPreviewImage()
+    // toggleNavigate('.navigate', 1000, middleScreenWidth, 80);
+});

+ 90 - 0
src/main/resources/static/js/encyclopedia/index.js

@@ -0,0 +1,90 @@
+"use strict";
+
+$(function () {
+    var windowWidth = $(window).width();
+    // 页面滚动偏移
+    var offset = 0;
+    // pc端
+    if (windowWidth > 768) {
+        offset = getScrollOffset('.navbar');
+        // 导航菜单展开折叠
+        collapseToggle('[data-collapse-toggle="category"]', 'click', function (result) {
+            var bindEl = result.bindEl,
+                parent = result.parent,
+                height = result.height,
+                isCollapse = result.isCollapse;
+            var text = isCollapse ? '展开' : '收起';
+            var lineHeight = height - 32;
+            bindEl.children('.icon').toggleClass('arrowup');
+            bindEl.children('span').text(text);
+            parent.children('.name').children('em').height(lineHeight);
+        });
+        // 可折叠楼层
+        // makeFloorList({
+        //     root: '.floor',
+        //     // 根节点元素
+        //     collapse: '.article',
+        //     //可折叠元素
+        //     item: '.section',
+        //     // 子元素
+        //     touch: '.more-btn',
+        //     // 事件绑定元素
+        //     size: 6,
+        //     // 每页最多显示的子元素个数
+        //     col: 3,
+        //     // 每列最多显示的子元素个数
+        //     minHeight: $('.floor').find('.section').height() + 24,
+        //     // 单个子元素的高度
+        //     // 展开时的回调
+        //     open: function open(floor) {
+        //         if (floor.current === floor.step) {
+        //             floor.$floor.find('.more span').text('收起全部');
+        //             floor.$floor.find('.more .icon').addClass('arrowup');
+        //         }
+        //     },
+        //     // 收起时的回调
+        //     close: function close(floor) {
+        //         floor.$floor.find('.more span').text('查看更多');
+        //         floor.$floor.find('.more .icon').removeClass('arrowup');
+        //     }
+        // });
+        $('.floor-list .floor').each(function(index, el){
+            if($(el).find('.section').length < 6){
+                $(el).find('.more').hide();
+            }
+        });
+    } else {
+        // 移动端
+        $('.floor-list .floor').each(function(index, el){
+            if($(el).find('.section').length < 6){
+                $(el).find('.h5-more-btn').hide();
+            }
+        });
+        offset = getScrollOffset(['.navbar', '.category']);
+        stickyResponse('#category', getScrollOffset('.banner'), function (e) {
+            if (e.sticky) {
+                $('#category-list').addClass('fixed');
+            } else {
+                $('#category-list').removeClass('fixed');
+            }
+        });
+    }
+
+    // 生成导航
+    makeNavigate('.floor h2', '.navigate');
+    makeNavigate('.floor h2', '#category-list');
+    // 楼层滚动
+    bindCategory('.navigate li,.category-list li', '.floor', offset, function (index) {
+        activeCategory('.navigate li, .category-list li', index);
+    });
+    // 页面滚动
+    $('.navigate').hide();
+    pageScrollObserve('.floor', offset, function (el, index) {
+        if (index > -1) {
+            windowWidth > 768 && $('.navigate').fadeIn();
+            activeCategory('.navigate li, .category-list li', index);
+        } else {
+            windowWidth > 768 && $('.navigate').fadeOut();
+        }
+    });
+});

+ 66 - 0
src/main/resources/static/js/encyclopedia/moreFloor.js

@@ -0,0 +1,66 @@
+"use strict";
+
+// 页码vue实例
+var pagination = new Vue({
+    el: '#pagination',
+    data: {
+        name: 'more-list',
+        pageSize: 12,
+        pageNum: 0,
+        totalPage: 0,
+        typeId: 0,
+        jumpInput: 1
+    },
+    computed: {
+        // 页码
+        pagination: function pagination() {
+            return this.makePagination(this.pageNum, this.totalPage);
+        }
+    },
+    mounted: function mounted() {
+        window.name = this.name;
+        this.initPaginationData();
+    },
+    methods: {
+        // 初始化页码
+        initPaginationData: function initPaginationData() {
+            var moreData = getMoreData() || {};
+            this.pageNum = moreData.pageNum;
+            this.pageSize = moreData.pageSize;
+            this.totalPage = moreData.totalPage;
+            this.typeId = moreData.typeId;
+            console.log(moreData);
+        },
+        makeUrl: function makeUrl(pageNum) {
+            return 'more-' + this.typeId + '-' + pageNum + '-' + this.pageSize + '.html';
+        },
+        // 页码切换
+        pageChange: function pageChange(pageNum) {
+            if (pageNum < 1 || pageNum > this.totalPage) return;
+            window.open(this.makeUrl(pageNum), this.name);
+        },
+        // 处理页码
+        makePagination: function makePagination(pageNum, totalPage) {
+            // 页码列表
+            var arr = [];
+            // 初始化页码列表
+            for (var i = 1; i <= totalPage; i++) {
+                arr[i - 1] = i;
+            }
+
+            if (totalPage <= 7) return arr;
+            // 查找当前页码在页码列表中的位置
+            var pop = arr.indexOf(pageNum);
+            // 截取页码
+            if (pageNum < 4) {
+                arr = arr.splice(pop + 1 - pageNum, 6);
+            } else if (pageNum > totalPage - 3) {
+                arr = arr.reverse().splice(0, 6).reverse();
+            } else {
+                arr = arr.splice(pop - 2, 5);
+            }
+            console.log(arr);
+            return arr;
+        }
+    }
+});

+ 105 - 0
src/main/resources/static/js/encyclopedia/search.js

@@ -0,0 +1,105 @@
+"use strict";
+var search = new Vue({
+    el: '#search',
+    data: {
+        listQuery: {
+            keyword: '',
+            pageSize: 12,
+            pageNum: 1
+        },
+        searchList: [], // 查询列表
+        totalRecord: 0,
+        totalPage: 0,
+        jumpInput: 1
+    },
+    filters: {
+        // 处理url
+        formatUrl: function (item) {
+            if (item.commodityType === 1) {
+                return 'product-' + item.productId + '.html';
+            } else {
+                return 'instrument-' + item.productId + '.html';
+            }
+        }
+    },
+    computed: {
+        // 页码
+        pagination: function () {
+            return this.makePagination(this.listQuery.pageNum, this.totalPage);
+        }
+    },
+    mounted: function () {
+        this.initSearchWord();
+        this.fetchSearchList();
+    },
+    methods: {
+        // 初始化关键字
+        initSearchWord: function () {
+            var query = this.queryString(window.location.search.slice(1));
+            document.querySelector('#searchKeyword').value = query.keyword;
+            this.listQuery.keyword = query.keyword || '';
+        },
+        // 获取查询列表
+        fetchSearchList: function () {
+            var self = this;
+            EncyclopediaApi.FetchListByKeyword(this.listQuery, function (res) {
+                if (res.code === 0) {
+                    var data = res.data;
+                    self.listQuery.pageNum = data.pageNum;
+                    self.searchList = data.results;
+                    self.totalRecord = data.totalRecord;
+                    self.totalPage = data.totalPage;
+                } else {
+                    CAIMEI.Alert(res.msg, '确定', false);
+                }
+            });
+        },
+        // 页码切换
+        pageChange: function (pageNum) {
+            console.log(pageNum);
+            if (pageNum < 1 || pageNum > this.totalPage) return;
+            this.listQuery.pageNum = pageNum;
+            this.fetchSearchList();
+        },
+        // 根据关键词进行标题格式化
+        formatFromKeyword: function (name) {
+            var reg = new RegExp(this.listQuery.keyword, 'ig');
+            return name.replace(reg, function ($1) {
+                return '<span style="color: #e15616">' + $1 + '</span>';
+            });
+        },
+        // 处理url参数 返回参数键值对
+        queryString: function (queryStr) {
+            var queryStrList = decodeURI(queryStr).split('&');
+            var query = Object.create(null);
+            queryStrList.forEach(function (str) {
+                var temp = str.split('=');
+                var key = temp[0];
+                var val = temp[1] || '';
+                query[key] = val;
+            });
+            return query;
+        },
+        // 处理页码
+        makePagination: function (pageNum, totalPage) {
+            // 页码列表
+            var arr = [];
+            // 初始化页码列表
+            for (var i = 1; i <= totalPage; i++) {
+                arr[i - 1] = i;
+            }
+            if (totalPage <= 7) return arr;
+            // 查找当前页码在页码列表中的位置
+            var pop = arr.indexOf(pageNum);
+            // 截取页码
+            if (pageNum < 4) {
+                arr = arr.splice(pop + 1 - pageNum, 6);
+            } else if (pageNum > totalPage - 3) {
+                arr = arr.reverse().splice(0, 6).reverse();
+            } else {
+                arr = arr.splice(pop - 2, 5);
+            }
+            return arr;
+        }
+    }
+});

+ 214 - 0
src/main/resources/static/js/supplier-center/article/article-edit.js

@@ -0,0 +1,214 @@
+"use strict";
+
+var articleEdit = new Vue({
+    el: '#articleEdit',
+    mixins: [formMixin, uploadMixin],
+    data: {
+        NODE_ENV_BASE_URL: '',
+        editor: null,
+        shopId: GLOBAL_SHOP_ID,
+        // 供应商id
+        formData: {
+            articleId: 0,
+            // 文章id
+            title: '',
+            // 标题
+            articleContent: '',
+            // 内容
+            guidanceImage: '',
+            // 引导图
+            keyword: '',
+            // seo关键词
+            label: '',
+            // 标签
+            publisher: '',
+            // 发布人
+            recommendContent: '',
+            // 推荐语
+            source: '',
+            // 来源
+            status: 1,
+            // 状态
+            typeId: '' // 文章分类
+
+        },
+        articleLabels: [],
+        chooseLabels: [],
+        articleTypeList: [],
+        addLabelName: ''
+    },
+    watch: {
+        chooseLabels: function chooseLabels(newVal) {
+            this.formData.label = newVal.join(',');
+        },
+        'formData.label': function formDataLabel(newVal, oldVal) {
+            if (!newVal.trim()) {
+                return this.chooseLabels = [];
+            }
+            if (newVal === oldVal) return;
+            this.chooseLabels = newVal.split(',');
+        }
+    },
+    created: function created() {
+        this.init();
+    },
+    mounted: function mounted() {
+        this.NODE_ENV_BASE_URL = $('#coreServer').val(); // console.log(this.NODE_ENV_BASE_URL);
+        $('.navLayout').find('.navList').removeClass("on").find('.con').hide().find('a').removeClass("on");
+        $('.navLayout').find('.navList').eq(2).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
+        this.initEditor();
+    },
+    beforeDestroy: function beforeDestroy() {
+        // 销毁编辑器
+        this.editor.destroy();
+        this.editor = null;
+        localStorage.removeItem('articleId');
+    },
+    methods: {
+        // 页面初始化
+        init: function init() {
+            var articleId = localStorage.getItem('articleId') || 0;
+            this.formData.articleId = articleId;
+            this.fetchArticleCatagory(); // 文章id就是修改文章
+            this.fetchFormList();
+        },
+        // 获取标签列表和分类列表
+        fetchFormList: function fetchFormList() {
+            var that = this;
+            SupplierApi.GetArticleForm({
+                articleId: this.formData.articleId
+            }, function (res) {
+                if (res.code === 0) {
+                    // console.log(res);
+                    that.articleLabels = res.data.articleLabels.split(','); // 初始化表单数据
+
+                    if (res.data.shopArticle) {
+                        that.setFormData(res.data.shopArticle);
+                    }
+                } else {
+                    CAIMEI.Alert(res.msg, '确定', false);
+                }
+            });
+        },
+        // 设置表单初始数据
+        setFormData: function setFormData(shopArticle) {
+            for (var key in this.formData) {
+                if (key === 'status' || key === 'typeId') {
+                    this.formData[key] = shopArticle[key].toString();
+                } else {
+                    this.formData[key] = shopArticle[key];
+                }
+            }
+
+            this.editor.txt.html(this.formData.articleContent);
+        },
+        // 获取文章分类
+        fetchArticleCatagory: function fetchArticleCatagory() {
+            var that = this;
+            SupplierApi.ArticleCategory({}, function (res) {
+                if (res.code === 0) {
+                    // console.log(res);
+                    that.articleTypeList = res.data;
+                } else {
+                    CAIMEI.Alert(res.msg, '确定', false);
+                }
+            });
+        },
+        // 选择文章标签
+        labelClick: function labelClick(index) {
+            var newLabel = this.articleLabels[index];
+            var popIndex = this.chooseLabels.indexOf(newLabel);
+
+            if (popIndex > -1) {
+                this.chooseLabels.splice(popIndex, 1);
+            } else {
+                this.chooseLabels.push(newLabel);
+            }
+        },
+        // 手动添加文章标签
+        addLabel: function addLabel() {
+            if (!this.addLabelName.trim()) return;
+            if (this.chooseLabels.indexOf(this.addLabelName) > -1) return this.addLabelName = '';
+            this.chooseLabels.push(this.addLabelName);
+            this.addLabelName = '';
+        },
+        // 判断标签是否被选
+        checkLabel: function checkLabel(index) {
+            return this.chooseLabels.indexOf(this.articleLabels[index]) > -1;
+        },
+        // 引导图上传(文章封面图)
+        fileInputChange: function fileInputChange(e) {
+            var _this = this;
+
+            this.uploadImage(e.target.files[0]).then(function (res) {
+                _this.formData.guidanceImage = res;
+            });
+        },
+        // 初始化富文本
+        initEditor: function initEditor() {
+            var E = window.wangEditor;
+            this.editor = new E("#editor");
+            this.initEditorOptions(this.editor, this.NODE_ENV_BASE_URL);
+            this.editor.create();
+        },
+        // 保存 提交表单
+        handleSave: function handleSave() {
+            var _this = this;
+            this.formData.articleContent = this.editor.txt.html();
+            this.handleFormData(); // console.log(this.formData);
+            this.validAll(this.formData).then(function (valid) {
+                console.log(valid);
+                _this.save();
+            }).catch(function (err) {
+                console.log(err);
+            });
+        },
+        // 保存接口
+        save: function save() {
+            var _this = this;
+            this.formData.shopId = this.shopId;
+            SupplierApi.ArticleSubmitSave(this.formData, function (res) {
+                if (res.code === 0) {
+                    CAIMEI.dialog('保存成功');
+                    setTimeout(function () {
+                        _this.handleBack();
+                    }, 2000);
+                } else {
+                    CAIMEI.Alert(res.msg, '确定', false);
+                }
+            });
+        },
+        // 处理表单数据
+        handleFormData: function handleFormData() {
+            var that = this;
+            $('.form').submit(function (eventData) {
+                var formData = that.serializeArrayToObj($(this).serializeArray());
+
+                for (var key in formData) {
+                    if (key === 'typeId' || key === 'status') {
+                        that.formData[key] = Number(formData[key]);
+                    } else {
+                        that.formData[key] = formData[key];
+                    }
+                }
+
+                return false;
+            });
+        },
+        // 表单数据转为对象
+        serializeArrayToObj: function serializeArrayToObj(serializeArray) {
+            var obj = Object.create(null);
+            serializeArray.forEach(function (item) {
+                obj[item.name] = item.value;
+            });
+            return obj;
+        },
+        // 返回文章列表页面
+        handleBack: function handleBack() {
+            localStorage.removeItem('articleId');
+            window.open('/supplier/article/list.html', 'supplier-article-list');
+            window.close();
+        }
+    }
+});
+

+ 227 - 0
src/main/resources/static/js/supplier-center/article/article-list.js

@@ -0,0 +1,227 @@
+"use strict";
+
+var articleList = new Vue({
+    el: '#articleList',
+    data: {
+        name: 'supplier-article-list',
+        refreshType: '',
+        hidden: '',
+        visibilityChange: '',
+        listRecord: 0,
+        shopId: GLOBAL_SHOP_ID || 0,
+        listQuery: {
+            articleId: '',
+            title: '',
+            publisher: '',
+            auditStatus: '',
+            typeId: '',
+            pageNum: 1,
+            pageSize: 10
+        },
+        pageInput: 1,
+        pageTotal: 0,
+        articleList: [],
+        articleTypeList: []
+    },
+    computed: {
+        pageTotal: function pageTotal() {
+            var total = Math.ceil(this.listRecord / this.listQuery.pageSize);
+            return total > 0 ? total : 1;
+        },
+        showPageBtn: function showPageBtn() {
+            var total = Math.ceil(this.listRecord / this.listQuery.pageSize);
+            total = total > 0 ? total : 1;
+            var index = this.listQuery.pageNum,
+                arr = [];
+
+            if (total <= 6) {
+                for (var i = 1; i <= total; i++) {
+                    arr.push(i);
+                }
+
+                return arr;
+            }
+
+            if (index <= 3) return [1, 2, 3, 4, 5, 0, total];
+            if (index >= total - 2) return [1, 0, total - 4, total - 3, total - 2, total - 1, total];
+            return [1, 0, index - 2, index - 1, index, index + 1, index + 2, 0, total];
+        }
+    },
+    filters: {
+        // 时间格式化
+        formatDate: function formatDate(date) {
+            if (!date) return '---';
+            return dateFormat(new Date(date));
+        }
+    },
+    created: function created() {
+        this.getArticleList();
+        this.fetchArticleCatagory();
+    },
+    mounted: function mounted() {
+        window.name = this.name;
+        // this.bindWindowHiddenOrVis();
+        $('.navLayout').find('.navList').removeClass("on").find('.con').hide().find('a').removeClass("on");
+        $('.navLayout').find('.navList').eq(2).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
+    },
+    methods: {
+        // 获取文章列表
+        getArticleList: function getArticleList() {
+            var that = this;
+            this.listQuery.shopId = this.shopId;
+            SupplierApi.GetArticleList(this.listQuery, function (res) {
+                // console.log(res);
+                if (res.code === 0) {
+                    that.listRecord = res.data.total;
+                    that.articleList = res.data.list;
+                    that.pageTotal = res.data.pages;
+                } else {
+                    CAIMEI.Alert(res.msg, '确定', false);
+                }
+            });
+        },
+        //表格操作按钮点击
+        clickOption: function clickOption(article, type) {
+            var handles = {
+                1: this.toEdit,
+                2: this.changeStatus,
+                3: this.toDetail,
+                4: this.handleDelete
+            };
+            handles[type](article);
+        },
+        //跳转编辑页面
+        toEdit: function toEdit(article) {
+            localStorage.setItem('articleId', article.articleId);
+            window.open('/supplier/article/edit.html');
+        },
+        //修改状态
+        changeStatus: function changeStatus(article) {
+            var newStatus = 1;
+
+            if (article.status === 1) {
+                newStatus = 0;
+            }
+
+            SupplierApi.ArticleStatusChange({
+                articleId: article.articleId,
+                shopId: this.shopId,
+                status: newStatus
+            }, function (res) {
+                if (res.code === 0) {
+                    // 不刷新数据更新
+                    article.status = newStatus;
+                    CAIMEI.dialog('修改文章状态成功!');
+                } else {
+                    CAIMEI.dialog('修改文章状态失败!');
+                }
+            });
+        },
+        //查看
+        toDetail: function toDetail(article) {
+            if (article.auditStatus !== 2) return CAIMEI.dialog('请等待审核通过后查看!');
+            if (!article.status) return CAIMEI.dialog('文章未启用!');
+            window.open('/info/detail-' + article.articleId + '-1.html');
+        },
+        // 跳转添加文章页面
+        handleAddArticle: function handleAddArticle() {
+            window.open('/supplier/article/edit.html');
+        },
+        // 查询文章列表
+        handleSearchList: function handleSearchList() {
+            this.listQuery.pageNum = 1;
+            this.getArticleList();
+        },
+        // 获取文章列表
+        fetchArticleCatagory: function fetchArticleCatagory() {
+            var that = this;
+            SupplierApi.ArticleCategory({}, function (res) {
+                if (res.code === 0) {
+                    that.articleTypeList = res.data;
+                } else {
+                    CAIMEI.Alert(res.msg, '确定', false);
+                }
+            });
+        },
+        //删除确认
+        handleDelete: function handleDelete(article) {
+            var that = this;
+            var params = {
+                content: '确认删除改文章?',
+                cancelBtnText: '取消',
+                confitmBtnText: '删除'
+            };
+            CAIMEI.Popup(params, function () {
+                that.articleDelete(article);
+            });
+        },
+        // 删除文章
+        articleDelete: function articleDelete(article) {
+            var that = this;
+            SupplierApi.ArticleRemove({
+                articleId: article.articleId
+            }, function (res) {
+                if (res.code === 0) {
+                    that.getArticleList();
+                    CAIMEI.dialog('删除文章成功!');
+                } else {
+                    CAIMEI.dialog('删除文章失败!');
+                }
+            });
+        },
+        //页码跳转
+        toPagination: function toPagination(pageNum) {
+            if (pageNum <= this.pageTotal) {
+                this.listQuery.pageNum = pageNum; // console.log('页码跳转');
+                this.getArticleList();
+                $('html ,body').animate({scrollTop: 0}, 400, 'linear'); // 页面置顶
+            }
+        },
+        // 输入框设置页码
+        checkNum: function checkNum() {
+            if (this.pageInput > this.pageTotal) {
+                this.pageInput = this.pageTotal;
+            } else if (this.pageInput < 1) {
+                this.pageInput = 1;
+            }
+        },
+        bindWindowHiddenOrVis: function bindWindowHiddenOrVis() {
+            // 设置隐藏属性和改变可见属性的事件的名称
+            if (typeof document.hidden !== "undefined") {
+                // Opera 12.10 and Firefox 18 and later support
+                this.hidden = "hidden";
+                this.visibilityChange = "visibilitychange";
+            } else if (typeof document.msHidden !== "undefined") {
+                this.hidden = "msHidden";
+                this.visibilityChange = "msvisibilitychange";
+            } else if (typeof document.webkitHidden !== "undefined") {
+                this.hidden = "webkitHidden";
+                this.visibilityChange = "webkitvisibilitychange";
+            } // 如果浏览器不支持addEventListener 或 Page Visibility API 给出警告
+
+
+            if (typeof document.addEventListener === "undefined" || typeof document[this.hidden] === "undefined") {
+                console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
+            } else {
+                // 处理页面可见属性的改变
+                document.addEventListener(this.visibilityChange, this.handleVisibilityChange, false);
+            }
+        },
+        // 如果页面是展示状态 && 需要刷新列表,则刷新列表
+        handleVisibilityChange: function handleVisibilityChange() {
+            var that = this;
+            this.refreshType = window.localStorage.getItem('refreshType');
+
+            if (document[that.hidden]) {
+                console.log(this.refreshType);
+                console.log('article list page is show');
+
+                if (this.refreshType) {
+                    that.listQuery.pageNum = 1;
+                    window.localStorage.removeItem('refreshType');
+                    that.getArticleList();
+                }
+            }
+        }
+    }
+});

+ 158 - 0
src/main/resources/static/js/supplier-center/article/formMixin.js

@@ -0,0 +1,158 @@
+"use strict";
+
+var formMixin = {
+    data: {
+        validData: {},
+        rules: {
+            title: [{
+                required: true,
+                type: 'string',
+                message: '请输入文章标题',
+                trigger: 'blur'
+            }],
+            label: [{
+                required: true,
+                message: '请输入文章标签',
+                trigger: ['blur', 'change']
+            }],
+            keyword: [{
+                required: true,
+                message: '请输入文章seo关键词',
+                trigger: 'blur'
+            }],
+            publisher: [{
+                required: true,
+                message: '请输入发布人',
+                trigger: 'blur'
+            }],
+            recommendContent: [{
+                required: true,
+                message: '请输入文章推荐语',
+                trigger: 'blur'
+            }],
+            articleContent: [{
+                required: true,
+                message: '请输入文章内容',
+                trigger: 'change'
+            }],
+            typeId: [{
+                required: true,
+                message: '请选择文章分类',
+                trigger: 'change'
+            }],
+            guidanceImage: [{
+                required: true,
+                message: '请上传文章引导图',
+                trigger: 'change'
+            }],
+            status: [{
+                required: true,
+                message: '请选择文章状态',
+                trigger: 'change'
+            }]
+        }
+    },
+    mounted: function mounted() {
+        //初始化表单验证
+        this.initValidForm(this.formData);
+    },
+    created: function created() {
+        //初始化验证关系对象
+        this.initValidData();
+    },
+    methods: {
+        //初始化验证关系对象
+        initValidData: function initValidData() {
+            for (var key in this.rules) {
+                this.$set(this.validData, key, {
+                    valid: true,
+                    message: ''
+                });
+            }
+        },
+        //初始化表单验证
+        initValidForm: function initValidForm(formData) {
+            var _this = this;
+
+            var that = this;
+
+            var _loop = function _loop(key) {
+                var rules = _this.rules[key];
+                var input = document.querySelector(".form-item[prop=\"".concat(key, "\"] input"));
+                var textarea = document.querySelector(".form-item[prop=\"".concat(key, "\"] textarea"));
+                var trigger = rules[0].trigger.toString();
+
+                if (trigger.indexOf('blur') > -1) {
+                    if (input) {
+                        input.addEventListener('blur', function () {
+                            that.validInputHandle(formData, key, rules);
+                        });
+                    }
+
+                    if (textarea) {
+                        textarea.addEventListener('blur', function () {
+                            that.validInputHandle(formData, key, rules);
+                        });
+                    }
+                }
+
+                if (trigger.indexOf('change') > -1) {
+                    var str = 'formData.' + key;
+                    that.$watch(str, function (newVal, oldVal) {
+                        that.validInputHandle(formData, key, rules);
+                    });
+                }
+            };
+
+            for (var key in this.rules) {
+                _loop(key);
+            }
+        },
+        //数据校验
+        validInputHandle: function validInputHandle(formData, key, rules) {
+            var validData = {
+                valid: true,
+                message: ''
+            };
+            rules.forEach(function (rule, index) {
+                if (!validData.valid) return; // 字符长度
+
+                var len = formData[key].toString().trim().length; // 是否必填
+
+                if (rule.required && !formData[key]) {
+                    validData.valid = false;
+                    validData.message = rule.message || '';
+                } // 最大值最小值
+
+
+                if (rule.maxLength && len < rule.minLength || rule.maxLength && len > rule.maxLength) {
+                    validData.valid = false;
+                    validData.message = rule.message || '';
+                } // 自定义校验规则
+
+
+                if (rule.pattern && !rule.pattern.test(formData[key])) {
+                    validData.valid = false;
+                    validData.message = rule.message || '';
+                }
+            });
+            this.validData[key] = validData;
+        },
+        // 验证全部数据
+        validAll: function validAll(formData) {
+            for (var key in this.rules) {
+                var rules = this.rules[key];
+                this.validInputHandle(formData, key, rules);
+            }
+
+            for (var _key in this.validData) {
+                // console.log(key, this.validData[key].valid);
+                if (!this.validData[_key].valid) {
+                    return Promise.reject(false);
+                }
+            }
+
+            return Promise.resolve(true);
+        }
+    }
+};

+ 37 - 0
src/main/resources/static/js/supplier-center/article/uploadMixin.js

@@ -0,0 +1,37 @@
+"use strict";
+
+var uploadMixin = {
+    methods: {
+        // 富文本框配置
+        initEditorOptions: function initEditorOptions(editor, baseUrl) {
+            var that = this;
+            this.editor.config.zIndex = 333;
+            this.editor.config.height = 400;
+            this.editor.config.uploadImgMaxSize = 2 * 1024 * 1024;
+            this.editor.config.uploadImgMaxLength = 5; // 一次最多上传 5 个图片
+
+            this.editor.config.customUploadImg = function (resultFiles, insertImgFn) {
+                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();
+                });
+            });
+        }
+    }
+};

+ 1 - 1
src/main/resources/static/js/supplier-center/setting/information.js

@@ -466,6 +466,6 @@
             }
         });
      $('.navLayout').find('.navList').removeClass("on").find('.con').hide().find('a').removeClass("on");
-     $('.navLayout').find('.navList').eq(2).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
+     $('.navLayout').find('.navList').eq(3).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
     }
  })

+ 1 - 1
src/main/resources/static/js/supplier-center/setting/password.js

@@ -219,7 +219,7 @@ var passwordPage = new Vue({
     mounted: function () {
         var _self = this;
         $('.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");
+        $('.navLayout').find('.navList').eq(4).addClass("on").find('.con').show().find('a').eq(0).addClass("on");
 
          }
 });

+ 2 - 1
src/main/resources/static/js/utils.js

@@ -300,4 +300,5 @@ CAIMEI.returnedTarget = function(){//对象合并 IE 兼容方法
             return target;
         };
     }
-}
+};
+

文件差异内容过多而无法显示
+ 15 - 0
src/main/resources/static/lib/wangEditor.min.js


+ 1 - 0
src/main/resources/templates/article/components/article-header.html

@@ -13,6 +13,7 @@
                 <a class="home" href="/" target="_blank">商城</a>
                 <a th:each="type: *{articleType}" th:text="${type.name}" th:href="'/info/center-'+${type.id}+'-1.html'" th:class="${typeId==type.id}?'typeBtn current':'typeBtn'" th:typeId="${type.id}"></a>
                 <a class="typeBtn" href="/document/beauty-archive.html" target="_blank">美业资料</a>
+                <a class="typeBtn" href="/encyclopedia/product.html" target="_blank">采美百科</a>
             </div>
         </div>
         <!--搜索-->

+ 35 - 0
src/main/resources/templates/encyclopedia/about.html

@@ -0,0 +1,35 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>采美百科-联系我们</title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/contact.css(v=${version})}"/>
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<!-- 页面标题 -->
+<div class="page-title">
+    <div class="container">
+        <div class="title">
+            <h2>关于我们</h2>
+            <div class="line"></div>
+        </div>
+        <p class="subtitle"><span></span>about us</p>
+    </div>
+</div>
+<div class="contact container">
+    <div class="content">
+
+    </div>
+</div>
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+</body>
+</html>

+ 16 - 0
src/main/resources/templates/encyclopedia/components/footer.html

@@ -0,0 +1,16 @@
+<!-- 底部 -->
+<footer class="copyright" >
+    <div class="container">
+        <p>
+            <img class="icp" src="/img/encyclopedia/icon-icp@2x.png" width="18" height="18" alt="粤B1-20160129"/>
+            <span>粤B1-20160129</span><span>备案号</span>
+            <a href="https://beian.miit.gov.cn">粤ICP备14019824号</a>
+            <span class="br">互联网药品信息服务资格证编号(粤)-非经营性-2021-0339</span>
+            <span class="br">中华人民共和国增值电信业务经营许可证</span>
+        </p>
+        <p>Copyright © 2015-2020 CAIMEI365.com All Rights Reserved 深圳市采美网络信息有限公司</p>
+    </div>
+</footer>
+<!-- 底部公共js -->
+<script src="/lib/jquery-3.6.0.min.js"></script>
+<script th:src="@{/js/encyclopedia/common.js(v=${version})}" xmlns:th="https://www.thymeleaf.org"></script>

+ 44 - 0
src/main/resources/templates/encyclopedia/components/header.html

@@ -0,0 +1,44 @@
+<!-- 头部导航 -->
+<header class="navbar" xmlns:th="https://www.thymeleaf.org">
+    <input type="hidden" th:value="${coreServer}" id="coreServer">
+    <input type="hidden" th:value="${agent}" id="userAgent">
+    <div class="container">
+        <div class="logo">
+            <div class="menu-btn" id="menuBtn" data-target="#menuNav" data-colse="#menuColseBtn">
+                <i class="icon menu"></i>
+            </div>
+            <a href="/">
+                <h1>采美百科丰富的百科文库</h1>
+                <img src="/img/encyclopedia/logo.png" alt="采美百科"/>
+            </a>
+        </div>
+        <ul class="nav" id="menuNav">
+            <li class="active"><a href="product.html">产品百科</a></li>
+            <li><a href="instrument.html">仪器百科</a></li>
+<!--            <li><a href="about.html">关于采美百科</a></li>-->
+            <li><a href="contact.html">联系我们</a></li>
+            <li><span class="nav-close" id="#menuColseBtn"></span></li>
+        </ul>
+        <div class="search">
+            <div class="search-control">
+                <form action="search.html">
+                    <input type="text" id="searchKeyword" class="search-input" name="keyword" placeholder="请输入产品/仪器名称"/>
+                    <button class="search-btn">搜索</button>
+                </form>
+                <button class="hot-keyword" id="hotKeyword" data-target="#hotKeywords">热搜词</button>
+            </div>
+            <div class="keywords" id="hotKeywords">
+                <span class="close-btn icon close"></span>
+                <span>热门搜索:</span>
+                <!--跳转方式:1仅搜索,2产品,3仪器,4链接-->
+                <th:block th:each="item,stat: ${searchHotWord}" th:object="${item}">
+                    <a th:href="*{'search.html?keyword=' + keyWord}" th:if="*{jumpType eq 1}" th:text="*{keyWord}" th:title="*{keyWord}"></a>
+                    <a th:href="*{'product-' + productId + '.html'}" th:if="*{jumpType eq 2}" th:text="*{keyWord}" th:title="*{keyWord}"></a>
+                    <a th:href="*{'instrument-' + productId + '.html'}" th:if="*{jumpType eq 3}" th:text="*{keyWord}" th:title="*{keyWord}"></a>
+                    <a th:href="*{jumpLink}" th:if="*{jumpType eq 4}" th:text="*{keyWord}" th:title="*{keyWord}"></a>
+                    <em th:if="${stat.size gt 1 and stat.size ne stat.index + 1}">/</em>
+                </th:block>
+            </div>
+        </div>
+    </div>
+</header>

+ 59 - 0
src/main/resources/templates/encyclopedia/contact.html

@@ -0,0 +1,59 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>采美百科-联系我们</title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/contact.css(v=${version})}"/>
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<!-- 页面标题 -->
+<div class="page-title">
+    <div class="container">
+        <div class="title">
+            <h2>联系我们</h2>
+            <div class="line"></div>
+        </div>
+        <p class="subtitle"><span></span>contact us</p>
+    </div>
+</div>
+<div class="contact container">
+    <div class="content">
+        <h2>深圳市采美网络信息有限公司</h2>
+        <p>
+            采美365网,是一家集美业仪器、产品采购交易和信息咨询为一体的一站式B2B服务平台,另设有针对C端的线上商城。
+            平台集合了各类美业资源及多方优质供应商,不仅能满足生活美容院、高级医美会所、医疗美容机构对产品、光电仪器、易耗品的采购需求,还能提供专业的产品信息咨询服务,包括仪器对比、配套信息,仪器查找、项目合作洽谈,
+            专业高端药妆产品采购,高端SPA产品采购,正品仪器采购,涵盖生美、医美等专业线产品。
+        </p>
+        <div class="address">
+            <div class="col">
+                <div class="dt">工作时间</div>
+                <div class="dd">周一至周五 9:00-18:00</div>
+            </div>
+            <span class="line"></span>
+            <div class="col">
+                <div class="dt">联系电话</div>
+                <div class="dd">0755-22907771</div>
+            </div>
+            <span class="line"></span>
+            <div class="col">
+                <div class="dt">公司地址</div>
+                <div class="dd">深圳市福田区上步南路1001号锦峰大厦A座21B</div>
+            </div>
+        </div>
+        <div class="map">
+            <iframe src="/encyclopedia/map.html" frameborder="0" width="100%" height="100%"></iframe>
+        </div>
+    </div>
+</div>
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+</body>
+</html>

+ 222 - 0
src/main/resources/templates/encyclopedia/instrument-detail.html

@@ -0,0 +1,222 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <meta name="keyword" th:content="${baikeInstrument.seoKeyword}" />
+    <meta name="description" th:content="${baikeInstrument.discription}" />
+    <title th:text="${baikeInstrument.name + '详情-采美百科-美业百科全书'}"></title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/detail.css(v=${version})}"/>
+    <link rel="stylesheet" type="text/css" href="/lib/css/viewer.min.css">
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+
+<article class="article" th:object="${baikeInstrument}">
+    <!-- 仪器简述 -->
+    <section class="section description">
+        <div class="title">
+            <h2>仪器简述</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="content-left">
+                <div class="names">
+                    <div class="name"><b>仪器名称:</b><span th:text="*{name}"></span></div>
+                    <div class="alias">别名:<span th:text="*{alias}"></span></div>
+                </div>
+                <!-- 描述 -->
+                <div class="row desc" th:text="*{discription}"></div>
+            </div>
+            <div class="cover">
+                <img th:src="*{image}" th:alt="*{name}"/>
+            </div>
+        </div>
+    </section>
+    <!-- 正品识别 -->
+    <section class="section approve">
+        <div class="title">
+            <h2>正品识别</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <p>认证连接:<a th:href="*{authLink}" th:text="*{authLink}"></a></p>
+            <p>认证二维码</p>
+            <div class="img-list">
+                <img th:src="*{authQrCode}" alt="认证二维码"/>
+            </div>
+        </div>
+    </section>
+    <!-- 仪器参数 -->
+    <section class="section params">
+        <div class="title">
+            <h2>仪器参数</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="tr">
+                <div class="group" th:each="params: *{paramList}">
+                    <div class="th" th:text="${params.name}"></div>
+                    <div class="td" th:text="${params.content}"></div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- 仪器优点 -->
+    <section class="section">
+        <div class="title">
+            <h2>仪器优点</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{advantage}"></div>
+    </section>
+    <!-- 仪器缺点 -->
+    <section class="section">
+        <div class="title">
+            <h2>仪器缺点</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{disadvantage}"></div>
+    </section>
+    <!-- 仪器原理 -->
+    <section class="section">
+        <div class="title">
+            <h2>仪器原理</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{principle}"></div>
+    </section>
+    <!-- 仪器档案 -->
+    <section class="section params">
+        <div class="title">
+            <h2>仪器档案</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="tr">
+                <div class="group">
+                    <div class="th">品牌</div>
+                    <div class="td" th:text="*{brand}"></div>
+                </div>
+                <div class="group">
+                    <div class="th">产地</div>
+                    <div class="td" th:text="*{producePlace}"></div>
+                </div>
+            </div>
+            <div class="tr">
+                <div class="group">
+                    <div class="th">上市时间</div>
+                    <div class="td" th:text="*{#dates.format(marketTime,'yyyy年MM月dd日')}"></div>
+                </div>
+                <div class="group">
+                    <div class="th">公司/厂商</div>
+                    <div class="td" th:text="*{company}"></div>
+                </div>
+            </div>
+            <div class="tr">
+                <div class="group">
+                    <div class="th">NMPA认证时间</div>
+                    <div class="td" th:text="*{#dates.format(nmpaTime,'yyyy年MM月dd日')}"></div>
+                </div>
+                <div class="group">
+                    <div class="th">价格区间</div>
+                    <div class="td"><a href="javascript:void(0);" id="contactPopupBtn">点击查询</a></div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- 仪器认证 -->
+    <section class="section approve">
+        <div class="title">
+            <h2>仪器认证</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="name">该仪器已获得以下认证:</div>
+            <div class="img-list">
+                <img th:src="${img}" th:each="img: *{authImageList}"/>
+            </div>
+        </div>
+    </section>
+    <!-- 适应人群 -->
+    <section class="section">
+        <div class="title">
+            <h2>适应人群</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{adaptiveMan}"></div>
+    </section>
+    <!-- 不适应人群 -->
+    <section class="section">
+        <div class="title">
+            <h2>不适应人群</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{unAdaptiveMan}"></div>
+    </section>
+    <!-- 术前术后 -->
+    <section class="section">
+        <div class="title">
+            <h2>术前术后</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{aroundOperation}"></div>
+    </section>
+    <!-- 效果展示 -->
+    <section class="section effect">
+        <div class="title">
+            <h2>效果展示</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <img th:src="${img}" th:each="img: *{displayImageList}"/>
+        </div>
+    </section>
+    <!-- 常见问题 -->
+    <section class="section question">
+        <div class="title">
+            <h2>常见问题</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <dl class="collapse" th:each="question,questionStat: *{questionList}">
+                <dt>
+                    <span>问</span><block th:text="${question.question}"></block>
+                    <i class="icon arrowdown" data-toggle="collapse" th:data-target="'#question' + ${questionStat.index}"></i>
+                </dt>
+                <dd th:id="'question' + ${questionStat.index}">
+                    <span>答</span>
+                    <block th:text="${question.answer}">
+                        几乎没有什么副作用,非常安全,这是光子嫩肤治疗的一个非常大的优点。但是和任何治疗都一样,治疗本身是具有两面性的,光子一方面是治疗色素性皮肤疾病非常好的
+                    治疗方法...
+                    </block>
+                </dd>
+            </dl>
+        </div>
+    </section>
+</article>
+<!-- 侧边楼层导航 -->
+<aside class="navigate" id="category"></aside>
+<!-- 立即咨询弹窗 -->
+<div class="contact-popup" id="contactPopup">
+    <span class="close" id="contactPopupClose">&times;</span>
+    <div class="content">
+        <p class="tel">0755-22907771</p>
+        <p class="tel">15398851365</p>
+        <p>工作日</p>
+        <p class="time">周一~周五 / 09:00 ~ 18:00</p>
+    </div>
+</div>
+
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+<script charset="utf-8" type="text/javascript" src="/lib/viewer.min.js"></script>
+<script th:src="@{/js/encyclopedia/detail.js(v=${version})}"></script>
+</body>
+</html>

+ 93 - 0
src/main/resources/templates/encyclopedia/instrument.html

@@ -0,0 +1,93 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>采美百科-产品百科</title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/index.css(v=${version})}"/>
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<!-- banner -->
+<div class="banner">
+    <a th:href="${banner.link}"><img th:src="${banner.image}" th:alt="${banner.link}"/></a>
+</div>
+<!-- 产品 / 仪器分类 -->
+<div class="category container" id="category">
+    <div class="name"><b>产品分类</b><em></em></div>
+    <div class="category-list" id="category-list"></div>
+    <div
+            class="collapse on"
+            id="hello"
+            data-collapse-toggle="category"
+            data-collapse-parent-target="#category"
+            data-collapse-children-target="#category-list"
+    >
+        <span>展开</span>
+        <i class="icon arrowdown"></i>
+    </div>
+</div>
+<!-- 分类楼层 -->
+<div class="floor-list">
+    <div class="floor" th:each="floor,floorStat : ${typeData}" th:if="${floor.productList.size} > 0">
+        <div class="floor-title">
+            <h2 th:text="${floor.name}" th:class="'color' + ${floor.typeId % 10}"></h2>
+            <div class="h5-more-btn">
+                <a th:href="'more-' + ${floor.typeId} + '-1-12.html'">
+                    <span>更多</span>
+                    <i class="icon arrowright"></i>
+                </a>
+            </div>
+            <img th:src="'/img/encyclopedia/title-bg-' + ${floor.typeId % 10} + '.png'" th:alt="${floor.name}"/>
+        </div>
+        <article class="article container">
+            <section class="section" th:each="item,stat : ${floor.productList}" th:object="${item}">
+                <a th:href="'instrument-' + *{productId} + '.html'">
+                    <div class="cover">
+                        <img th:src="*{image}" th:alt="*{name}"/>
+                    </div>
+                    <div class="content">
+                        <h3 th:text="*{name}"></h3>
+                        <div class="title" th:text="*{discription}"></div>
+                        <div class="question">
+                            <p th:each="question : *{questionList}" th:text="${question}"></p>
+                        </div>
+                        <div class="tag-list">
+                            <span class="tag">常见问题</span>
+                            <span class="tag">效果展示</span>
+                            <span class="tag">技术原理</span>
+                            <span class="tag">术前术后</span>
+                        </div>
+                        <div class="dashed-line"></div>
+                        <footer class="footer">
+                            <time>日期:<span th:text="*{publishTime}"></span></time>
+                            <span>浏览量:<span th:text="*{pv lt 10000 ? pv : '9999+'}"></span></span>
+                        </footer>
+                    </div>
+                </a>
+            </section>
+        </article>
+        <!-- 更多 -->
+        <div class="more">
+            <a th:href="'more-' + ${floor.typeId} + '-1-12.html'">
+                <div class="more-btn">
+                    <span class="">查看更多</span>
+                    <i class="icon arrowdown"></i>
+                </div>
+            </a>
+        </div>
+    </div>
+</div>
+<!-- 侧边楼层导航 -->
+<aside class="navigate"></aside>
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+<script th:src="@{/js/encyclopedia/index.js(v=${version})}"></script>
+</body>
+</html>

+ 125 - 0
src/main/resources/templates/encyclopedia/map.html

@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <meta name="keywords" content="高德地图,DIY地图,高德地图生成器"/>
+    <meta name="description" content="高德地图,DIY地图,自己制作地图,生成自己的高德地图"/>
+    <title>高德地图 - DIY我的地图</title>
+    <link rel="stylesheet" href="/css/encyclopedia/map.css"/>
+</head>
+<body>
+<div id="wrap" class="my-map">
+    <div id="mapContainer"></div>
+</div>
+<script src="//webapi.amap.com/maps?v=1.3&key=09b9feeff00d27c751c2edc1aca556d8"></script>
+<script>
+    !(function () {
+        var infoWindow,
+            map,
+            level = 17,
+            center = {lng: 114.096029, lat: 22.535957},
+            features = [
+                {
+                    icon: 'twig',
+                    color: 'red',
+                    name: '锦峰大厦A座21B',
+                    desc: '深圳市采美网络信息有限公司',
+                    lnglat: {Q: 22.53608091509164, R: 114.09600510165099, lng: 114.096005, lat: 22.536081},
+                    offset: {x: -18, y: -25},
+                    type: 'Marker',
+                },
+            ]
+
+        function loadFeatures() {
+            for (var feature, data, i = 0, len = features.length, j, jl, path; i < len; i++) {
+                data = features[i]
+                switch (data.type) {
+                    case 'Marker':
+                        feature = new AMap.Marker({
+                            map: map,
+                            position: new AMap.LngLat(data.lnglat.lng, data.lnglat.lat),
+                            zIndex: 3,
+                            extData: data,
+                            offset: new AMap.Pixel(data.offset.x, data.offset.y),
+                            title: data.name,
+                            content: '<div class="icon icon-' + data.icon + ' icon-' + data.icon + '-' + data.color + '"></div>',
+                        })
+                        break
+                    case 'Polyline':
+                        for (j = 0, jl = data.path.length, path = []; j < jl; j++) {
+                            path.push(new AMap.LngLat(data.path[j].lng, data.path[j].lat))
+                        }
+                        feature = new AMap.Polyline({
+                            map: map,
+                            path: path,
+                            extData: data,
+                            zIndex: 2,
+                            strokeWeight: data.strokeWeight,
+                            strokeColor: data.strokeColor,
+                            strokeOpacity: data.strokeOpacity,
+                        })
+                        break
+                    case 'Polygon':
+                        for (j = 0, jl = data.path.length, path = []; j < jl; j++) {
+                            path.push(new AMap.LngLat(data.path[j].lng, data.path[j].lat))
+                        }
+                        feature = new AMap.Polygon({
+                            map: map,
+                            path: path,
+                            extData: data,
+                            zIndex: 1,
+                            strokeWeight: data.strokeWeight,
+                            strokeColor: data.strokeColor,
+                            strokeOpacity: data.strokeOpacity,
+                            fillColor: data.fillColor,
+                            fillOpacity: data.fillOpacity,
+                        })
+                        break
+                    default:
+                        feature = null
+                }
+                if (feature) {
+                    AMap.event.addListener(feature, 'click', mapFeatureClick)
+                    createInfoWindow(data)
+                }
+            }
+        }
+
+        function createInfoWindow(data) {
+            infoWindow = new AMap.InfoWindow({autoMove: true, isCustom: false})
+            infoWindow.setContent(
+                "<div class='myinfowindow'><h5>" + data.name + '</h5><div>' + data.desc + '</div></div>'
+            )
+            infoWindow.open(map, {M: 114.09606937301635, O: 22.536328738891648, lat: 22.536329, lng: 114.096069})
+        }
+
+        function mapFeatureClick(e) {
+            var extData = e.target.getExtData()
+            infoWindow.setContent(
+                "<div class='myinfowindow'><h5>" + extData.name + '</h5><div>' + extData.desc + '</div></div>'
+            )
+            console.log(e.lnglat)
+            infoWindow.open(map, e.lnglat)
+        }
+
+        map = new AMap.Map('mapContainer', {
+            center: new AMap.LngLat(center.lng, center.lat),
+            level: level,
+            keyboardEnable: true,
+            dragEnable: true,
+            scrollWheel: true,
+            doubleClickZoom: true,
+        })
+        loadFeatures()
+
+        map.on('complete', function () {
+            map.plugin(['AMap.ToolBar', 'AMap.OverView', 'AMap.Scale'], function () {
+                map.addControl(new AMap.ToolBar({ruler: true, direction: true, locate: false}))
+                map.addControl(new AMap.OverView({isOpen: true}))
+                map.addControl(new AMap.Scale())
+            })
+        })
+    })()
+</script>
+</body>
+</html>

+ 93 - 0
src/main/resources/templates/encyclopedia/more.html

@@ -0,0 +1,93 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>采美百科搜索页面</title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/pagination.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/index.css(v=${version})}"/>
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<!-- 分类楼层 -->
+<div class="floor container more-floor" id="moreFloor" th:object="${moreData}">
+    <div class="floor-title" th:id="${moreData}">
+        <h2 th:text="*{typeName}" th:class="'color' + *{typeId % 10}"></h2>
+        <img th:src="'/img/encyclopedia/title-bg-' + *{typeId % 10} + '.png'" alt="中胚层产品"/>
+    </div>
+    <article class="article">
+        <section class="section" th:each="item: *{results}">
+            <!-- commodityType : 1 产品  2 仪器 -->
+            <a th:href="${item.commodityType eq 1 ? 'product-' + item.productId + '.html' : 'instrument-' + item.productId + '.html'}">
+                <div class="cover">
+                    <img th:src="${item.image}" th:alt="${item.name}"/>
+                </div>
+                <div class="content">
+                    <h3 th:text="${item.name}"></h3>
+                    <div class="title" th:text="${item.discription}"></div>
+                    <div class="question">
+                        <p th:each="question : ${item.questionList}" th:text="${question}"></p>
+                    </div>
+                    <div class="tag-list">
+                        <span class="tag">常见问题</span>
+                        <span class="tag">效果展示</span>
+                        <span class="tag">技术原理</span>
+                        <span class="tag">术前术后</span>
+                    </div>
+                    <div class="dashed-line"></div>
+                    <footer class="footer">
+                        <time>日期:<span th:text="${item.publishTime}"></span></time>
+                        <span>浏览量:<span th:text="${item.pv lt 10000 ? item.pv : '9999+'}"></span></span>
+                    </footer>
+                </div>
+            </a>
+        </section>
+    </article>
+</div>
+
+<!--页码-->
+<div class="pagination-container" id="pagination" th:if="${moreData.totalPage > 1}">
+    <ul class="pagination" v-if="totalPage > 1">
+        <!--左侧固定-->
+        <li v-if="pageNum > 1"><a :href="makeUrl(pageNum - 1)" @click.prevent="pageChange(pageNum - 1)">«</a></li>
+        <li v-if="pagination[0] > 1"><a :href="makeUrl(1)" @click.prevent="pageChange(1)">1</a></li>
+        <li class="ellipsis" v-if="pagination[0] > 2"><span>···</span></li>
+        <!--可变动-->
+        <template v-for="num in pagination">
+            <li :class="{ active: pageNum === num }" v-if="num >= 1  && num <= totalPage">
+                <a :href="makeUrl(num)" @click.prevent="pageChange(num)" v-text="num"></a>
+            </li>
+        </template>
+        <!--右侧固定-->
+        <li class="ellipsis" v-if="pagination[pagination.length - 1] < totalPage - 1"><span>···</span></li>
+        <li v-if="pagination[pagination.length - 1] < totalPage">
+            <a :href="makeUrl(totalPage)" @click.prevent="pageChange(totalPage)" v-text="totalPage"></a>
+        </li>
+        <li v-if="pageNum < totalPage" :class="{ active: pageNum === totalPage }">
+            <a :href="makeUrl(pageNum + 1)" @click.prevent="pageChange(pageNum + 1)">»</a>
+        </li>
+    </ul>
+    <div class="tool">
+        <div class="total">共<span v-text="totalPage"></span>页</div>
+        <div class="jump">
+            <div class="pagenum-input">跳至<input type="text" v-model="jumpInput"/>页</div>
+            <a :href="makeUrl(jumpInput)" class="jump-btn" @click.prevent="pageChange(jumpInput)">点击跳转</a>
+        </div>
+    </div>
+</div>
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+<script src="/lib/vue2.6.12.min.js"></script>
+<script th:inline="javascript">
+// 从 Thymeleaf 域中获取数据使用[[${prototype}]]
+function getMoreData() { return [[${moreData}]]}
+</script>
+<script th:src="@{/js/encyclopedia/moreFloor.js(v=${version})}"></script>
+</body>
+</html>

+ 203 - 0
src/main/resources/templates/encyclopedia/product-detail.html

@@ -0,0 +1,203 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <meta name="keyword" th:content="${baikeProduct.seoKeyword}" />
+    <meta name="description" th:content="${baikeProduct.discription}" />
+    <title th:text="${baikeProduct.name + '详情-采美百科-美业百科全书'}"></title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/detail.css(v=${version})}"/>
+    <link rel="stylesheet" type="text/css" href="/lib/css/viewer.min.css">
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<article class="article" th:object="${baikeProduct}">
+    <!-- 产品简述 -->
+    <section class="section description">
+        <div class="title">
+            <h2>产品简述</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="content-left">
+                <div class="names">
+                    <div class="name"><b>产品名称:</b><span th:text="*{name}"></span></div>
+                    <div class="alias">别名:<span th:text="*{alias}"></span></div>
+                </div>
+                <!-- 描述 -->
+                <div class="row desc" th:text="*{discription}"></div>
+            </div>
+            <div class="cover">
+                <img th:src="*{image}" th:alt="*{name}"/>
+            </div>
+        </div>
+    </section>
+    <!-- 产品参数 -->
+    <section class="section params">
+        <div class="title">
+            <h2>产品参数</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="tr">
+                <div class="group" th:each="params: *{paramList}">
+                    <div class="th" th:text="${params.name}"></div>
+                    <div class="td" th:text="${params.content}"></div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- 产品优点 -->
+    <section class="section">
+        <div class="title">
+            <h2>产品优点</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{advantage}"></div>
+    </section>
+    <!-- 产品缺点 -->
+    <section class="section">
+        <div class="title">
+            <h2>产品缺点</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{disadvantage}"></div>
+    </section>
+    <!-- 产品原理 -->
+    <section class="section">
+        <div class="title">
+            <h2>产品原理</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{principle}"></div>
+    </section>
+    <!-- 产品档案 -->
+    <section class="section params">
+        <div class="title">
+            <h2>产品档案</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="tr">
+                <div class="group">
+                    <div class="th">品牌</div>
+                    <div class="td" th:text="*{brand}"></div>
+                </div>
+                <div class="group">
+                    <div class="th">产地</div>
+                    <div class="td" th:text="*{producePlace}"></div>
+                </div>
+            </div>
+            <div class="tr">
+                <div class="group">
+                    <div class="th">上市时间</div>
+                    <div class="td" th:text="*{#dates.format(marketTime,'yyyy年MM月dd日')}"></div>
+                </div>
+                <div class="group">
+                    <div class="th">公司/厂商</div>
+                    <div class="td" th:text="*{company}"></div>
+                </div>
+            </div>
+            <div class="tr">
+                <div class="group">
+                    <div class="th">NMPA认证时间</div>
+                    <div class="td" th:text="*{#dates.format(nmpaTime,'yyyy年MM月dd日')}"></div>
+                </div>
+                <div class="group">
+                    <div class="th">价格区间</div>
+                    <div class="td"><a href="javascript:void(0);" id="contactPopupBtn">点击查询</a></div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- 产品认证 -->
+    <section class="section approve">
+        <div class="title">
+            <h2>产品认证</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <div class="name">该产品已获得以下认证:</div>
+            <div class="img-list">
+                <img th:src="${img}" th:each="img: *{authImageList}"/>
+            </div>
+        </div>
+    </section>
+    <!-- 适应人群 -->
+    <section class="section">
+        <div class="title">
+            <h2>适应人群</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{adaptiveMan}"></div>
+    </section>
+    <!-- 不适应人群 -->
+    <section class="section">
+        <div class="title">
+            <h2>不适应人群</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{unAdaptiveMan}"></div>
+    </section>
+    <!-- 术前术后 -->
+    <section class="section">
+        <div class="title">
+            <h2>术前术后</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content" th:utext="*{aroundOperation}"></div>
+    </section>
+    <!-- 效果展示 -->
+    <section class="section effect">
+        <div class="title">
+            <h2>效果展示</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <img th:src="${img}" th:each="img: *{displayImageList}"/>
+        </div>
+    </section>
+    <!-- 常见问题 -->
+    <section class="section question">
+        <div class="title">
+            <h2>常见问题</h2>
+            <div class="line"></div>
+        </div>
+        <div class="content">
+            <dl class="collapse" th:each="question,questionStat: *{questionList}">
+                <dt>
+                    <span>问</span><th:block th:text="${question.question}"></th:block>
+                    <i class="icon arrowdown" data-toggle="collapse" th:data-target="'#question' + ${questionStat.index}"></i>
+                </dt>
+                <dd th:id="'question' + ${questionStat.index}">
+                    <span>答</span>
+                    <th:block th:text="${question.answer}"></th:block>
+                </dd>
+            </dl>
+        </div>
+    </section>
+</article>
+<!-- 侧边楼层导航 -->
+<aside class="navigate" id="category"></aside>
+<!-- 立即咨询弹窗 -->
+<div class="contact-popup" id="contactPopup">
+    <span class="close" id="contactPopupClose">&times;</span>
+    <div class="content">
+        <p class="tel">0755-22907771</p>
+        <p class="tel">15398851365</p>
+        <p>工作日</p>
+        <p class="time">周一~周五 / 09:00 ~ 18:00</p>
+    </div>
+</div>
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+<script charset="utf-8" type="text/javascript" src="/lib/viewer.min.js"></script>
+<script th:src="@{/js/encyclopedia/detail.js(v=${version})}"></script>
+</body>
+</html>

+ 93 - 0
src/main/resources/templates/encyclopedia/product.html

@@ -0,0 +1,93 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>采美百科-产品百科</title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/index.css(v=${version})}"/>
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<!-- banner -->
+<div class="banner">
+    <a th:href="${banner.link}"><img th:src="${banner.image}" th:alt="${banner.link}"/></a>
+</div>
+<!-- 产品 / 仪器分类 -->
+<div class="category container" id="category">
+    <div class="name"><b>产品分类</b><em></em></div>
+    <div class="category-list" id="category-list"></div>
+    <div
+            class="collapse on"
+            id="hello"
+            data-collapse-toggle="category"
+            data-collapse-parent-target="#category"
+            data-collapse-children-target="#category-list"
+    >
+        <span>展开</span>
+        <i class="icon arrowdown"></i>
+    </div>
+</div>
+<!-- 分类楼层 -->
+<div class="floor-list">
+    <div class="floor" th:each="floor,floorStat : ${typeData}" th:if="${floor.productList.size} > 0">
+        <div class="floor-title">
+            <h2 th:text="${floor?.name}" th:class="'color' + ${floor.typeId % 10}"></h2>
+            <div class="h5-more-btn">
+                <a th:href="'more-' + ${floor.typeId} + '-1-12.html'">
+                    <span>更多</span>
+                    <i class="icon arrowright"></i>
+                </a>
+            </div>
+            <img th:src="'/img/encyclopedia/title-bg-' + ${floor.typeId % 10} + '.png'" th:alt="${floor.name}"/>
+        </div>
+        <article class="article container">
+            <section class="section" th:each="item,stat : ${floor.productList}" th:object="${item}">
+                <a th:href="'product-' + *{productId} + '.html'">
+                    <div class="cover">
+                        <img th:src="*{image}" th:alt="*{name}"/>
+                    </div>
+                    <div class="content">
+                        <h3 th:text="*{name}"></h3>
+                        <div class="title" th:text="*{discription}"></div>
+                        <div class="question">
+                            <p th:each="question : *{questionList}" th:text="${question}"></p>
+                        </div>
+                        <div class="tag-list">
+                            <span class="tag">常见问题</span>
+                            <span class="tag">效果展示</span>
+                            <span class="tag">技术原理</span>
+                            <span class="tag">术前术后</span>
+                        </div>
+                        <div class="dashed-line"></div>
+                        <footer class="footer">
+                            <time>日期:<span th:text="*{publishTime}"></span></time>
+                            <span>浏览量:<span th:text="*{pv lt 10000 ? pv : '9999+'}"></span></span>
+                        </footer>
+                    </div>
+                </a>
+            </section>
+        </article>
+        <!-- 查看更多 -->
+        <div class="more">
+            <a th:href="'more-' + ${floor.typeId} + '-1-12.html'">
+                <div class="more-btn">
+                    <span class="">查看更多</span>
+                    <i class="icon arrowdown"></i>
+                </div>
+            </a>
+        </div>
+    </div>
+</div>
+<!-- 侧边楼层导航 -->
+<aside class="navigate"></aside>
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+<script th:src="@{/js/encyclopedia/index.js(v=${version})}"></script>
+</body>
+</html>

+ 92 - 0
src/main/resources/templates/encyclopedia/search.html

@@ -0,0 +1,92 @@
+<!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>
+    <meta charset="UTF-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>采美百科搜索页面</title>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/normalize.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/base.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/common.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/pagination.css(v=${version})}"/>
+    <link rel="stylesheet" th:href="@{/css/encyclopedia/index.css(v=${version})}"/>
+</head>
+<body>
+<!-- 引用公共头部 -->
+<template th:replace="encyclopedia/components/header"></template>
+<!-- 分类楼层 -->
+<div class="floor container search-floor" id="search">
+    <p class="search-title">为您找到相关结果<span v-text="totalRecord"></span>条</p>
+    <div class="emtyp" v-if="totalRecord <= 0">
+        <img src="/img/encyclopedia/pc-icon-empty.png" alt="搜索结果为空"/>
+        <p>未找到相关结果!</p>
+    </div>
+    <article class="article" v-else>
+        <section class="section" v-for="(item, index) in searchList" :key="index">
+            <a :href="item | formatUrl">
+                <div class="cover">
+                    <img :src="item.image" :alt="item.name"/>
+                </div>
+                <div class="content">
+                    <h3 v-html="formatFromKeyword(item.name)"></h3>
+                    <div class="title" v-text="item.discription"></div>
+                    <div class="question">
+                        <p v-for="question in item.questionList" v-html="formatFromKeyword(question)"></p>
+                    </div>
+                    <div class="tag-list">
+                        <span class="tag">常见问题</span>
+                        <span class="tag">效果展示</span>
+                        <span class="tag">技术原理</span>
+                        <span class="tag">术前术后</span>
+                    </div>
+                    <div class="dashed-line"></div>
+                    <footer class="footer">
+                        <time>日期:<span v-text="item.publishTime"></span></time>
+                        <span>浏览量:<span v-text="item.pv"></span></span>
+                    </footer>
+                </div>
+            </a>
+        </section>
+    </article>
+
+    <!--页码-->
+    <div class="pagination-container" v-if="totalPage > 1">
+        <ul class="pagination">
+            <!--左侧固定-->
+            <li v-if="listQuery.pageNum > 1"><a href="#" @click.prevent="pageChange(listQuery.pageNum - 1)">«</a></li>
+            <li v-if="pagination[0] > 1"><a href="#" @click.prevent="pageChange(1)">1</a></li>
+            <li class="ellipsis" v-if="pagination[0] > 2"><span>···</span></li>
+            <!--可变动-->
+            <template v-for="num in pagination">
+                <li :class="{ active: listQuery.pageNum === num }" v-if="num >= 1  && num <= totalPage">
+                    <a href="#" @click.prevent="pageChange(num)" v-text="num"></a>
+                </li>
+            </template>
+            <!--右侧固定-->
+            <li class="ellipsis" v-if="pagination[pagination.length - 1] < totalPage - 1"><span>···</span></li>
+            <li v-if="pagination[pagination.length - 1] < totalPage">
+                <a href="#" @click.prevent="pageChange(totalPage)" v-text="totalPage"></a>
+            </li>
+            <li v-if="listQuery.pageNum < totalPage" :class="{ active: listQuery.pageNum === totalPage }">
+                <a href="#" @click.prevent="pageChange(listQuery.pageNum + 1)">»</a>
+            </li>
+        </ul>
+        <div class="tool">
+            <div class="total">共<span v-text="totalPage"></span>页</div>
+            <div class="jump">
+                <div class="pagenum-input">跳至<input type="text" v-model="jumpInput"/>页</div>
+                <a href="#" class="jump-btn" @click.prevent="pageChange(jumpInput)">点击跳转</a>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- 引用公共底部 -->
+<template th:replace="encyclopedia/components/footer"></template>
+<script src="/lib/vue2.6.12.min.js"></script>
+<script th:src="@{/js/common/ajax.service.js(v=${version})}"></script>
+<script th:src="@{/js/common/serviceapi/encyclopedia.service.js(v=${version})}"></script>
+<script th:src="@{/js/encyclopedia/search.js(v=${version})}"></script>
+</body>
+</html>

+ 18 - 0
src/main/resources/templates/index.html

@@ -98,6 +98,24 @@
                             </a>
                         </div>
                     </div>
+                    <div class="section_right_item" th:if="${sideJson.get('baikeList')}!=null and ${sideJson.get('baikeList').size}>0">
+                        <div class="right_item_title">
+                            <p>热门百科</p>
+                            <a href="/encyclopedia/product.html" target="_blank" onclick="_czc.push(['_trackEvent','商城首页','热门百科','点击','','Um_Event_HomeBaikeTemplateClick'])">
+                                <template v-if="isPC">更多&gt;</template><template v-else>&gt;</template>
+                            </a>
+                        </div>
+                        <div class="right_item_main" th:each="info,stat : ${sideJson.get('baikeList')}" th:object="${info}">
+                            <a th:if="${stat.index}==0" th:href="*{link}" th:title="*{name}" class="item_banner" target="_blank" onclick="_czc.push(['_trackEvent','商城首页','热门百科','点击','','Um_Event_HomeBaikeTemplateClick'])">
+                                <img src="/img/base/placeholder.png" th:attr="data-original=*{image}" th:alt="*{name}">
+                                <div class="name" th:text="*{name}"></div>
+                            </a>
+                            <a th:if="${stat.index}>0" th:href="*{link}" th:title="*{name}" class="item_text" target="_blank" onclick="_czc.push(['_trackEvent','商城首页','热门百科','点击','','Um_Event_HomeBaikeTemplateClick'])">
+                                <p class="item_text_name info" th:text="*{name}"></p>
+                                <!-- <p class="item_text_time" v-if="isPC" th:text="*{createDate}"></p> -->
+                            </a>
+                        </div>
+                    </div>
                 </div>
             </div>
             <div class="section_left ">

+ 175 - 0
src/main/resources/templates/supplier-center/article/article-edit.html

@@ -0,0 +1,175 @@
+<!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/article/article-edit.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="articleEdit" class="article-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="form">
+                        <!-- 标题 -->
+                        <div class="form-item" required prop="title">
+                            <label for="title" class="form-label"><em>*</em>标题:</label>
+                            <input id="title" name="title" class="form-control" placeholder="请输入文章标题"
+                                   v-model="formData.title"/>
+                            <template v-if="validData['title'] && !validData['title'].valid">
+                                <div class="errTips" v-html="validData['title'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 文章标签 -->
+                        <div class="form-item" required prop="label">
+                            <label for="tag" class="form-label"><em>*</em>文章标签:</label>
+                            <input id="tag" name="label" class="form-control" placeholder="多个标签请用英文逗号( , )分割,例如:美白,祛痘"
+                                   v-model="formData.label"/>
+                            <template v-if="validData['label'] && !validData['label'].valid">
+                                <div class="errTips" v-html="validData['label'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 预选标签列表 -->
+                        <div class="tag-list">
+                            <div v-for="(label, index) in articleLabels" class="tag"
+                                 :class="{active: checkLabel(index)}" @click.stop="labelClick(index)">{{label}}<span
+                                    class="close">×</span></div>
+                        </div>
+                        <!-- 新增标签 -->
+                        <div class="control-group">
+                            <input id="tagName" name="addLabel" class="form-control tagName" placeholder="请输入标签名"
+                                   v-model="addLabelName"/>
+                            <button class="form-button addTag" type="button" @click.stop="addLabel">添加</button>
+                        </div>
+                        <!-- SEO关键词 -->
+                        <div class="form-item" required prop="keyword">
+                            <label for="keyword" class="form-label"><em>*</em>SEO关键词:</label>
+                            <input id="keyword" type="text" name="keyword" class="form-control" placeholder="请输入SEO关键词"
+                                   v-model="formData.keyword"/>
+                            <template v-if="validData['keyword'] && !validData['keyword'].valid">
+                                <div class="errTips" v-html="validData['keyword'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 发布人 -->
+                        <div class="form-item" required prop="publisher">
+                            <label for="postAuthor" class="form-label"><em>*</em>发布人:</label>
+                            <input id="postAuthor" name="publisher" class="form-control" placeholder="请输入发布人"
+                                   v-model="formData.publisher"/>
+                            <template v-if="validData['publisher'] && !validData['publisher'].valid">
+                                <div class="errTips" v-html="validData['publisher'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 来源 -->
+                        <div class="form-item">
+                            <label for="source" class="form-label"><em>*</em>来源:</label>
+                            <input id="source" name="source" class="form-control" placeholder="请输入文章来源"
+                                   v-model="formData.source"/>
+                            <template v-if="validData['source'] && !validData['source'].valid">
+                                <div class="errTips" v-html="validData['source'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 推荐语 -->
+                        <div class="form-item" required prop="recommendContent">
+                            <label for="desc" class="form-label"><em>*</em>推荐语(描述):</label>
+                            <textarea id="desc" name="recommendContent" placeholder="请输入推荐语" rows="4"
+                                      v-model="formData.recommendContent" class="form-control"></textarea>
+                            <template v-if="validData['recommendContent'] && !validData['recommendContent'].valid">
+                                <div class="errTips" v-html="validData['recommendContent'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 文章内容 -->
+                        <div class="form-item" required prop="articleContent">
+                            <label class="form-label"><em>*</em>文章内容:</label>
+                            <div id="editor"></div>
+                            <template v-if="validData['articleContent'] && !validData['articleContent'].valid">
+                                <div class="errTips" v-html="validData['articleContent'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 文章分类 -->
+                        <div class="form-item" required prop="typeId">
+                            <label for="category" class="form-label"><em>*</em>文章分类:</label>
+                            <select id="category" name="typeId" class="form-control form-select"
+                                    v-model="formData.typeId">
+                                <option value="">请选择</option>
+                                <template v-for="(typeInfo, index) in articleTypeList">
+                                    <option :value="typeInfo.typeId" :key="index">{{typeInfo.typeName}}</option>
+                                </template>
+                            </select>
+                            <template v-if="validData['typeId'] && !validData['typeId'].valid">
+                                <div class="errTips" v-html="validData['typeId'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 引导图 -->
+                        <div class="form-item" required prop="guidanceImage">
+                            <label class="form-label"><em>*</em>引导图:</label>
+                            <label for="cover" class="upload-control">
+                                <template v-if="!formData.guidanceImage">
+                                    <span>+</span>
+                                    <span>添加图片</span>
+                                </template>
+                                <img :src="formData.guidanceImage" alt="guidanceImage" v-show="formData.guidanceImage">
+                            </label>
+                            <input type="file" name="guidanceImage" id="cover" class="form-control" hidden
+                                   @change="fileInputChange(event)"/>
+                            <template v-if="validData['guidanceImage'] && !validData['guidanceImage'].valid">
+                                <div class="errTips" v-html="validData['guidanceImage'].message"></div>
+                            </template>
+                        </div>
+                        <!-- 状态 -->
+                        <div class="form-item radio-group" required prop="status">
+                            <div class="form-label"><em>*</em>状态:</div>
+                            <div class="radio-control">
+                                <input id="on" type="radio" value="1" name="status" v-model="formData.status"/>
+                                <label for="on" class="radio">启用</label>
+                            </div>
+                            <div class="radio-control">
+                                <input id="off" type="radio" value="0" name="status" v-model="formData.status"/>
+                                <label for="off" class="radio">停用</label>
+                            </div>
+                        </div>
+                        <div class="form-item btns">
+                            <button class="btn break" @click="handleBack">返回</button>
+                            <button class="btn submit" @click="handleSave">保存</button>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<!-- 引入底部 -->
+<template th:replace="components/footer"></template>
+<template th:replace="components/foot-link"></template>
+<script charset="utf-8" type="text/javascript" th:src="@{/lib/wangEditor.min.js}"></script>
+<script charset="utf-8" type="text/javascript" th:src="@{/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/article/formMixin.js(v=${version})}"></script>
+<script charset="UTF-8" type="text/javascript"
+        th:src="@{/js/supplier-center/article/uploadMixin.js(v=${version})}"></script>
+<script charset="UTF-8" type="text/javascript"
+        th:src="@{/js/supplier-center/article/article-edit.js(v=${version})}"></script>
+</body>
+</html>

+ 160 - 0
src/main/resources/templates/supplier-center/article/article-list.html

@@ -0,0 +1,160 @@
+<!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/article/table.css(v=${version})}" rel="stylesheet" type="text/css">-->
+    <link th:href="@{/css/supplier-center/article/article-list.css(v=${version})}" rel="stylesheet" type="text/css">
+    <template th:replace="components/analysis"></template>
+</head>
+<body>
+<!-- 引用头部 -->
+<template th:replace="components/header"></template>
+
+<!-- 我的采美 -->
+<div id="articleList" class="article-list">
+    <div class="navLayout" v-cloak>
+        <div v-if="isPC" class="top-row">
+            <div class="crumbs">
+                <span>我的采美</span>
+                <span>&gt;</span>
+                <span>文章管理</span>
+                <span>&gt;</span>
+                <span>文章列表</span>
+            </div>
+            <div class="hot-tip">温馨提示:多发布文章,有利于曝光您的店铺商品,提高成交量(发布并且审核通过后,可在信息中心搜索您的文章)</div>
+        </div>
+        <div class="wrap clear">
+            <!--左侧导航-->
+            <template th:replace="supplier-center/components/tableft"></template>
+            <div class="right">
+                <!--筛选-->
+                <div class="row">
+                    <div class="form-section">
+                        <div class="form-item">
+                            <label for="articleId" class="form-label">文章ID:</label>
+                            <input id="articleId" class="form-control" v-model="listQuery.articleId" type="text" placeholder="请输入文章ID"/>
+                        </div>
+                        <div class="form-item">
+                            <label for="articleTitle" class="form-label">文章标题:</label>
+                            <input id="articleTitle" class="form-control" v-model="listQuery.title" type="text" placeholder="请输入文章标题"/>
+                        </div>
+                        <div class="form-item">
+                            <label for="articleAuthor" class="form-label">发布人:</label>
+                            <input id="articleAuthor" class="form-control" v-model="listQuery.publisher" type="text" placeholder="输入发布人"/>
+                        </div>
+                        <div class="form-item">
+                            <label for="articleCate" class="form-label">文章分类:</label>
+                            <select id="articleCate" class="form-control form-select" v-model="listQuery.typeId" @change="getArticleList">
+                                <option value="">请选择</option>
+                                <template v-for="(typeInfo, index) in articleTypeList">
+                                    <option :value="typeInfo.typeId" :key="index">{{typeInfo.typeName}}</option>
+                                </template>
+                            </select>
+                        </div>
+                        <div class="form-item">
+                            <label for="articleStatus" class="form-label">审核状态:</label>
+                            <select id="articleStatus" class="form-control form-select" v-model="listQuery.auditStatus"  @change="handleSearchList">
+                                <option value="">全部</option>
+                                <option value="1">待审核</option>
+                                <option value="2">审核通过</option>
+                                <option value="3">审核未通过</option>
+                            </select>
+                        </div>
+                        <div class="form-item buttons">
+                            <button class="form-button search" type="button" @click="handleSearchList">搜索</button>
+                            <button class="form-button add" type="button" @click="handleAddArticle">添加</button>
+                        </div>
+                    </div>
+                </div>
+                <!--列表表格-->
+                <div class="row">
+                    <table class="table">
+                        <tr>
+                            <th>ID</th>
+                            <th>文章分类</th>
+                            <th>引导图</th>
+                            <th>文章标题</th>
+                            <th>点赞数</th>
+                            <th>阅读量</th>
+                            <th>审核状态</th>
+                            <th>发布时间</th>
+                            <th>发布人</th>
+                            <th>添加时间</th>
+                            <th>状态</th>
+                            <th>操作</th>
+                        </tr>
+                        <template v-for="(articleInfo, index) in articleList"  >
+                            <tr :key="index" class="tr-row">
+                                <td v-text="articleInfo.articleId"></td>
+                                <td v-text="articleInfo.typeName"></td>
+                                <td>
+                                    <img class="cover" :src="articleInfo.guidanceImage" :alt="articleInfo.title"/></td>
+                                <td class="title">
+                                    <div class="title" v-text="articleInfo.title" :title="articleInfo.title"></div>
+                                </td>
+                                <td v-text="articleInfo.praiseNum"></td>
+                                <td v-text="articleInfo.pvNum"></td>
+                                <td>
+                                    <span class="state warning" v-if="articleInfo.auditStatus === 1">待审核</span>
+                                    <span class="state success" v-else-if="articleInfo.auditStatus === 2">审核通过</span>
+                                    <span class="state danger" v-else>审核失败</span>
+                                    <span class="reason" v-if="articleInfo.auditStatus === 3" :title="'审核失败:' + articleInfo.failReason">?</span>
+                                </td>
+                                <td class="time">
+                                    <div class="time">{{ articleInfo.publishDate | formatDate }}</div>
+                                </td>
+                                <td v-html="articleInfo.publisher"></td>
+                                <td class="time" v-if="articleInfo.createDate">
+                                    <div class="time">{{ articleInfo.createDate | formatDate}}</div>
+                                </td>
+                                <td>
+                                    <span class="state primary" v-if="articleInfo.status === 1">已启用</span>
+                                    <span class="state default" v-else>未启用</span>
+                                </td>
+                                <td class="option">
+                                    <div class="option">
+                                        <button class="form-button edit" @click="clickOption(articleInfo, 1)">编辑</button>
+                                        <button class="form-button stop" @click="clickOption(articleInfo, 2)">{{ articleInfo.status === 1 ? '停用':'启用' }}</button>
+                                        <button class="form-button search" @click="clickOption(articleInfo, 3)">查看</button>
+                                        <button class="form-button delete" @click="clickOption(articleInfo, 4)">删除</button>
+                                    </div>
+                                </td>
+                            </tr>
+                        </template>
+                    </table>
+                </div>
+                <!--页码-->
+                <div class="pageWrap clear" v-if="isPC && pageTotal>1">
+                    <a v-if="listQuery.pageNum>1" class="prev" @click="toPagination(listQuery.pageNum*1-1)"
+                       href="javascript:void(0);"></a>
+                    <template v-for="n in showPageBtn">
+                        <a v-if="n" :class="{'on':(n==listQuery.pageNum)}" @click="toPagination(n)"
+                           href="javascript:void(0);" v-text="n"></a>
+                        <span v-else>···</span>
+                    </template>
+                    <a v-if="listQuery.pageNum<pageTotal" class="next" @click="toPagination(listQuery.pageNum*1+1)"
+                       href="javascript:void(0);"></a>
+                    <span>共<b v-text="pageTotal>1?pageTotal:1"></b>页</span>
+                    <span>跳至</span>
+                    <input v-model="pageInput" @blur="checkNum()"/>
+                    <span>页</span>&nbsp;
+                    <a class="btn" href="javascript:void(0);" @click="toPagination(pageInput)">点击跳转</a>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<!-- 引入底部 -->
+<template th:replace="components/footer"></template>
+<template th:replace="components/foot-link"></template>
+<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/article/article-list.js(v=${version})}"></script>
+</body>
+</html>

+ 6 - 1
src/main/resources/templates/supplier-center/components/tableft.html

@@ -17,7 +17,12 @@
             <a href="/supplier/release.html">发布商品</a>
             <a href="/supplier/goods.html">我的商品</a>
             <a href="/supplier/brand.html">品牌管理</a>
-
+        </div>
+    </div>
+    <div class="navList">
+        <span class="tab">文章管理</span>
+        <div class="con" style="display:none">
+            <a href="/supplier/article/list.html">文章列表</a>
         </div>
     </div>
     <div class="navList">

部分文件因为文件数量过多而无法显示