Parcourir la source

添加 官网系统设置模块

huangguoce il y a 2 mois
Parent
commit
9b18b058f8

+ 38 - 0
src/main/java/com/jeeplus/modules/official/dao/OfficialCategoryDao.java

@@ -0,0 +1,38 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.official.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.official.entity.OfficialCategory;
+import com.jeeplus.modules.project.entity.Project;
+import com.jeeplus.modules.project.entity.ProjectEvaluationRecord;
+import com.jeeplus.modules.project.entity.Projectgeneral;
+import com.jeeplus.modules.project.entity.Workprojectgroup;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientLinkman;
+import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
+
+import java.util.List;
+
+/**
+ * 官网分类DAO接口
+ *
+ * @author fgy
+ * @version 2017-10-12
+ */
+@MyBatisDao
+public interface OfficialCategoryDao extends CrudDao<OfficialCategory> {
+
+    public List<OfficialCategory> findList();
+
+     void logicDelete(OfficialCategory officialCategory);
+
+    public Integer countByCategory(OfficialCategory officialCategory);
+
+    void updateDisplay(OfficialCategory officialCategory);
+
+    public List<OfficialCategory> findAllChildren(OfficialCategory officialCategory);
+
+    public OfficialCategory findMaxSort(OfficialCategory officialCategory);
+}

+ 38 - 0
src/main/java/com/jeeplus/modules/official/dao/OfficialInfoDao.java

@@ -0,0 +1,38 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.official.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.official.entity.OfficialCategory;
+import com.jeeplus.modules.official.entity.OfficialInfo;
+
+import java.util.List;
+
+/**
+ * 分类详情DAO接口
+ *
+ * @author fgy
+ * @version 2017-10-12
+ */
+@MyBatisDao
+public interface OfficialInfoDao extends CrudDao<OfficialInfo> {
+
+
+    /**
+     * 查询单个分类下的数量
+     * @param officialInfo
+     * @return
+     */
+    public int findCount(OfficialInfo officialInfo);
+
+
+    /**
+     * 查询sort最大
+     * @param officialInfo
+     * @return
+     */
+    public OfficialInfo findMaxSort(OfficialInfo officialInfo);
+
+}

+ 98 - 0
src/main/java/com/jeeplus/modules/official/entity/OfficialCategory.java

@@ -0,0 +1,98 @@
+package com.jeeplus.modules.official.entity;
+
+import com.jeeplus.common.persistence.DataEntity;
+
+import java.util.List;
+
+/**
+ * 官网配置类
+ */
+public class OfficialCategory extends DataEntity<OfficialCategory> {
+    private static final long serialVersionUID = 1L;
+    private String parentId;//父级id
+
+    private String parentName;//父级名称
+    private String name;//名称
+    private String display;//是否展示
+    private String contentType;//内容类型(1:单内容,2:多内容)
+    private String sort;//排序
+    private String remarks;//备注
+
+    private String cateLevel;//当前层级
+
+    private List<OfficialCategory> children; // 树形结构用
+
+    public String getCateLevel() {
+        return cateLevel;
+    }
+
+    public void setCateLevel(String cateLevel) {
+        this.cateLevel = cateLevel;
+    }
+
+    public String getParentName() {
+        return parentName;
+    }
+
+    public void setParentName(String parentName) {
+        this.parentName = parentName;
+    }
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDisplay() {
+        return display;
+    }
+
+    public void setDisplay(String display) {
+        this.display = display;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+
+    public String getSort() {
+        return sort;
+    }
+
+    public void setSort(String sort) {
+        this.sort = sort;
+    }
+
+    public String getRemarks() {
+        return remarks;
+    }
+
+    public void setRemarks(String remarks) {
+        this.remarks = remarks;
+    }
+
+    public List<OfficialCategory> getChildren() {
+        return children;
+    }
+
+    public void setChildren(List<OfficialCategory> children) {
+        this.children = children;
+    }
+
+
+}

+ 93 - 0
src/main/java/com/jeeplus/modules/official/entity/OfficialInfo.java

@@ -0,0 +1,93 @@
+package com.jeeplus.modules.official.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.modules.sys.entity.Workattachment;
+
+import java.util.List;
+
+/**
+ * 官网分类详情类
+ */
+public class OfficialInfo extends DataEntity<OfficialInfo> {
+    private static final long serialVersionUID = 1L;
+    private String title; // 标题
+    private String isUsable; // 是否有效
+    private String sort; // 排序
+    private String cateId; // 分类id
+    private String keyword; // 关键词
+    private String content; // 内容
+
+    private String contentType; // 内容
+
+
+    private List<Workattachment> workAttachments;
+
+    public List<Workattachment> getWorkAttachments() {
+        return workAttachments;
+    }
+
+    public void setWorkAttachments(List<Workattachment> workAttachments) {
+        this.workAttachments = workAttachments;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+
+    public String getCateId() {
+        return cateId;
+    }
+
+    public void setCateId(String cateId) {
+        this.cateId = cateId;
+    }
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getIsUsable() {
+        return isUsable;
+    }
+
+    public void setIsUsable(String isUsable) {
+        this.isUsable = isUsable;
+    }
+
+    public String getSort() {
+        return sort;
+    }
+
+    public void setSort(String sort) {
+        this.sort = sort;
+    }
+
+
+
+    public String getKeyword() {
+        return keyword;
+    }
+
+    public void setKeyword(String keyword) {
+        this.keyword = keyword;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+
+}

+ 145 - 0
src/main/java/com/jeeplus/modules/official/service/OfficialCategoryService.java

@@ -0,0 +1,145 @@
+package com.jeeplus.modules.official.service;
+
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.official.dao.OfficialCategoryDao;
+import com.jeeplus.modules.official.entity.OfficialCategory;
+import com.jeeplus.modules.project.dao.ProjectDao;
+import com.jeeplus.modules.project.entity.Project;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @Author hgc
+ * @Date 2025/5/13/11:18
+ * @ClassName OfficialCategoryService
+ * @Description
+ */
+@Service
+@Transactional(readOnly = true)
+public class OfficialCategoryService extends CrudService<OfficialCategoryDao, OfficialCategory> {
+    @Autowired
+    private OfficialCategoryDao categoryDao;
+
+    public List<OfficialCategory> getCategoryTree(OfficialCategory officialCategory) {
+        List<OfficialCategory> all = super.findList(officialCategory);
+        List<OfficialCategory> relatedList = new ArrayList<>();
+        if (StringUtils.isNotBlank(officialCategory.getName())) {
+            Optional<OfficialCategory> target = all.stream()
+                    .filter(item -> officialCategory.getName().equals(item.getName()))
+                    .findFirst();
+            if (target != null) {
+                officialCategory.setId(target.get().getParentId());
+                findChildrenRecursively(all, target.get().getId(), relatedList);
+                relatedList.add(0, target.get());
+            }
+        }else{
+            relatedList = all;
+        }
+
+        return relatedList;
+    }
+
+    private void findChildrenRecursively(List<OfficialCategory> all, String parentId, List<OfficialCategory> result) {
+        for (OfficialCategory item : all) {
+            if (parentId.equals(item.getParentId())) {
+                result.add(item);
+                findChildrenRecursively(all, item.getId(), result); // 递归查找子项
+            }
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public void save(OfficialCategory officialCategory) {
+        super.save(officialCategory);
+    }
+
+    private List<OfficialCategory> buildTree(String parentId, List<OfficialCategory> all) {
+        List<OfficialCategory> tree = new ArrayList<>();
+        for (OfficialCategory category : all) {
+            if (parentId.equals(category.getParentId())) {
+                category.setChildren(buildTree(category.getId(), all));
+                tree.add(category);
+            }
+        }
+        // 排序,按字符串数字递增排序
+        tree.sort(Comparator.comparing(c -> {
+            try {
+                return Integer.parseInt(c.getSort());
+            } catch (NumberFormatException e) {
+                return 0; // 默认0
+            }
+        }));
+        return tree;
+    }
+
+
+    public int countByOffice(OfficialCategory officialCategory) {
+        return categoryDao.countByCategory(officialCategory);
+    }
+
+    public OfficialCategory findMaxSort(OfficialCategory officialCategory) {
+        return categoryDao.findMaxSort(officialCategory);
+    }
+
+
+
+
+    @Transactional(readOnly = false)
+    public void logicDelete(OfficialCategory officialCategory) {
+        // 获取所有子集
+        List<OfficialCategory> allChildren = findAllChildren(officialCategory);
+        // 更新当前
+        categoryDao.logicDelete(officialCategory);
+        // 删除所有子节点
+        if (allChildren != null && !allChildren.isEmpty()) {
+            for (OfficialCategory child : allChildren) {
+                categoryDao.logicDelete(child); // 更新数据库
+            }
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public void updateDisplay(OfficialCategory officialCategory) {
+        // 获取所有子集
+        List<OfficialCategory> allChildren = findAllChildren(officialCategory);
+        // 更新当前
+        categoryDao.updateDisplay(officialCategory);
+        // 3. 批量更新所有子节点的 display
+        if (allChildren != null && !allChildren.isEmpty()) {
+            for (OfficialCategory child : allChildren) {
+                child.setDisplay(officialCategory.getDisplay()); // 同步设置 display
+                categoryDao.updateDisplay(child); // 更新数据库
+            }
+        }
+    }
+
+
+    /**
+     * 递归获取所有子节点
+     * @param officialCategory
+     * @return
+     */
+    public List<OfficialCategory> findAllChildren(OfficialCategory officialCategory) {
+        List<OfficialCategory> result = new ArrayList<>();
+        collectChildren(officialCategory, result);
+        return result;
+    }
+
+    private void collectChildren(OfficialCategory officialCategory , List<OfficialCategory> result) {
+        List<OfficialCategory> children = categoryDao.findAllChildren(officialCategory);
+        for (OfficialCategory child : children) {
+            result.add(child);
+            // 递归收集子节点
+            collectChildren(child, result);
+        }
+    }
+}

+ 133 - 0
src/main/java/com/jeeplus/modules/official/service/OfficialInfoService.java

@@ -0,0 +1,133 @@
+package com.jeeplus.modules.official.service;
+
+import com.alibaba.fastjson.JSON;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.iim.entity.Mail;
+import com.jeeplus.modules.iim.entity.MailBox;
+import com.jeeplus.modules.iim.entity.MailCompose;
+import com.jeeplus.modules.knowledgeSharing.dify.DifyApiClient;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBase;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBaseDoc;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeSharingInfo;
+import com.jeeplus.modules.official.dao.OfficialCategoryDao;
+import com.jeeplus.modules.official.dao.OfficialInfoDao;
+import com.jeeplus.modules.official.entity.OfficialCategory;
+import com.jeeplus.modules.official.entity.OfficialInfo;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.checkerframework.checker.units.qual.A;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+/**
+ * @Author hgc
+ * @Date 2025/5/13/11:18
+ * @ClassName OfficialCategoryService
+ * @Description
+ */
+@Service
+@Transactional(readOnly = true)
+public class OfficialInfoService extends CrudService<OfficialInfoDao, OfficialInfo> {
+
+    @Autowired
+    private WorkattachmentService workattachmentService;
+
+    public List<OfficialInfo> findList(OfficialInfo officialInfo) {
+        List<OfficialInfo> list = super.findList(officialInfo);
+        return list;
+    }
+
+    public Page<OfficialInfo> findListByPage(Page<OfficialInfo> page, OfficialInfo officialInfo) {
+        //总数
+        int total = dao.findCount(officialInfo);
+        page.setCount(total);
+        page.setCountFlag(false);
+        officialInfo.setPage(page);
+        List<OfficialInfo> list = findList(officialInfo);
+        page.setList(list);
+        return page;
+    }
+
+    @Transactional(readOnly = false)
+    public void save(OfficialInfo officialInfo) {
+        //添加信息
+        super.save(officialInfo);
+        //保存附件
+        this.saveAttachments(officialInfo);
+    }
+
+    @Transactional(readOnly = false)
+    public void delete(OfficialInfo officialInfo) {
+        dao.deleteByLogic(officialInfo);
+    }
+
+    /**
+     * 添加附件信息
+     *
+     * @param officialInfo
+     */
+    @Transactional(readOnly = false)
+    public void saveAttachments(OfficialInfo officialInfo) {
+        List<Workattachment> workattachments = officialInfo.getWorkAttachments();
+        if (workattachments != null && workattachments.size() != 0) {
+            for (Workattachment workattachment : workattachments) {
+                if (workattachment.getId() == null) {
+                    continue;
+                }
+                if (workattachment.DEL_FLAG_NORMAL.equals(workattachment.getDelFlag())) {
+                    workattachment.setAttachmentId(officialInfo.getId());
+                    workattachment.setAttachmentFlag("official");
+                    workattachment.setAttachmentUser(UserUtils.getUser().getId());
+                    if (StringUtils.isBlank(workattachment.getId()) || "null".equals(workattachment.getId())) {
+                        workattachmentService.insertOnWorkAttachment(workattachment);
+                    } else {
+                        workattachmentService.updateOnWorkAttachment(workattachment);
+                    }
+                } else {
+                    workattachmentService.delete(workattachment);
+                }
+            }
+        }
+    }
+
+    /**
+     * 获取附件信息
+     *
+     * @param officialInfo
+     */
+    public void queryDetails(OfficialInfo officialInfo){
+        if (officialInfo == null) return;
+        Workattachment attchment = new Workattachment();
+        attchment.setAttachmentId(officialInfo.getId());
+        attchment.setAttachmentFlag("official");
+        List<Workattachment> attachments = workattachmentService.findList(attchment);
+        officialInfo.setWorkAttachments(attachments);
+        for (Workattachment clientAttachment : attachments) {
+            if (clientAttachment.getCollectFlag().equals("1")) {
+                for (Workattachment workattachment : officialInfo.getWorkAttachments()) {
+                    if (clientAttachment.getId().equals(workattachment.getId())) {
+                        workattachment.setCollectFlag("1");
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+
+    public OfficialInfo findMaxSort(OfficialInfo officialInfo){
+       return dao.findMaxSort(officialInfo);
+    }
+
+    public int findCount(OfficialInfo officialInfo){
+        return dao.findCount(officialInfo);
+    }
+}

+ 242 - 0
src/main/java/com/jeeplus/modules/official/web/OfficialCategoryController.java

@@ -0,0 +1,242 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.official.web;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.official.entity.OfficialCategory;
+import com.jeeplus.modules.official.service.OfficialCategoryService;
+import com.jeeplus.modules.project.entity.*;
+import com.jeeplus.modules.project.service.ProjectService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientLinkman;
+import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
+import com.jeeplus.modules.workcontractinfo.service.WorkContractInfoService;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.validation.ConstraintViolationException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 官网分类配置Controller
+ *
+ * @author fgy
+ * @version 2017-10-12
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/official/category")
+public class OfficialCategoryController extends BaseController {
+
+    @Autowired
+    private OfficialCategoryService categoryService;
+
+    @ModelAttribute
+    public OfficialCategory get(@RequestParam(required = false) String id) {
+        OfficialCategory entity = null;
+        if (StringUtils.isNotBlank(id)) {
+            entity = categoryService.get(id);
+        }
+        if (entity == null) {
+            entity = new OfficialCategory();
+        }
+        return entity;
+    }
+
+    /**
+     * 分类列表
+     */
+    @RequiresPermissions("official:category:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(OfficialCategory officialCategory, HttpServletRequest request, HttpServletResponse response, Model model) {
+        List<OfficialCategory> tree = categoryService.getCategoryTree(officialCategory);
+        model.addAttribute("list", tree);
+        model.addAttribute("officialCategory", officialCategory);
+        return "modules/official/officialCategoryList";
+    }
+
+
+    /**
+     * 查看,增加,编辑项目表单页面
+     */
+    @RequiresPermissions(value = {"official:category:add", "official:category:edit"}, logical = Logical.OR)
+    @RequestMapping(value = "form")
+    public String form(OfficialCategory officialCategory, Model model, HttpSession session, HttpServletRequest request) {
+        String view = request.getParameter("view");
+        if (!StringUtils.isBlank(view)) {
+            if (view.equals("view")) {
+                return "modules/official/officialCategoryView";
+            }
+        }
+
+        String add = request.getParameter("add");
+        if (!StringUtils.isBlank(add)) {
+            if (add.equals("add")) {
+                officialCategory.setDisplay("1");
+                officialCategory.setContentType("2");
+            }
+        }
+
+        if (StringUtils.isNotBlank(officialCategory.getParentId())) {
+            officialCategory.setParentId(officialCategory.getParentId());
+        }
+        if (StringUtils.isNotBlank(officialCategory.getParentName())) {
+            officialCategory.setParentName(officialCategory.getParentName());
+        }
+        model.addAttribute("officialCategory", officialCategory);
+        return "modules/official/officialCategoryForm";
+    }
+
+
+    /**
+     * 查看,增加,编辑项目表单页面
+     */
+    @RequiresPermissions("official:category:add")
+    @RequestMapping(value = "save")
+    public String save(OfficialCategory officialCategory, Model model, HttpSession session, HttpServletRequest request) throws Exception {
+        if (!beanValidator(model, officialCategory)) {
+            return form(officialCategory, model, session, request);
+        }
+        OfficialCategory parent = get(officialCategory.getParentId()); // 查父节点
+        if (parent != null) {
+            String parentLevel = parent.getCateLevel();
+            int level = 1;
+            try {
+                level = Integer.parseInt(parentLevel) + 1;
+            } catch (NumberFormatException e) {
+                level = 1; // 如果转换失败默认设为 1
+            }
+            officialCategory.setCateLevel(String.valueOf(level));
+        } else {
+            officialCategory.setCateLevel("1"); // 如果找不到父节点,默认1级
+        }
+        if (!officialCategory.getIsNewRecord()) {//编辑表单保存
+            OfficialCategory t = get(officialCategory.getId());//从数据库取出记录的值
+            MyBeanUtils.copyBeanNotNull2Bean(officialCategory, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+            categoryService.save(t);//保存
+        } else {//新增表单保存
+            if (StringUtils.isBlank(officialCategory.getSort())) {
+                OfficialCategory maxSort = categoryService.findMaxSort(officialCategory);
+                int sortNum = 10;
+                if (maxSort != null) {
+                    sortNum = Integer.parseInt(maxSort.getSort()) + 1;
+                } else {
+                    sortNum = 10;
+                }
+                officialCategory.setSort(String.valueOf(sortNum));
+            }
+            categoryService.save(officialCategory);//保存
+        }
+        return "redirect:" + Global.getAdminPath() + "/official/category/?repage";
+    }
+
+    /**
+     * 删除分类。逻辑删除
+     *
+     * @param officialCategory
+     * @param redirectAttributes
+     * @param request
+     * @return
+     */
+    @RequiresPermissions("official:category:del")
+    @RequestMapping(value = "delete")
+    @ResponseBody
+    public Map<String, Object> delete(OfficialCategory officialCategory, RedirectAttributes redirectAttributes, HttpServletRequest request) {
+        HashMap<String, Object> map = new HashMap<>();
+        try {
+            if (StringUtils.isBlank(officialCategory.getId())) {
+                addMessage(redirectAttributes, "删除分类失败!");
+                map.put("success", false);
+            }
+            if ("1".equals(officialCategory.getId())) {
+                addMessage(redirectAttributes, "删除分类失败,不能删除当前分类!");
+                map.put("success", false);
+            }
+            categoryService.logicDelete(officialCategory);
+            map.put("success", true);
+        } catch (Exception e) {
+            map.put("success", false);
+        }
+        return map;
+    }
+
+    /**
+     * 分类的隐藏和显示
+     *
+     * @param officialCategory
+     * @param redirectAttributes
+     * @param request
+     * @return
+     */
+    @RequiresPermissions("official:category:edit")
+    @RequestMapping(value = "deleteDisplay")
+    public String deleteDisplay(OfficialCategory officialCategory, RedirectAttributes redirectAttributes, HttpServletRequest request) {
+        try {
+            categoryService.updateDisplay(officialCategory);
+            addMessage(redirectAttributes, "操作成功");
+        } catch (Exception e) {
+            logger.error("Exception e:" + e);
+            addMessage(redirectAttributes, "操作失败");
+        }
+        return "redirect:" + Global.getAdminPath() + "/official/category/?repage";
+    }
+
+
+    /**
+     * 树型数据
+     */
+    //@RequiresPermissions("project:project:list")
+    @RequestMapping(value = {"treeData"})
+    @ResponseBody
+    public List<Map<String, Object>> treeData(@RequestParam(required = false) String extId, @RequestParam(required = false) String type, @RequestParam(required = false) String selectName,
+                                              @RequestParam(required = false) Long grade, @RequestParam(required = false) Boolean isAll, @RequestParam(required = false) Integer flagOffice, HttpServletResponse response) {
+        OfficialCategory officialCategory = new OfficialCategory();
+        List<Map<String, Object>> mapList = Lists.newArrayList();
+        if (StringUtils.isNotBlank(selectName)) {
+            officialCategory.setName(selectName);
+        }
+        List<OfficialCategory> list = categoryService.getCategoryTree(officialCategory);
+
+        for (int i = 0; i < list.size(); i++) {
+            OfficialCategory e = list.get(i);
+
+            if ((StringUtils.isNotBlank(extId) && !extId.equals(e.getId()) && !extId.equals(e.getParentId()))
+                    && Global.SHOW.equals(e.getDisplay())) {
+
+                Map<String, Object> map = Maps.newHashMap();
+                map.put("id", e.getId());
+                map.put("pId", e.getParentId());
+                map.put("pIds", e.getParentId()); // 如果 pIds 是所有父级ID串,这里建议用 e.getParentIds()
+                map.put("name", e.getName());
+                mapList.add(map);
+            }
+        }
+        return mapList;
+    }
+
+
+}

+ 253 - 0
src/main/java/com/jeeplus/modules/official/web/OfficialInfoController.java

@@ -0,0 +1,253 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.official.web;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.iim.entity.Mail;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBase;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeSharingInfo;
+import com.jeeplus.modules.official.entity.OfficialCategory;
+import com.jeeplus.modules.official.entity.OfficialInfo;
+import com.jeeplus.modules.official.service.OfficialCategoryService;
+import com.jeeplus.modules.official.service.OfficialInfoService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 官网分类配置Controller
+ *
+ * @author fgy
+ * @version 2017-10-12
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/official/info")
+public class OfficialInfoController extends BaseController {
+
+    @Autowired
+    private OfficialCategoryService categoryService;
+
+    @Autowired
+    private OfficialInfoService officialInfoService;
+
+    @ModelAttribute
+    public OfficialInfo get(@RequestParam(required = false) String id) {
+        OfficialInfo entity = null;
+        if (StringUtils.isNotBlank(id)) {
+            entity = officialInfoService.get(id);
+        }
+        if (entity == null) {
+            entity = new OfficialInfo();
+        }
+        return entity;
+    }
+
+    /**
+     * 分类列表
+     */
+    //@RequiresPermissions("project:project:list")
+    @RequestMapping(value = {""})
+    public String list(OfficialInfo officialInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        return "modules/official/officialIndex";
+    }
+
+    /**
+     * 分类详情列表
+     */
+    //@RequiresPermissions("project:project:list")
+    @RequestMapping(value = {"infoList"})
+    public String infoList(OfficialInfo officialInfo, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
+        Page<OfficialInfo> page = officialInfoService.findListByPage(new Page<OfficialInfo>(request, response), officialInfo);
+        model.addAttribute("page", page);
+        model.addAttribute("officialInfo", officialInfo);
+        return "modules/official/officialInfo";
+    }
+
+
+    /**
+     * 查看,增加,编辑项目表单页面
+     */
+    @RequestMapping(value = "form")
+    public String form(OfficialInfo officialInfo, Model model, HttpServletRequest request) throws Exception {
+        OfficialCategory officialCategory = categoryService.get(officialInfo.getCateId());
+
+        if (officialInfo != null && StringUtils.isNotBlank(officialInfo.getId())) {
+            officialInfoService.queryDetails(officialInfo);
+        } else {
+            officialInfo.setCreateBy(UserUtils.getUser());
+            officialInfo.setCreateDate(new Date());
+            officialInfo.setIsUsable("1");
+        }
+        model.addAttribute("officialCategory", officialCategory);
+        model.addAttribute("OfficialInfo", officialInfo);
+        if("view".equals(request.getParameter("view"))){
+            return "modules/official/officialInfoView";
+        }
+        return "modules/official/officialInfoForm";
+    }
+
+    /**
+     * 判断是否为单内容
+     */
+    @RequestMapping(value = "isContentType")
+    @ResponseBody
+    public Map<String, Object> isContentType(OfficialInfo officialInfo, Model model, HttpServletRequest request) throws Exception {
+        HashMap<String, Object> map = new HashMap<>();
+        OfficialCategory officialCategory = categoryService.get(officialInfo.getCateId());
+        String contentType = officialCategory.getContentType();
+        if("1".equals(contentType)){
+            int count = officialInfoService.findCount(officialInfo);
+            if (count >= 1) {
+                map.put("success", false);
+            } else {
+                map.put("success", true);
+            }
+        }else{
+            map.put("success", true);
+        }
+
+        return map;
+    }
+
+
+    @RequestMapping(value = "view")
+    public String view(OfficialInfo officialInfo, Model model, HttpServletRequest request) {
+        if (StringUtils.isNotBlank(officialInfo.getCateId())) {
+            OfficialCategory officialCategory = categoryService.get(officialInfo.getCateId());
+            model.addAttribute("officialCategory", officialCategory);
+        }
+
+        if (officialInfo != null && StringUtils.isNotBlank(officialInfo.getId())) {
+            officialInfoService.queryDetails(officialInfo);
+        } else {
+            officialInfo.setCreateBy(UserUtils.getUser());
+            officialInfo.setCreateDate(new Date());
+            officialInfo.setIsUsable("1");
+        }
+        model.addAttribute("OfficialInfo", officialInfo);
+        return "modules/official/officialInfoView";
+    }
+
+
+    @RequestMapping(value = "delete")
+    @ResponseBody
+    public  Map<String, Object> delete(OfficialInfo officialInfo) {
+        HashMap<String, Object> map = new HashMap<>();
+        try {
+            officialInfoService.delete(officialInfo);
+            map.put("success", true);
+        } catch (Exception e) {
+            map.put("success", false);
+        }
+        return map;
+    }
+
+    /**
+     * 批量删除
+     */
+    @RequestMapping(value = "deleteAll")
+    public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+        String idArray[] = ids.split(",");
+        for (String id : idArray) {
+            officialInfoService.delete(officialInfoService.get(id));
+        }
+        addMessage(redirectAttributes, "删除成功");
+        return "redirect:" + Global.getAdminPath() + "/official/info/infoList/?repage";
+    }
+
+
+    /**
+     * 保存
+     *
+     * @param officialInfo
+     * @param model
+     * @param redirectAttributes
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "save")
+    public String save(OfficialInfo officialInfo, Model model, RedirectAttributes redirectAttributes, HttpServletRequest request) throws Exception {
+        if (!beanValidator(model, officialInfo)) {
+            return form(officialInfo, model, request);
+        }
+        if (!officialInfo.getIsNewRecord()) {//编辑表单保存
+            OfficialInfo t = officialInfoService.get(officialInfo.getId());//从数据库取出记录的值
+            MyBeanUtils.copyBeanNotNull2Bean(officialInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+            officialInfoService.save(t);//保存
+        } else {//新增表单保存
+            if(StringUtils.isBlank(officialInfo.getSort())){
+                OfficialInfo maxSort = officialInfoService.findMaxSort(officialInfo);
+                int sortNum = 10;
+                if(maxSort != null){
+                    sortNum = Integer.parseInt(maxSort.getSort() )+ 1 ;
+                }else{
+                    sortNum = 10;
+                }
+                officialInfo.setSort(String.valueOf(sortNum));
+            }
+            officialInfoService.save(officialInfo);//保存
+        }
+        addMessage(redirectAttributes, "保存成功");
+        return "redirect:" + Global.getAdminPath() + "/official/info/infoList?cateId=" + officialInfo.getCateId();
+
+    }
+
+
+    /**
+     * 树型数据
+     */
+    //@RequiresPermissions("project:project:list")
+    @RequestMapping(value = {"treeData"})
+    @ResponseBody
+    public List<Map<String, Object>> treeData(@RequestParam(required = false) String userId, @RequestParam(required = false) String extId, @RequestParam(required = false) String type,
+                                              @RequestParam(required = false) Long grade, @RequestParam(required = false) Boolean isAll, HttpServletResponse response) {
+        OfficialCategory officialCategory = new OfficialCategory();
+        List<Map<String, Object>> mapList = Lists.newArrayList();
+        List<OfficialCategory> list = categoryService.getCategoryTree(officialCategory);
+
+        for (int i = 0; i < list.size(); i++) {
+            OfficialCategory e = list.get(i);
+
+            if ((StringUtils.isBlank(extId) || !extId.equals(e.getId()))) {
+                Map<String, Object> map = Maps.newHashMap();
+                map.put("id", e.getId());
+                map.put("name", e.getName());
+                map.put("pId", e.getParentId());
+                if (!"1".equals(e.getId())) {
+                    map.put("pIds", "1," + e.getParentId()); // 如果 pIds 是所有父级ID串,这里建议用 e.getParentIds()
+                } else {
+                    map.put("pIds", "1"); // 如果 pIds 是所有父级ID串,这里建议用 e.getParentIds()
+                }
+                map.put("look", false);
+                map.put("contentType", e.getContentType());
+                map.put("cateLevel", e.getCateLevel());
+                mapList.add(map);
+            }
+        }
+        return mapList;
+    }
+
+}

+ 146 - 0
src/main/resources/mappings/modules/official/OfficialCategoryDao.xml

@@ -0,0 +1,146 @@
+<?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.jeeplus.modules.official.dao.OfficialCategoryDao">
+
+	<sql id="officialCategoryColumns">
+	a.id AS "id",
+    a.parent_id AS "parentId",
+    a.name AS "name",
+    a.display AS "display",
+    a.cate_level AS "cateLevel",
+    a.content_type AS "contentType",
+    a.sort AS "sort",
+	a.create_by AS "createBy.id",
+	a.create_date AS "createDate",
+	a.update_by AS "updateBy.id",
+	a.update_date AS "updateDate",
+	a.remarks AS "remarks",
+	a.del_flag AS "delFlag",
+	su.name AS "createBy.name",
+	z.name AS "parentName"
+	</sql>
+
+	<select id="get" resultType="OfficialCategory">
+		select
+		<include refid="officialCategoryColumns" />
+		from official_category a
+		left join sys_user su on su.id = a.create_by
+		left join official_category z on z.id =  a.parent_id
+		where a.id = #{id} and  a.del_flag = "0"
+
+	</select>
+
+	<select id="findList" resultType="OfficialCategory">
+		select
+		<include refid="officialCategoryColumns" />
+		from official_category a
+		left join sys_user su on su.id = a.create_by
+		left join official_category z on z.id =  a.parent_id
+        <where>
+            a.del_flag = "0"
+
+        </where>
+		order BY a.sort ASC
+	</select>
+
+    <select id="countByCategory" resultType="java.lang.Integer">
+        SELECT
+            count(*)
+        FROM official_category a
+        WHERE a.parent_id = #{id} AND a.del_flag = 0
+    </select>
+
+    <update id="logicDelete">
+        UPDATE official_category SET del_flag = '1' WHERE id = #{id}
+    </update>
+
+	<insert id="insert">
+        INSERT INTO official_category(
+            id,
+            parent_id,
+            name,
+            display,
+            cate_level,
+            content_type,
+            sort,
+            create_by,
+            create_date,
+            update_by,
+            update_date,
+            remarks,
+            del_flag
+        )
+        VALUES (
+                   #{id},
+                   #{parentId},
+                   #{name},
+                   #{display},
+                   #{cateLevel},
+                   #{contentType},
+                   #{sort},
+                   #{createBy.id},
+                   #{createDate},
+                   #{updateBy.id},
+                   #{updateDate},
+                   #{remarks},
+                   #{delFlag}
+               )
+
+    </insert>
+
+	<update id="update">
+        UPDATE official_category
+        SET parent_id= #{parentId},
+            name = #{name},
+            display = #{display},
+            cate_level = #{cateLevel},
+            content_type = #{contentType},
+            sort = #{sort},
+            create_by = #{createBy.id},
+            create_date = #{createDate},
+            update_by = #{updateBy.id},
+            update_date = #{updateDate},
+            remarks= #{remarks},
+            del_flag = #{delFlag}
+        WHERE id = #{id}
+    </update>
+
+    <update id="updateDisplay">
+        UPDATE official_category
+        SET display=#{display}
+        WHERE id = #{id} or parent_id = #{id}
+    </update>
+
+
+    <select id="findAllChildren" resultType="OfficialCategory">
+        select
+        <include refid="officialCategoryColumns" />
+        from official_category a
+        left join sys_user su on su.id = a.create_by
+        left join official_category z on z.id =  a.parent_id
+        <where>
+            a.del_flag = "0"
+            <if test="parentId != null and parentId != ''">
+                AND a.parent_id = #{id}
+            </if>
+        </where>
+    </select>
+
+    <select id="findMaxSort" resultType="OfficialCategory">
+        SELECT
+        <include refid="officialCategoryColumns" />
+        FROM official_category a
+        left join sys_user su on su.id = a.create_by
+        left join official_category z on z.id =  a.parent_id
+        <where>
+            a.del_flag = "0"
+            <if test="parentId != null and parentId != ''">
+                AND a.parent_id = #{parentId}
+            </if>
+        </where>
+        ORDER BY sort DESC
+        LIMIT 1;
+    </select>
+
+
+</mapper>

+ 149 - 0
src/main/resources/mappings/modules/official/OfficialInfoDao.xml

@@ -0,0 +1,149 @@
+<?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.jeeplus.modules.official.dao.OfficialInfoDao">
+
+	<sql id="OfficialInfoColumns">
+	a.id AS "id",
+    a.title AS "title",
+	a.is_usable AS "isUsable",
+    a.sort AS "sort",
+	a.cate_id AS "cateId",
+	a.keyword AS "keyword",
+    a.content AS "content",
+	a.create_by AS "createBy.id",
+	a.create_date AS "createDate",
+	a.update_by AS "updateBy.id",
+	a.update_date AS "updateDate",
+	a.remarks AS "remarks",
+	a.del_flag AS "delFlag",
+	z.content_type AS "contentType",
+	su.name AS "createBy.name"
+	</sql>
+
+	<select id="get" resultType="com.jeeplus.modules.official.entity.OfficialInfo">
+		select
+		<include refid="OfficialInfoColumns" />
+		from official_info a
+		left join official_category z on z.id =  a.cate_id
+		left join sys_user su on su.id = a.create_by
+		where a.id = #{id} and  a.del_flag = "0"
+	</select>
+
+	<select id="findList" resultType="com.jeeplus.modules.official.entity.OfficialInfo">
+		select
+		<include refid="OfficialInfoColumns" />
+		from official_info a
+		left join official_category z on z.id =  a.cate_id
+		left join sys_user su on su.id = a.create_by
+        <where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+			<if test="cateId != null and cateId != ''">
+				AND a.cate_id = #{cateId}
+			</if>
+			<if test="title != null and title != ''">
+				AND a.title LIKE CONCAT('%', #{title}, '%')
+			</if>
+			<if test="keyword != null and keyword != ''">
+				AND a.keyword LIKE CONCAT('%', #{keyword}, '%')
+			</if>
+			<if test="isUsable != null and isUsable != ''">
+				AND a.is_usable = #{isUsable}
+			</if>
+        </where>
+		order BY a.sort ASC
+	</select>
+
+    <select id="findCount" resultType="java.lang.Integer">
+        select count(*)
+        from official_info a
+        left join official_category z on z.id = a.cate_id
+        <where>
+            a.del_flag = #{DEL_FLAG_NORMAL}
+			<if test="cateId != null and cateId != ''">
+				AND a.cate_id = #{cateId}
+			</if>
+        </where>
+    </select>
+
+	<insert id="insert">
+		INSERT INTO official_info(
+			id,
+			title,
+		    keyword,
+			is_usable,
+			sort,
+			cate_id,
+			content,
+			create_by,
+			create_date,
+			update_by,
+			update_date,
+			remarks,
+			del_flag
+		)
+		VALUES (
+				   #{id},
+				   #{title},
+				   #{keyword},
+				   #{isUsable},
+				   #{sort},
+				   #{cateId},
+				   #{content},
+				   #{createBy.id},
+				   #{createDate},
+				   #{updateBy.id},
+				   #{updateDate},
+				   #{remarks},
+				   #{delFlag}
+			   )
+
+	</insert>
+
+	<update id="update">
+		UPDATE official_info
+		SET
+			title= #{title},
+			keyword=#{keyword},
+			is_usable= #{isUsable},
+			sort= #{sort},
+			cate_id= #{cateId},
+			content= #{content},
+			create_by= #{createBy.id},
+			create_date= #{createDate},
+			update_by= #{updateBy.id},
+			update_date= #{updateDate},
+			remarks= #{remarks},
+			del_flag = #{delFlag}
+		WHERE id = #{id}
+	</update>
+
+
+	<!--物理删除-->
+	<update id="delete">
+		DELETE FROM official_info
+		WHERE id = #{id}
+	</update>
+
+	<!--逻辑删除-->
+	<update id="deleteByLogic">
+		UPDATE official_info SET
+			del_flag = #{DEL_FLAG_DELETE}
+		WHERE id = #{id}
+	</update>
+
+	<select id="findMaxSort" resultType="com.jeeplus.modules.official.entity.OfficialInfo">
+		SELECT
+		<include refid="OfficialInfoColumns" />
+		FROM official_info a
+		left join official_category z on z.id =  a.cate_id
+		left join sys_user su on su.id = a.create_by
+		<where>
+			a.del_flag = "0"
+			<if test="cateId != null and cateId != ''">
+				AND a.cate_id = #{cateId}
+			</if>
+		</where>
+		ORDER BY sort DESC
+		LIMIT 1;
+	</select>
+</mapper>

+ 98 - 0
src/main/webapp/WEB-INF/tags/sys/treeselectOfficialCategory.tag

@@ -0,0 +1,98 @@
+<%@ tag language="java" pageEncoding="UTF-8"%>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<%@ attribute name="id" type="java.lang.String" required="true" description="编号"%>
+<%@ attribute name="name" type="java.lang.String" required="true" description="隐藏域名称(ID)"%>
+<%@ attribute name="value" type="java.lang.String" required="true" description="隐藏域值(ID)"%>
+<%@ attribute name="labelName" type="java.lang.String" required="true" description="输入框名称(Name)"%>
+<%@ attribute name="labelValue" type="java.lang.String" required="true" description="输入框值(Name)"%>
+<%@ attribute name="title" type="java.lang.String" required="true" description="选择框标题"%>
+<%@ attribute name="url" type="java.lang.String" required="true" description="树结构数据地址"%>
+<%@ attribute name="checked" type="java.lang.Boolean" required="false" description="是否显示复选框,如果不需要返回父节点,请设置notAllowSelectParent为true"%>
+<%@ attribute name="extId" type="java.lang.String" required="false" description="排除掉的编号(不能选择的编号)"%>
+<%@ attribute name="isAll" type="java.lang.Boolean" required="false" description="是否列出全部数据,设置true则不进行数据权限过滤(目前仅对Office有效)"%>
+<%@ attribute name="notAllowSelectRoot" type="java.lang.Boolean" required="false" description="不允许选择根节点"%>
+<%@ attribute name="notAllowSelectParent" type="java.lang.Boolean" required="false" description="不允许选择父节点"%>
+<%@ attribute name="module" type="java.lang.String" required="false" description="过滤栏目模型(只显示指定模型,仅针对CMS的Category树)"%>
+<%@ attribute name="selectScopeModule" type="java.lang.Boolean" required="false" description="选择范围内的模型(控制不能选择公共模型,不能选择本栏目外的模型)(仅针对CMS的Category树)"%>
+<%@ attribute name="allowClear" type="java.lang.Boolean" required="false" description="是否允许清除"%>
+<%@ attribute name="allowInput" type="java.lang.Boolean" required="false" description="文本框可填写"%>
+<%@ attribute name="cssClass" type="java.lang.String" required="false" description="css样式"%>
+<%@ attribute name="cssStyle" type="java.lang.String" required="false" description="css样式"%>
+<%@ attribute name="smallBtn" type="java.lang.Boolean" required="false" description="缩小按钮显示"%>
+<%@ attribute name="hideBtn" type="java.lang.Boolean" required="false" description="是否显示按钮"%>
+<%@ attribute name="disabled" type="java.lang.String" required="false" description="是否限制选择,如果限制,设置为disabled"%>
+<%@ attribute name="dataMsgRequired" type="java.lang.String" required="false" description=""%>
+	<input id="${id}Id" name="${name}" class="${cssClass}" type="hidden" value="${value}"/>
+	<div class="input-group">
+		<input id="${id}Name" placeholder="请选择${title}" name="${labelName}" ${allowInput?'':'readonly="readonly"'}  type="text" value="${labelValue}" data-msg-required="${dataMsgRequired}"
+		class="${cssClass}" style="${cssStyle}"/>
+       		 <span class="input-group-btn">
+	       		 <button type="button"  id="${id}Button" class="btn <c:if test="${fn:contains(cssClass, 'input-sm')}"> btn-sm </c:if><c:if test="${fn:contains(cssClass, 'input-lg')}"> btn-lg </c:if>  btn-primary ${disabled} ${hideBtn ? 'hide' : ''}"><i class="fa fa-search"></i>
+	             </button> 
+       		 </span>
+       		
+    </div>
+	 <label id="${id}Name-error" class="error" for="${id}Name" style="display:none"></label>
+<script type="text/javascript">
+	$("#${id}Button, #${id}Name").click(function(){
+		// 是否限制选择,如果限制,设置为disabled
+		if ($("#${id}Button").hasClass("disabled")){
+			return true;
+		}
+		// 正常打开	
+		top.layer.open({
+		    type: 2, 
+		    area: ['300px', '420px'],
+		    title:"选择${title}",
+		    ajaxData:{selectIds: $("#${id}Id").val()},
+		    content: "${ctx}/tag/treeselect?url="+encodeURIComponent("${url}")+"&module=${module}&checked=${checked}&extId=${extId}&isAll=${isAll}" ,
+		    btn: ['确定', '关闭']
+    	       ,yes: function(index, layero){ //或者使用btn1
+						var tree = layero.find("iframe")[0].contentWindow.tree;//h.find("iframe").contents();
+						var ids = [], names = [], nodes = [];
+						if ("${checked}" == "true"){
+							nodes = tree.getCheckedNodes(true);
+						}else{
+							nodes = tree.getSelectedNodes();
+						}
+						for(var i=0; i<nodes.length; i++) {//<c:if test="${checked && notAllowSelectParent}">
+							if (nodes[i].isParent){
+								continue; // 如果为复选框选择,则过滤掉父节点
+							}//</c:if><c:if test="${notAllowSelectRoot}">
+							if (nodes[i].level == 0){
+								//top.$.jBox.tip("不能选择根节点("+nodes[i].name+")请重新选择。");
+								top.layer.msg("不能选择根节点("+nodes[i].name+")请重新选择。", {icon: 0});
+								return false;
+							}//</c:if><c:if test="${notAllowSelectParent}">
+							if (nodes[i].isParent){
+								//top.$.jBox.tip("不能选择父节点("+nodes[i].name+")请重新选择。");
+								//layer.msg('有表情地提示');
+								top.layer.msg("不能选择父节点("+nodes[i].name+")请重新选择。", {icon: 0});
+								return false;
+							}//</c:if><c:if test="${not empty module && selectScopeModule}">
+							if (nodes[i].module == ""){
+								//top.$.jBox.tip("不能选择公共模型("+nodes[i].name+")请重新选择。");
+								top.layer.msg("不能选择公共模型("+nodes[i].name+")请重新选择。", {icon: 0});
+								return false;
+							}else if (nodes[i].module != "${module}"){
+								//top.$.jBox.tip("不能选择当前栏目以外的栏目模型,请重新选择。");
+								top.layer.msg("不能选择当前栏目以外的栏目模型,请重新选择。", {icon: 0});
+								return false;
+							}//</c:if>
+							ids.push(nodes[i].id);
+							names.push(nodes[i].name);//<c:if test="${!checked}">
+							break; // 如果为非复选框选择,则返回第一个选择  </c:if>
+						}
+						$("#${id}Id").val(ids.join(",").replace(/u_/ig,""));
+						$("#${id}Name").val(names.join(","));
+						$("#${id}Name").focus();
+						setCompInfo($("#${id}Id").val());
+						top.layer.close(index);
+				    	       },
+    	cancel: function(index){ //或者使用btn2
+    	           //按钮【按钮二】的回调
+    	       }
+		}); 
+	
+	});
+</script>

+ 196 - 0
src/main/webapp/webpage/modules/official/officialCategoryForm.jsp

@@ -0,0 +1,196 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+<html>
+<head>
+    <title>分类管理</title>
+    <meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <style>
+        label.error {
+            left: 0;
+            top: 40px;
+        }
+    </style>
+    <script type="text/javascript">
+        var validateForm;
+
+        function doSubmit() {//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if (validateForm.form()) {
+                $("#inputForm").submit();
+                return true;
+            }
+            return false;
+        }
+
+        $(document).ready(function () {
+            layui.use(['form', 'layer'], function () {
+                var form = layui.form;
+            });
+            jQuery.validator.addMethod("isMobile", function (value, element) {
+                var length = value.length;
+                var mobile = /^(13[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})|(14[0-9]{9})|(17[0-9]{9})|(15[0-9]{9})$/;
+                return (length == 0 || (length == 11 && mobile.test(value)));
+            }, "请正确填写您的手机号码");
+            $("#name").focus();
+            validateForm = $("#inputForm").validate({
+                submitHandler: function (form) {
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                /*rules: {
+                    name:{remote: "${ctx}/sys/company/validateCompany?oldName=" + encodeURIComponent("${office.name}")}
+                },
+                messages: {
+                    name:{remote: "此公司名称已经被注册!", required: "公司名称不能为空."}
+                },*/
+                errorContainer: "#messageBox",
+                errorPlacement: function (error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+
+            /*if('
+            ${sessionScope.state}' =='disabled'){
+                $('select').attr('disabled','
+            <%=session.getAttribute("state")%>');
+            }else if('
+            ${sessionScope.state}' !='disabled'){
+                $('select').removeAttr('disabled');
+            }*/
+            setCompInfo($("#officeId").val());
+            dispSimpleName('${office.type}');
+        });
+
+        function setCompInfo(comId) {
+            $.ajax({
+                type: 'post',
+                url: '${ctx}/sys/office/compInfo',
+                data: {
+                    "id": comId
+                },
+                success: function (data) {
+                    if (data.type == "2") {
+                        $("#type option[value='1']").hide();
+                        $("#type option[value='2']").show();
+                        $("#type option[value='3']").hide();
+                    } else if (data.type == "3") {
+                        $("#type option[value='1']").hide();
+                        $("#type option[value='2']").show();
+                        $("#type option[value='3']").show();
+                    } else {
+                        $("#type option[value='1']").hide();
+                        $("#type option[value='2']").show();
+                        $("#type option[value='3']").show();
+                    }
+                }
+            })
+        }
+
+        function dispSimpleName(val) {
+            /*if(val=='1'){
+                $(".simpleName").show();
+            }else {
+                $(".simpleName").hide();
+            }*/
+        }
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <form:form id="inputForm" modelAttribute="officialCategory" action="${ctx}/official/category/save" method="post"
+                   class="form-horizontal layui-form">
+            <form:hidden path="id"/>
+            <sys:message content="${message}"/>
+            <input type="hidden" id="sign"/>
+            <c:set var="officedis" scope="session" value='<%=session.getAttribute("state")%>'/>
+            <c:set var="cnmae" scope="session" value='<%=session.getAttribute("cname")%>'/>
+
+            <div class="form-group layui-row first">
+                <div class="form-group-label"><h2>分类信息</h2></div>
+                <div class="layui-item layui-col-sm12">
+                    <label class="layui-form-label"><span class="require-item">*</span>上级分类:</label>
+                    <div class="layui-input-block with-icon">
+<%--                        <c:choose>--%>
+<%--                            <c:when test="${not empty officialCategory.id}">--%>
+                                <input placeholder="请选择上级分类" htmlEscape="false" readonly="true"
+                                       class="form-control layui-input" value="${officialCategory.parentName}"/>
+<%--                            </c:when>--%>
+<%--                            <c:otherwise>--%>
+<%--                                <sys:treeselectOfficialCategory id="parentId" name="parentId"--%>
+<%--                                                                value="${officialCategory.parentId}"--%>
+<%--                                                                labelName="parentName"--%>
+<%--                                                                labelValue="${officialCategory.parentName}"--%>
+<%--                                                                title="分类" url="/official/category/treeData"--%>
+<%--                                                                extId="${officialCategory.id}"--%>
+<%--                                                                cssClass="form-control layui-input required"--%>
+<%--                                                                allowClear="${true}"/>--%>
+<%--                            </c:otherwise>--%>
+<%--                        </c:choose>--%>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label"><span class="require-item">*</span>分类名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="name" placeholder="分类名称" htmlEscape="false" maxlength="50"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label"><span class="require-item">*</span>是否展示:</label>
+                    <div class="layui-input-block">
+                        <c:forEach var="item" items="${fns:getDictList('category_display')}">
+                            <input type="radio" name="display" value="${item.value}" title="${item.label}"
+                                   <c:if test="${item.value == officialCategory.display}">checked</c:if>>
+                        </c:forEach>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label">排序:</label>
+                    <div class="layui-input-block">
+                        <form:input path="sort" placeholder="排序" htmlEscape="false" maxlength="50"
+                                    class="form-control number layui-input "/>
+                    </div>
+                </div>
+                <c:choose>
+                    <c:when test="${officialCategory.cateLevel >= 2 && officialCategory.parentId != '1'}">
+                        <!-- cateLevel >= 3 的情况 -->
+                        <div class="layui-item layui-col-sm6">
+                            <label class="layui-form-label"><span class="require-item">*</span>内容类型:</label>
+                            <div class="layui-input-block">
+                                <c:forEach var="item" items="${fns:getDictList('content_type')}">
+                                    <input type="radio" name="contentType" value="${item.value}" title="${item.label}"
+                                           <c:if test="${item.value == officialCategory.contentType}">checked</c:if>>
+                                </c:forEach>
+                            </div>
+                        </div>
+                    </c:when>
+                    <c:otherwise>
+                        <form:hidden path="contentType"/>
+                    </c:otherwise>
+                </c:choose>
+
+                <div class="layui-item layui-col-sm12 with-textarea">
+                    <label class="layui-form-label">备注:</label>
+                    <div class="layui-input-block">
+                        <form:textarea path="remarks" placeholder="请输入备注" htmlEscape="false" rows="3"
+                                       maxlength="200" class="form-control"/>
+                    </div>
+                </div>
+            </div>
+
+        </form:form>
+    </div>
+</div>
+</body>
+<%
+    session.removeAttribute("state");
+    session.removeAttribute("cname");
+%>
+</html>

+ 276 - 0
src/main/webapp/webpage/modules/official/officialCategoryList.jsp

@@ -0,0 +1,276 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+<html>
+<head>
+    <title>分类管理</title>
+    <meta name="decorator" content="default"/>
+    <%@include file="/webpage/include/treetable.jsp" %>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            $("th").css('text-align', 'center');
+            var tpl = $("#treeTableTpl").html().replace(/(\/\/\<!\-\-)|(\/\/\-\->)/g, "");
+            var data = ${fns:toJson(list)}, rootId = "${not empty officialCategory.id ? officialCategory.id : '-1'}";
+            addRow("#treeTableList", tpl, data, rootId, true);
+            $("#treeTable").treeTable({expandLevel: 999});
+
+            $("a").on("click", addLinkVisied);
+            stateBtn("#treeTableList")
+
+        });
+
+        function stateBtn(list) {
+            //隐藏对应状态按钮
+            var tableLists = $(list).context.getElementById('treeTableList').getElementsByTagName('tr');
+            var arr = [];
+            for (var i = 0, length = tableLists.length; i < length; i++) {
+                arr.push(tableLists[i]);
+                var organizStateText = $(arr[i]).children('td').eq(1).text();
+                if (organizStateText == '展示') {
+                    $(arr[i]).children('td').eq(4).find('a').eq(1).hide();
+                } else if (organizStateText == '隐藏') {
+                    $(arr[i]).children('td').eq(4).find('a').eq(2).hide();
+                }
+
+
+            }
+
+        }
+
+        function addRow(list, tpl, data, pid, root) {
+            for (var i = 0; i < data.length; i++) {
+                var row = data[i];
+                if ((${fns:jsGetVal('row.parentId')}) == pid) {
+                    $(list).append(Mustache.render(tpl, {
+                        dict: {
+                            display: getDictLabel(${fns:toJson(fns:getDictList('category_display'))}, row.display)
+                        },
+                        pid: (root ? 0 : pid),
+                        row: row,
+                        isCateLevel : row.cateLevel != "3" ? true : false,
+                        isNotTopNode : row.id != "1" ? true :false,
+                        isTopNode : row.id == "1" ? true :false
+                    }));
+                    addRow(list, tpl, data, row.id);
+                }
+            }
+        }
+
+        function openDialogres(title, url, width, height, level,target) {
+            if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
+                width = 'auto';
+                height = 'auto';
+            } else {//如果是PC端,根据用户设置的width和height显示。
+
+            }
+            top.layer.open({
+                type: 2,
+                area: [width, height],
+                title: title,
+                skin: 'three-btns',
+                maxmin: true, //开启最大化最小化按钮
+                content: url,
+                btn: ['提交', '关闭'],
+                yes: function (index, layero) {
+                    // var body = top.layer.getChildFrame('body', index);
+                    var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                    // var inputForm = body.find('#inputForm');
+                    // var top_iframe;
+                    // if (target) {
+                    //     top_iframe = target;//如果指定了iframe,则在改frame中跳转
+                    // } else {
+                    //     top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+                    // }
+                    // inputForm.attr("target", top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+                    if (iframeWin.contentWindow.doSubmit(1)) {
+                        //top.layer.close(index);//关闭对话框。
+                        setTimeout(function () {
+                            top.layer.close(index)
+                            setTimeout(function () {
+                            window.location.reload();
+                            if(window.parent.refreshTree){
+                                window.parent.refreshTree();
+                            }
+                            }, 200);//延时0.1秒,对应360 7.1版本bug
+                        }, 200);//延时0.1秒,对应360 7.1版本bug
+                    }
+                },
+                no: function (index) {
+                }
+            });
+        }
+
+        function deleteInfo(title,id) {
+            layer.open({
+                title: title,
+                maxmin: true, //开启最大化最小化按钮
+                content: '<span style="color:#333">确认要删除此分类吗?</span>',
+                skin: 'two-btns',
+                btn: ['确定', '取消'],
+                btn1: function(index, layero){
+                    $.ajax({
+                        type:"post",
+                        url:"${ctx}/official/category/delete?id="+ id,
+                        success:function(data){
+                            if(data.success) {
+                                parent.layer.msg('删除成功', {icon: 1});
+                                // 当前项被删除,需要重置查询
+                                resetSearch()
+                                   // 如果是通过iframe删除的,就触发父页面的刷新左侧树的方法
+                                   if(window.parent.refreshTree){
+                                       window.parent.refreshTree();
+                                   }
+                            }else {
+                                parent.layer.msg('删除失败', {icon: 0});
+                            }
+                        }
+                    })
+
+                },
+                btn2: function (index) {
+                }
+            });
+        }
+
+        function refresh() {//刷新或者排序,页码不清零
+
+            window.location = "${ctx}/official/category/list";
+        }
+    </script>
+    <style>
+        body {
+            background-color: transparent;
+            filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#26FFFFFF, endColorstr=#26FFFFFF);
+            background-color: rgba(255, 255, 255, 0);
+            height: 100%;
+        }
+    </style>
+</head>
+<body>
+<div class="wrapper wrapper-content">
+    <sys:message content="${message}"/>
+    <div class="layui-row">
+        <div class="full-width fl">
+            <div class="contentShadow layui-row" id="queryDiv">
+                <form:form id="searchForm" modelAttribute="officialCategory" action="${ctx}/official/category/list"
+                           method="post" class="form-inline">
+                    <input id="toflag" name="toflag" type="hidden" value="1"/>
+                    <div class="commonQuery">
+                        <div class="layui-item query athird">
+                            <label class="layui-form-label">分类名称:</label>
+                            <div class="layui-input-block with-icon">
+                                <form:input  path="name" class=" form-control layui-input"></form:input>
+                            </div>
+                        </div>
+                        <div class="layui-item athird">
+                            <div class="input-group" style="width: auto">
+                                <div class="layui-btn-group search-spacing">
+                                    <button id="searchQuery" class="layui-btn layui-btn-sm layui-bg-blue"
+                                            onclick="search()">查询
+                                    </button>
+                                    <button id="searchReset" class="layui-btn layui-btn-sm " onclick="resetSearch()">
+                                        重置
+                                    </button>
+                                </div>
+                                    <%--								<button id="searchReset" style="margin-right: 10px;" class="fixed-btn searchReset fr" onclick="resetSearch()">重置</button>--%>
+                                    <%--								<button id="searchQuery" class="fixed-btn searchQuery fr" onclick="search()">查询</button>--%>
+                            </div>
+                        </div>
+                        <div style="    clear:both;"></div>
+                    </div>
+                </form:form>
+            </div>
+        </div>
+        <div class="contentShadow shadowT full-width fl" style="margin-top: 0px;">
+            <div class="layui-form contentDetails">
+                <div class="nav-btns">
+                    <div class="layui-btn-group">
+                        <button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left"
+                                onclick="sortOrRefresh()" title="刷新"> 刷新
+                        </button>
+                    </div>
+                    <%--<shiro:hasPermission name="sys:office:add">
+                        <table:addRow url="${ctx}/sys/office/form?parent.id=${office.id}" title="机构" target=""></table:addRow><!-- 增加按钮 -->
+                    </shiro:hasPermission>--%>
+                    <%--					<button class="nav-btn nav-btn-refresh" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"><i class="glyphicon glyphicon-repeat"></i>&nbsp;刷新</button>--%>
+                    <div style="clear: both;"></div>
+                </div>
+
+                <table id="treeTable"
+                       class="table table-striped table-bordered table-hover table-condensed dataTables-example dataTable">
+                    <thead>
+                    <tr>
+                        <th>分类名称</th>
+                        <th>是否展示</th>
+                        <th>排序</th>
+                        <%--                        <th>创建人</th>--%>
+                        <th>创建时间</th>
+                        <shiro:hasPermission name="official:category:edit">
+                            <th width="330">操作</th>
+                        </shiro:hasPermission></tr>
+                    </thead>
+                    <tbody id="treeTableList"></tbody>
+                </table>
+                <script type="text/template" id="treeTableTpl">
+                    <tr id="{{row.id}}" pId="{{pid}}">
+                        <td style="text-align: center"><a class="attention-info" href="javascript:void(0)"
+                               onclick="openDialogView('查看分类', '${ctx}/official/category/form?id={{row.id}}&&view=view','95%','95%')">{{row.name}}</a>
+                        </td>
+                        <td  style="text-align: center">{{dict.display}}</td>
+                        <td  style="text-align: center">{{row.sort}}</td>
+                        <%--                        <td>{{row.createBy.name}}</td>--%>
+                        <td  style="text-align: center">{{row.createDate}}</td>
+                        <%--<td>禁用</td>--%>
+                        <td class="op-td text-center">
+                            <div class="op-btn-box">
+                                <div class="layui-btn-group">
+                                    {{#isNotTopNode}}
+                                        <shiro:hasPermission name="official:category:edit">
+                                            <a href="javascript:void(0)"
+                                               onclick="openDialogres('修改分类', '${ctx}/official/category/form?id={{row.id}}&cateLevel={{row.cateLevel}}','95%','95%', '')"
+                                               class="layui-btn layui-btn-xs layui-bg-green"> 修改</a>
+                                            <a href="${ctx}/official/category/deleteDisplay?id={{row.id}}&display=1"
+                                               onclick="return confirmx('要展示该分类及所有子分类项吗?', this.href)"
+                                               class="layui-btn layui-btn-xs layui-bg-orange"> 展示</a>
+                                        </shiro:hasPermission>
+                                        <shiro:hasPermission name="official:category:del">
+                                            <a href="${ctx}/official/category/deleteDisplay?id={{row.id}}&display=0"
+                                               onclick="return confirmx('要隐藏该分类及所有子项吗?', this.href)"
+                                               class="layui-btn layui-btn-xs layui-bg-orange">隐藏</a>
+                                            <a href="javascript:void(0)"
+                                               onclick="deleteInfo('删除', '{{row.id}}')"
+                                               class="layui-btn layui-btn-xs layui-bg-red">删除</a>
+                                        </shiro:hasPermission>
+                                    {{/isNotTopNode}}
+
+                                    {{#isCateLevel}}
+                                        <shiro:hasPermission name="official:category:add">
+                                            <a href="javascript:void(0)"
+                                               onclick="addSonNode('{{row.id}}','{{row.name}}','{{row.cateLevel}}');"
+                                               class="layui-btn layui-btn-xs layui-bg-blue">添加下级分类</a>
+                                        </shiro:hasPermission>
+                                    {{/isCateLevel}}
+                                </div>
+                            </div>
+                        </td>
+                    </tr>
+                </script>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+
+    resizeListWindow3();
+    $(window).resize(function () {
+        resizeListWindow3();
+    });
+
+    function addSonNode(rowId, name,cateLevel) {
+        openDialogres('添加下级分类', '${ctx}/official/category/form?parentId=' + rowId + '&parentName=' + name+ '&cateLevel=' + cateLevel +'&add=add', '95%', '95%', cateLevel, '');
+        return;
+    }
+
+
+</script>
+</body>
+</html>

+ 191 - 0
src/main/webapp/webpage/modules/official/officialCategoryView.jsp

@@ -0,0 +1,191 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+<html>
+<head>
+    <title>分类管理</title>
+    <meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <style>
+        label.error {
+            left: 0;
+            top: 40px;
+        }
+    </style>
+    <script type="text/javascript">
+        var validateForm;
+
+        function doSubmit() {//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if (validateForm.form()) {
+                $("#inputForm").submit();
+                return true;
+            }
+
+            return false;
+        }
+
+        $(document).ready(function () {
+            layui.use(['form', 'layer'], function () {
+                var form = layui.form;
+            });
+            jQuery.validator.addMethod("isMobile", function (value, element) {
+                var length = value.length;
+                var mobile = /^(13[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})|(14[0-9]{9})|(17[0-9]{9})|(15[0-9]{9})$/;
+                return (length == 0 || (length == 11 && mobile.test(value)));
+            }, "请正确填写您的手机号码");
+            $("#name").focus();
+            validateForm = $("#inputForm").validate({
+                submitHandler: function (form) {
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                /*rules: {
+                    name:{remote: "${ctx}/sys/company/validateCompany?oldName=" + encodeURIComponent("${office.name}")}
+                },
+                messages: {
+                    name:{remote: "此公司名称已经被注册!", required: "公司名称不能为空."}
+                },*/
+                errorContainer: "#messageBox",
+                errorPlacement: function (error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+
+            /*if('
+
+            ${sessionScope.state}' =='disabled'){
+                $('select').attr('disabled','
+
+            <%=session.getAttribute("state")%>');
+            }else if('
+
+            ${sessionScope.state}' !='disabled'){
+                $('select').removeAttr('disabled');
+            }*/
+            setCompInfo($("#officeId").val());
+            dispSimpleName('${office.type}');
+        });
+
+        function setCompInfo(comId) {
+            $.ajax({
+                type: 'post',
+                url: '${ctx}/sys/office/compInfo',
+                data: {
+                    "id": comId
+                },
+                success: function (data) {
+                    if (data.type == "2") {
+                        $("#type option[value='1']").hide();
+                        $("#type option[value='2']").show();
+                        $("#type option[value='3']").hide();
+                    } else if (data.type == "3") {
+                        $("#type option[value='1']").hide();
+                        $("#type option[value='2']").show();
+                        $("#type option[value='3']").show();
+                    } else {
+                        $("#type option[value='1']").hide();
+                        $("#type option[value='2']").show();
+                        $("#type option[value='3']").show();
+                    }
+                }
+            })
+        }
+
+        function dispSimpleName(val) {
+            /*if(val=='1'){
+                $(".simpleName").show();
+            }else {
+                $(".simpleName").hide();
+            }*/
+        }
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <form:form id="inputForm" modelAttribute="officialCategory" action="${ctx}/official/category/save" method="post"
+                   class="form-horizontal layui-form">
+            <form:hidden path="id"/>
+            <sys:message content="${message}"/>
+            <input type="hidden" id="sign"/>
+            <c:set var="officedis" scope="session" value='<%=session.getAttribute("state")%>'/>
+            <c:set var="cnmae" scope="session" value='<%=session.getAttribute("cname")%>'/>
+
+            <div class="form-group layui-row first">
+                <div class="form-group-label"><h2>分类信息</h2></div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label"><span class="require-item">*</span>上级分类:</label>
+                    <div class="layui-input-block with-icon">
+                        <input placeholder="请选择上级分类" htmlEscape="false" readonly="true"
+                               class="form-control layui-input" value="${officialCategory.parentName}"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label"><span class="require-item">*</span>分类名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="name" readonly="true" placeholder="分类名称" htmlEscape="false" maxlength="50"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label"><span class="require-item">*</span>是否展示:</label>
+                    <div class="layui-input-block">
+                        <c:forEach var="item" items="${fns:getDictList('category_display')}">
+                            <input disabled="true" type="radio" name="display" value="${item.value}" title="${item.label}"
+                                   <c:if test="${item.value == officialCategory.display}">checked</c:if>>
+                        </c:forEach>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6">
+                    <label class="layui-form-label"><span class="require-item">*</span>排序:</label>
+                    <div class="layui-input-block">
+                        <form:input readonly="true" path="sort" placeholder="排序" htmlEscape="false" maxlength="50"
+                                    class="form-control number layui-input required"/>
+                    </div>
+                </div>
+                <c:choose>
+                    <c:when test="${officialCategory.cateLevel >= 2 && officialCategory.parentId != '1'}">
+                        <!-- cateLevel >= 3 的情况 -->
+                        <div class="layui-item layui-col-sm6">
+                            <label class="layui-form-label"><span class="require-item">*</span>内容类型:</label>
+                            <div class="layui-input-block">
+                                <c:forEach var="item" items="${fns:getDictList('content_type')}">
+                                    <input disabled="true" type="radio" name="contentType" value="${item.value}" title="${item.label}"
+                                           <c:if test="${item.value == officialCategory.contentType}">checked</c:if>>
+                                </c:forEach>
+                            </div>
+                        </div>
+                    </c:when>
+                    <c:otherwise>
+                        <form:hidden path="contentType"/>
+                    </c:otherwise>
+                </c:choose>
+                <div class="layui-item layui-col-sm12 with-textarea">
+                    <label class="layui-form-label">备注:</label>
+                    <div class="layui-input-block">
+                        <form:textarea path="remarks"
+                                       disabled="true"
+                                       htmlEscape="false"
+                                       rows="3"
+                                       maxlength="200"
+                                       class="form-control"
+                                       readonly="readonly"
+                                       placeholder="" />
+                    </div>
+                </div>
+            </div>
+
+        </form:form>
+    </div>
+</div>
+</body>
+<%
+    session.removeAttribute("state");
+    session.removeAttribute("cname");
+%>
+</html>

+ 121 - 0
src/main/webapp/webpage/modules/official/officialIndex.jsp

@@ -0,0 +1,121 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+<html>
+<head>
+    <title>详情管理</title>
+    <meta name="decorator" content="default"/>
+    <%@include file="/webpage/include/treeview.jsp" %>
+    <style type="text/css">
+        .ztree {
+            overflow: auto;
+            margin: 0;
+            _margin-top: 10px;
+            padding: 10px 0 0 10px;
+        }
+    </style>
+    <script type="text/javascript">
+        function refresh() {//刷新
+
+            window.location = "${ctx}/official/info/";
+        }
+    </script>
+    <style>
+        body {
+            background-color: transparent;
+            filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#26FFFFFF, endColorstr=#26FFFFFF);
+            color: #ffffff;
+            background-color: rgba(255, 255, 255, 0);
+            height: 100%;
+        }
+    </style>
+</head>
+<body>
+<div class="wrapper wrapper-content full-width" id="divId">
+    <sys:message content="${message}"/>
+    <div id="content" class="pr full-height full-width">
+
+        <div id="left" class="contentShadow fl contents">
+            <div class="ztreeContainer">
+                <div id="ztree" class="ztree leftBox-content"></div>
+            </div>
+        </div>
+
+
+        <div id="right" class="fl contents">
+            <div class="layui-row contentShadow full-height tran-bg">
+                <iframe id="cateContent" name="cateContent" src="${ctx}/official/category/list" width="100%"
+                        height="100%" frameborder="0"></iframe>
+            </div>
+        </div>
+    </div>
+</div>
+<script type="text/javascript">
+    function addDiyDom(treeId, treeNode) {
+        var spaceWidth = 15;
+        var switchObj = $("#" + treeNode.tId + "_switch"),
+            icoObj = $("#" + treeNode.tId + "_ico");
+        switchObj.remove();
+        icoObj.before(switchObj);
+
+        if (treeNode.level > 0) {
+            var spaceStr = "<span style='display: inline-block;width:" + (spaceWidth * treeNode.level) + "px'></span>";
+            switchObj.before(spaceStr);
+        }
+    }
+
+
+    var setting = {
+        data: {simpleData: {enable: true, idKey: "id", pIdKey: "pId", rootPId: '1'}},
+        callback: {
+            onClick: function (event, treeId, treeNode) {
+                var id = treeNode.id == '1' ? '' : treeNode.id;
+                var look = treeNode.look;
+                var type = treeNode.contentType
+                var level = treeNode.cateLevel
+                if (level < 3) {
+                    if(treeNode.id == 1){
+                        $('#cateContent').attr("src", "${ctx}/official/category/list");
+                    }else{
+                        $('#cateContent').attr("src", "${ctx}/official/category/list?name=" + encodeURI(treeNode.name)+"&id="+treeNode.id);
+                    }
+                } else {
+                    $('#cateContent').attr("src", "${ctx}/official/info/infoList?cateId=" + id + "&look=" + look + "&name=" + encodeURI(treeNode.name));
+                }
+            }
+        }
+        , view: {
+            showLine: false,
+            showIcon: false,
+            addDiyDom: addDiyDom
+        }
+    };
+
+    function refreshTree() {
+        $.getJSON("${ctx}/official/info/treeData?" + Math.random(), function (data) {
+            $.fn.zTree.init($("#ztree"), setting, data).expandAll(true);
+            openSubChilds();
+        });
+    }
+
+    refreshTree();
+
+    function openSubChilds() {
+        var secondLevel = $('#ztree').children().children().eq(1).children();
+        var slists = secondLevel.find('a.level1').find('.level1');
+
+        for (var i = 0; i < slists.length; i++) {
+            var node = $(slists[i]);
+
+            // 显示当前 level1 节点的下一个兄弟节点(也就是子 ul)
+            node.parent().next().css('display', 'block');
+
+            // 修改图标样式为展开状态
+            node.removeClass("noline_close").addClass("noline_open");
+        }
+    }
+
+
+
+</script>
+</body>
+</html>

+ 329 - 0
src/main/webapp/webpage/modules/official/officialInfo.jsp

@@ -0,0 +1,329 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+<html>
+<head>
+    <title>分类详情管理</title>
+    <meta name="decorator" content="default"/>
+    <style>
+        body {
+            background-color: transparent;
+            filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#26FFFFFF, endColorstr=#26FFFFFF);
+            color: #ffffff;
+            background-color: rgba(255, 255, 255, 0);
+            height: 100%;
+        }
+
+    </style>
+    <script src="${ctxStatic}/layer-v2.3/layui/layui.all.js" charset="utf-8"></script>
+    <script type="text/javascript">
+        // 确认对话框
+        function confirmx(mess, href) {
+            top.layer.confirm(mess, {icon: 3, title: '系统提示'}, function (index) {
+                //do something
+                if (typeof href == 'function') {
+                    href();
+                } else {
+                    resetTip(); //loading();
+                    $.ajax({
+                        url: href,
+                        data: $('#loginForm').serialize(),
+                        type: "post",
+                        success: function (data) {
+                            if (data.success) {
+                                parent.layer.msg(data.msg, {icon: 1});
+                            } else {
+                                parent.layer.msg(data.msg, {icon: 2});
+                            }
+                            parent.refreshTree();
+                            location = "${ctx}/official/info/infoList?cateId=${officialInfo.cateId}";
+                        }
+                    });
+                }
+                top.layer.close(index);
+            });
+            return false;
+        }
+
+
+        function openInfoDialog(title,url,width,height,cateId,isNew,target) {
+            if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
+                width = 'auto';
+                height = 'auto';
+            }
+
+            if(isNew){
+                $.ajax({
+                    url: '${ctx}/official/info/isContentType?cateId='+cateId,  // 替换为你的后台请求地址
+                    method: 'get',          // 或 'POST',根据实际情况
+                    dataType: 'json',
+                    success: function (response) {
+                        if (response.success) {
+                            top.layer.open({
+                                type: 2,
+                                area: [width, height],
+                                title: title,
+                                maxmin: true, //开启最大化最小化按钮
+                                content: url,
+                                skin: 'two-btns',
+                                btn: ['确定', '关闭'],
+                                btn1: function(index, layero){
+                                    var body = top.layer.getChildFrame('body', index);
+                                    var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                                    var inputForm = body.find('#inputForm');
+                                    var top_iframe;
+                                    // if(target){
+                                    //     top_iframe = target;//如果指定了iframe,则在改frame中跳转
+                                    // }else{
+                                    //     top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+                                    // }
+                                    // inputForm.attr("target",top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+
+                                    if(iframeWin.contentWindow.doSubmit() ){
+                                        setTimeout(function(){
+                                            top.layer.close(index)
+                                            window.location.reload();
+                                        }, 100);//延时0.1秒,对应360 7.1版本bug
+                                    }
+                                },
+                                btn2: function (index) {
+                                }
+                            });
+                        }else{
+                            top.layer.alert("当前分类为单内容,无法添加多条数据", {title: "提示", area: '300px'});
+                        }
+                    }
+                })
+            }else{
+                top.layer.open({
+                    type: 2,
+                    area: [width, height],
+                    title: title,
+                    maxmin: true, //开启最大化最小化按钮
+                    content: url,
+                    skin: 'two-btns',
+                    btn: ['确定', '关闭'],
+                    btn1: function(index, layero){
+                        var body = top.layer.getChildFrame('body', index);
+                        var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                        var inputForm = body.find('#inputForm');
+                        var top_iframe;
+                        if(iframeWin.contentWindow.doSubmit() ){
+                            setTimeout(function(){
+                                top.layer.close(index)
+                                setTimeout(function(){
+                                    window.location.reload();
+                                },200)
+                            }, 200);//延时0.1秒,对应360 7.1版本bug
+                        }
+                    },
+                    btn2: function (index) {
+                    }
+                });
+            }
+
+        }
+
+        function deleteInfo(title,id,cateId) {
+            layer.open({
+                title: title,
+                maxmin: true, //开启最大化最小化按钮
+                content: '<span style="color:#333">确认要删除此条数据吗?</span>',
+                skin: 'two-btns',
+                btn: ['确定', '取消'],
+                btn1: function(index, layero){
+                    $.ajax({
+                        type:"post",
+                        url:"${ctx}/official/info/delete?id="+ id+"&cateId=cateId",
+                        success:function(data){
+                            if(data.success) {
+                                parent.layer.msg('删除成功', {icon: 1});
+                                window.location.reload();
+                            }else {
+                                parent.layer.msg('删除失败', {icon: 0});
+                            }
+                        }
+                    })
+
+                },
+                btn2: function (index) {
+                }
+            });
+        }
+    </script>
+</head>
+<body>
+<div class="wrapper wrapper-content">
+    <sys:message content="${message}"/>
+    <div class="layui-row">
+        <div class="full-width fl">
+            <div class="contentShadow shadowB layui-row" id="queryDiv">
+                <form:form id="searchForm" modelAttribute="officialInfo"
+                           action="${ctx}/official/info/infoList?cateId=${officialInfo.cateId}" method="post"
+                           class="form-inline">
+                    <input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}"/>
+                    <input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
+                    <table:sortColumn id="orderBy" name="orderBy" value="${page.orderBy}"
+                                      callback="sortOrRefresh();"/><!-- 支持排序 -->
+
+                    <div class="commonQuery">
+                        <div class="layui-item query athird">
+                            <label class="layui-form-label">标题:</label>
+                            <div class="layui-input-block with-icon">
+                                <form:input path="title" value="${officialInfo.title}" htmlEscape="false" maxlength="64"
+                                            class=" form-control layui-input"/>
+                            </div>
+                        </div>
+                        <div class="layui-item query athird">
+                            <label class="layui-form-label">是否有效:</label>
+                            <div class="layui-input-block with-icon">
+                                <form:select path="isUsable" class="form-control required simple-select"
+                                             onchange="dispSimpleName(this.value);">
+                                    <form:option value="" label=""/>
+                                    <form:options items="${fns:getDictList('is_usable')}" itemLabel="label"
+                                                  itemValue="value" htmlEscape="false"/>
+                                </form:select></div>
+                        </div>
+                        <div class="layui-item query athird">
+                            <label class="layui-form-label">关键词:</label>
+                            <div class="layui-input-block with-icon">
+                                <form:input path="keyword" value="${officialInfo.keyword}" htmlEscape="false"
+                                            maxlength="64" class=" form-control layui-input"/>
+                            </div>
+                        </div>
+                        <div class="layui-item athird fr">
+                            <div class="input-group">
+                                <div class="layui-btn-group search-spacing">
+                                    <button id="searchQuery" class="layui-btn layui-btn-sm layui-bg-blue"
+                                            onclick="search()">查询
+                                    </button>
+                                    <button id="searchReset" class="layui-btn layui-btn-sm " onclick="resetSearch()">
+                                        重置
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </form:form>
+            </div>
+        </div>
+
+        <div class="contentShadow shadowT full-width fl">
+            <div class="layui-form contentDetails">
+                <div class="nav-btns">
+                    <div class="layui-btn-group" style="">
+                        <shiro:hasPermission name="official:info:add">
+                            <button class="layui-btn layui-btn-sm layui-bg-blue"
+                                    data-toggle="tooltip"
+                                    data-placement="left"
+                                    onclick="openInfoDialog(
+                                            '添加分类详情',
+                                            '${ctx}/official/info/form?cateId=${officialInfo.cateId}',
+                                            '95%',
+                                            '95%',
+                                            '${officialInfo.cateId}',
+                                            true
+                                            )"
+                                    title="添加">
+                                添加
+                            </button>
+                        </shiro:hasPermission>
+
+
+                        <button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left"
+                                onclick="sortOrRefresh()" title="刷新"> 刷新
+                        </button>
+                    </div>
+                    <div style="clear: both;"></div>
+                </div>
+                <table class="oa-table layui-table" id="contentTable"></table>
+
+                <!-- 分页代码 -->
+                <table:page page="${page}"></table:page>
+                <div style="clear: both;"></div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="${ctxStatic}/layer-v2.3/layui/layui.all.js" charset="utf-8"></script>
+<script>
+    layui.use('table', function () {
+        layui.table.render({
+            limit:${ page.pageSize }
+            , elem: '#contentTable'
+            , page: false
+            , cols: [[
+                // {checkbox: true, fixed: true},
+                {field: 'index', align: 'center', width: 40, title: '序号'}
+                , {
+                    field: 'title', align: 'center', title: '标题', templet: function (d) {
+                        var xml = "<a class=\"attention-info\" href=\"javascript:void(0)\" onclick=\"openDialogView('查看详情', '${ctx}/official/info/form?id=" + d.id + "&cateId=" + d.cateId + "&view=view','95%','95%')\">" +
+                            "<span title=" + d.title + ">" + d.title + "</span></a>";
+                        return xml;
+                    }
+                }
+                , {
+                    field: 'contentType', align: 'center', title: '内容类型', minWidth: 100, templet: function (d) {
+                        return "<span title='" + d.contentType + "'>" + d.contentType + "</span>";
+                    }
+                }
+                , {
+                    field: 'isUsable', align: 'center', title: '是否有效', minWidth: 100, templet: function (d) {
+                        return "<span title='" + d.isUsable + "'>" + d.isUsable + "</span>";
+                    }
+                }
+                , {field: 'createBy', align: 'center', title: '创建人'}
+                , {field: 'createDate', align: 'center', title: '创建时间'}
+                , {field: 'sort', align: 'center', title: '排序', width: 160}
+                , {
+                    field: 'op', align: 'center', title: "操作", width: 200, templet: function (d) {
+                        ////对操作进行初始化
+                        var xml = "<div class=\"layui-btn-group\">";
+                        if (d.candelete1 != undefined && d.candelete1 == "1")
+                            xml += "<a href=\"javascript:void(0)\" onclick=\"openInfoDialog('修改详情', '${ctx}/official/info/form?id=" + d.id + "&cateId=" + d.cateId + "','95%','95%',false)\" class=\"layui-btn layui-btn-xs layui-bg-green\" > 修改</a>";
+                        if (d.candelete2 != undefined && d.candelete2 == "1")
+                            xml += "<a  href=\"javascript:void(0)\" onclick=\"deleteInfo('删除',  '"+d.id+"',  '"+d.cateId+"')\"   class=\"layui-btn layui-btn-xs layui-bg-red\"> 删除</a>";
+                        xml += "</div>";
+                        return xml;
+                    }
+                }
+            ]]
+            , data: [
+                <c:if test="${ not empty page.list}">
+                <c:forEach items="${page.list}" var="officialInfoItem" varStatus="index">
+                <c:if test="${index.index != 0}">, </c:if>
+                {
+                    "index": "${index.index+1}"
+                    , "id": "${officialInfoItem.id}"
+                    , "title": "${officialInfoItem.title}"
+                    , "contentType": "${fns:getDictLabel(officialInfoItem.contentType, 'content_type', '')}"
+                    , "isUsable": "${fns:getDictLabel(officialInfoItem.isUsable, 'is_usable', '')}"
+                    , "createBy": "${officialInfoItem.createBy.name}"
+                    , "createDate": "<fmt:formatDate value="${officialInfoItem.createDate}" pattern="yyyy-MM-dd HH:mm:ss"/>"
+                    , "sort": "${officialInfoItem.sort}"
+                    , "cateId": "${officialInfoItem.cateId}"
+                    <shiro:hasPermission name="official:info:edit">
+                    , "candelete1": "1"
+                    </shiro:hasPermission>
+                    <shiro:hasPermission name="official:info:del">
+                    , "candelete2": "1"
+                    </shiro:hasPermission>
+
+                }
+                </c:forEach>
+                </c:if>
+            ]
+            // ,even: true
+            // ,height: 315
+        });
+    })
+    resizeListTable();
+</script>
+<script>
+    $("a").on("click", addLinkVisied);
+    resizeListWindow3();
+    $(window).resize(function () {
+        resizeListWindow3();
+    });
+</script>
+</body>
+</html>

+ 375 - 0
src/main/webapp/webpage/modules/official/officialInfoForm.jsp

@@ -0,0 +1,375 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+
+<html>
+<head>
+    <title>业务提问管理</title>
+    <meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/iCheck/icheck.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <script src="${ctxStatic}/common/html/js/script.js"></script>
+
+    <link rel='stylesheet' type="text/css"
+          href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+
+    <script type="text/javascript">
+        var validateForm;
+        var isMasterClient = true;//是否是委托方
+        var clientCount = 0;
+
+        function doSubmit(i) {//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if (validateForm.form()) {
+                $("#inputForm").submit();
+                return true;
+            }
+
+            return false;
+        }
+
+        $(document).ready(function () {
+            layui.use(['form', 'layer'], function () {
+                var form = layui.form;
+
+            });
+            validateForm = $("#inputForm").validate({
+                submitHandler: function (form) {
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function (error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+
+            $("#attachment_btn").click(function () {
+                $("#attachment_file").click();
+            });
+        });
+
+
+        function insertTitle(tValue) {
+            var files = $("#attachment_file")[0].files;
+            for (var i = 0; i < files.length; i++) {
+                var file = files[i];
+                var attachmentId = "";
+                var attachmentFlag = "183";
+                var timestamp = new Date().getTime();
+
+                var storeAs = "officialInfo";
+                var uploadPath = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/" + storeAs;/*将这段字符串存到数据库即可*/
+                var divId = "_attachment";
+                $("#addFile" + divId).show();
+                multipartUploadWithSts(storeAs, file, attachmentId, attachmentFlag, uploadPath, divId, 0);
+            }
+        }
+
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <sys:message content="${message}"/>
+        <form:form id="inputForm" modelAttribute="officialInfo"
+                   action="${ctx}/official/info/save" method="post"
+                   class="form-horizontal layui-form">
+            <form:hidden path="id"/>
+            <form:hidden path="cateId"/>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>分类详情数据</h2></div>
+
+                <div class="layui-item layui-col-sm12 lw12">
+                    <label class="layui-form-label"><span class="require-item">*</span>分类名称:</label>
+                    <div class="layui-input-block" style="display: flex;align-items: center">
+                        <span>${officialCategory.name}</span>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>标题:</label>
+                    <div class="layui-input-block">
+                        <form:input path="title" placeholder="请输入标题" htmlEscape="false"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>关键词:</label>
+                    <div class="layui-input-block">
+                        <form:input path="keyword" placeholder="请输入关键词" htmlEscape="false"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label">排序:</label>
+                    <div class="layui-input-block">
+                        <form:input  type="number" path="sort" placeholder="请输入排序" htmlEscape="false"
+                                    class="form-control layui-input "/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>是否有效:</label>
+                    <div class="layui-input-block">
+                        <c:forEach var="item" items="${fns:getDictList('is_usable')}">
+                            <input type="radio" name="isUsable" value="${item.value}" title="${item.label}"
+                                   <c:if test="${item.value == officialInfo.isUsable}">checked</c:if>>
+                        </c:forEach>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm12" style="padding-bottom: 20px;">
+                    <label class="layui-form-label">发布内容:</label>
+                    <div class="layui-input-block">
+                        <form:textarea path="content" htmlEscape="false" colspan="3" rows="6" maxlength="550"
+                                       class="form-control "/>
+                        <sys:ckeditor replace="content" uploadPath="/oa/oa"/>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>附件上传</h2></div>
+                    <div class="layui-item nav-btns">
+                        <a id="attachment_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>
+                            <%--<sys:collectSelect  id="linkman" url="${ctx}/workclientinfo/workClientInfo/linkmanList"
+                                                name="linkman.id"  title="选择资料库"
+                                                cssClass="form-control judgment" fieldLabels="资料库" fieldKeys="name"
+                                                searchLabel="资料库" searchKey="fileName"></sys:collectSelect>--%>
+                    </div>
+                    <div id="addFile_attachment" style="display: none" class="upload-progress">
+                        <span id="fileName_attachment"></span>
+                        <b><span id="baifenbi_attachment"></span></b>
+                        <div class="progress">
+                            <div id="jindutiao_attachment" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                            </div>
+                        </div>
+                    </div>
+                    <input id="attachment_file" type="file" name="attachment_file" multiple="multiple"
+                           style="display: none;" onChange="if(this.value)insertTitle(this.value);"/>
+                    <span id="attachment_title"></span>
+                    <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                        <table id="listAttachment" class="table table-bordered table-condensed details">
+                            <thead>
+                            <tr>
+                                <!-- <th>序号</th> -->
+                                <th>文件预览</th>
+                                <th>上传人</th>
+                                <th>上传时间</th>
+                                <th width="200px">操作</th>
+                            </tr>
+                            </thead>
+                            <tbody id="file_attachment">
+                            <c:forEach items="${officialInfo.workAttachments}" var="workClientAttachment"
+                                       varStatus="status">
+                                <tr>
+                                        <%-- <td>${status.index + 1}</td>--%>
+                                    <c:choose>
+                                        <c:when test="${officialInfo.uploadMode == 2}">
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                    <td><img src="${workClientAttachment.temporaryUrl}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.temporaryUrl}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <c:choose>
+                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                            <td><a class="attention-info" href="javascript:void(0)"
+                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a>
+                                                            </td>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <c:choose>
+                                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'rar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
+                                                                    <td><a class="attention-info"
+                                                                           href="javascript:void(0)"
+                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a>
+                                                                    </td>
+                                                                </c:when>
+                                                                <c:otherwise>
+                                                                    <td><a class="attention-info"
+                                                                           href="javascript:void(0)"
+                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a>
+                                                                    </td>
+                                                                </c:otherwise>
+                                                            </c:choose>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:when>
+                                        <c:otherwise>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                    <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <c:choose>
+                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                            <td><a class="attention-info" href="javascript:void(0)"
+                                                                   onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a>
+                                                            </td>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <c:choose>
+                                                                <c:when test="${officialInfo.uploadMode == 2}">
+                                                                    <c:choose>
+                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                                            <td><img src="${workClientAttachment.temporaryUrl}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.temporaryUrl}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                                        </c:when>
+                                                                        <c:otherwise>
+                                                                            <c:choose>
+                                                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                                                    <td><a class="attention-info"
+                                                                                           href="javascript:void(0)"
+                                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a>
+                                                                                    </td>
+                                                                                </c:when>
+                                                                                <c:otherwise>
+                                                                                    <c:choose>
+                                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'rar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:when>
+                                                                                        <c:otherwise>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:otherwise>
+                                                                                    </c:choose>
+                                                                                </c:otherwise>
+                                                                            </c:choose>
+                                                                        </c:otherwise>
+                                                                    </c:choose>
+                                                                </c:when>
+                                                                <c:otherwise>
+                                                                    <c:choose>
+                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                                            <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                                        </c:when>
+                                                                        <c:otherwise>
+                                                                            <c:choose>
+                                                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                                                    <td><a href="javascript:void(0)"
+                                                                                           onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a>
+                                                                                    </td>
+                                                                                </c:when>
+                                                                                <c:otherwise>
+                                                                                    <c:choose>
+                                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'rar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.url}',3)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:when>
+                                                                                        <c:otherwise>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.url}',2)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:otherwise>
+                                                                                    </c:choose>
+                                                                                </c:otherwise>
+                                                                            </c:choose>
+                                                                        </c:otherwise>
+                                                                    </c:choose>
+                                                                </c:otherwise>
+                                                            </c:choose>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:otherwise>
+                                    </c:choose>
+
+                                    <td>${workClientAttachment.createBy.name}</td>
+                                    <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <td class="op-td">
+                                        <div class="op-btn-box">
+                                                <%--附件下载删除--%>
+                                            <c:choose>
+                                                <c:when test="${officialInfo.uploadMode == 2}">
+                                                    <c:choose>
+                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                            <a href="${workClientAttachment.temporaryUrl}"
+                                                               target="_blank" class="op-btn op-btn-download"><i
+                                                                    class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <a href="${workClientAttachment.temporaryUrl}"
+                                                               class="op-btn op-btn-download"><i
+                                                                    class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent('${workClientAttachment.url}');"
+                                                       class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                </c:otherwise>
+                                            </c:choose>
+                                            <c:if test="${workClientAttachment.collectFlag != 1}">
+                                                <a href="javascript:void(0)"
+                                                   onclick="collectingAccessory(this,'${ctx}/projectAccessory/projectAccessory/saveCollectAccessory','${workClientAttachment.url}','${workClientAttachment.createBy.id}','${workClientAttachment.fileSize}')"
+                                                   class="op-btn op-btn-delete" style="background-color: #FFB800"><i
+                                                        class="layui-icon layui-icon-rate"></i>&nbsp;收藏</a>
+                                            </c:if>
+                                            <c:if test="${workClientAttachment.createBy.id eq fns:getUser().id}">
+                                                <a href="javascript:void(0)"
+                                                   onclick="deleteFileFromAliyun(this,'${ctx}/sys/workattachment/deleteFilesFromAliyun?url=${workClientAttachment.url}&id=${workClientAttachment.id}&type=2&fileName=${workClientAttachment.attachmentName}','addFile_attachment','_attachment')"
+                                                   class="op-btn op-btn-delete"><i
+                                                        class="fa fa-trash"></i>&nbsp;删除</a>
+                                            </c:if>
+
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:forEach>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row page-end"></div>
+        </form:form>
+    </div>
+</div>
+</body>
+</html>

+ 375 - 0
src/main/webapp/webpage/modules/official/officialInfoView.jsp

@@ -0,0 +1,375 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+
+<html>
+<head>
+    <title>业务提问管理</title>
+    <meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/iCheck/icheck.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <script src="${ctxStatic}/common/html/js/script.js"></script>
+
+    <link rel='stylesheet' type="text/css"
+          href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+
+    <script type="text/javascript">
+        var validateForm;
+        var isMasterClient = true;//是否是委托方
+        var clientCount = 0;
+
+        function doSubmit(i) {//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if (validateForm.form()) {
+                $("#inputForm").submit();
+                return true;
+            }
+
+            return false;
+        }
+
+        $(document).ready(function () {
+            layui.use(['form', 'layer'], function () {
+                var form = layui.form;
+
+            });
+            validateForm = $("#inputForm").validate({
+                submitHandler: function (form) {
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function (error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+
+            $("#attachment_btn").click(function () {
+                $("#attachment_file").click();
+            });
+        });
+
+
+        function insertTitle(tValue) {
+            var files = $("#attachment_file")[0].files;
+            for (var i = 0; i < files.length; i++) {
+                var file = files[i];
+                var attachmentId = "";
+                var attachmentFlag = "183";
+                var timestamp = new Date().getTime();
+
+                var storeAs = "officialInfo";
+                var uploadPath = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/" + storeAs;/*将这段字符串存到数据库即可*/
+                var divId = "_attachment";
+                $("#addFile" + divId).show();
+                multipartUploadWithSts(storeAs, file, attachmentId, attachmentFlag, uploadPath, divId, 0);
+            }
+        }
+
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <sys:message content="${message}"/>
+        <form:form id="inputForm" modelAttribute="officialInfo"
+                   action="${ctx}/official/info/save" method="post"
+                   class="form-horizontal layui-form">
+            <form:hidden path="id"/>
+            <form:hidden path="cateId"/>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>分类详情数据</h2></div>
+
+                <div class="layui-item layui-col-sm12 lw12">
+                    <label class="layui-form-label"><span class="require-item">*</span>分类名称:</label>
+                    <div class="layui-input-block" style="display: flex;align-items: center">
+                        <span>${officialCategory.name}</span>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>标题:</label>
+                    <div class="layui-input-block">
+                        <form:input disabled="true" path="title" placeholder="请输入标题" htmlEscape="false"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>关键词:</label>
+                    <div class="layui-input-block">
+                        <form:input disabled="true" path="keyword" placeholder="" htmlEscape="false"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>排序:</label>
+                    <div class="layui-input-block">
+                        <form:input  disabled="true" type="number" path="sort" placeholder="请输入排序" htmlEscape="false"
+                                     class="form-control layui-input required"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw6">
+                    <label class="layui-form-label"><span class="require-item">*</span>是否有效:</label>
+                    <div class="layui-input-block">
+                        <c:forEach  var="item" items="${fns:getDictList('is_usable')}">
+                            <input disabled="true" type="radio" name="isUsable" value="${item.value}" title="${item.label}"
+                                   <c:if test="${item.value == officialInfo.isUsable}">checked</c:if>>
+                        </c:forEach>
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm12" style="padding-bottom: 20px;">
+                    <label class="layui-form-label">发布内容:</label>
+                    <div class="layui-input-block">
+                        <form:textarea disabled="true" path="content" htmlEscape="false" colspan="3" rows="6" maxlength="550"
+                                       class="form-control "/>
+                        <sys:ckeditor replace="content" uploadPath="/oa/oa"/>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>附件上传</h2></div>
+                    <div class="layui-item nav-btns">
+<%--                        <a id="attachment_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>--%>
+                            <%--<sys:collectSelect  id="linkman" url="${ctx}/workclientinfo/workClientInfo/linkmanList"
+                                                name="linkman.id"  title="选择资料库"
+                                                cssClass="form-control judgment" fieldLabels="资料库" fieldKeys="name"
+                                                searchLabel="资料库" searchKey="fileName"></sys:collectSelect>--%>
+                    </div>
+                    <div id="addFile_attachment" style="display: none" class="upload-progress">
+                        <span id="fileName_attachment"></span>
+                        <b><span id="baifenbi_attachment"></span></b>
+                        <div class="progress">
+                            <div id="jindutiao_attachment" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                            </div>
+                        </div>
+                    </div>
+                    <input id="attachment_file" type="file" name="attachment_file" multiple="multiple"
+                           style="display: none;" onChange="if(this.value)insertTitle(this.value);"/>
+                    <span id="attachment_title"></span>
+                    <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                        <table id="listAttachment" class="table table-bordered table-condensed details">
+                            <thead>
+                            <tr>
+                                <!-- <th>序号</th> -->
+                                <th>文件预览</th>
+                                <th>上传人</th>
+                                <th>上传时间</th>
+                                <th width="200px">操作</th>
+                            </tr>
+                            </thead>
+                            <tbody id="file_attachment">
+                            <c:forEach items="${officialInfo.workAttachments}" var="workClientAttachment"
+                                       varStatus="status">
+                                <tr>
+                                        <%-- <td>${status.index + 1}</td>--%>
+                                    <c:choose>
+                                        <c:when test="${officialInfo.uploadMode == 2}">
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                    <td><img src="${workClientAttachment.temporaryUrl}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.temporaryUrl}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <c:choose>
+                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                            <td><a class="attention-info" href="javascript:void(0)"
+                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a>
+                                                            </td>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <c:choose>
+                                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'rar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
+                                                                    <td><a class="attention-info"
+                                                                           href="javascript:void(0)"
+                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a>
+                                                                    </td>
+                                                                </c:when>
+                                                                <c:otherwise>
+                                                                    <td><a class="attention-info"
+                                                                           href="javascript:void(0)"
+                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a>
+                                                                    </td>
+                                                                </c:otherwise>
+                                                            </c:choose>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:when>
+                                        <c:otherwise>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                    <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <c:choose>
+                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                            <td><a class="attention-info" href="javascript:void(0)"
+                                                                   onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a>
+                                                            </td>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <c:choose>
+                                                                <c:when test="${officialInfo.uploadMode == 2}">
+                                                                    <c:choose>
+                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                                            <td><img src="${workClientAttachment.temporaryUrl}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.temporaryUrl}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                                        </c:when>
+                                                                        <c:otherwise>
+                                                                            <c:choose>
+                                                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                                                    <td><a class="attention-info"
+                                                                                           href="javascript:void(0)"
+                                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a>
+                                                                                    </td>
+                                                                                </c:when>
+                                                                                <c:otherwise>
+                                                                                    <c:choose>
+                                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'rar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:when>
+                                                                                        <c:otherwise>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:otherwise>
+                                                                                    </c:choose>
+                                                                                </c:otherwise>
+                                                                            </c:choose>
+                                                                        </c:otherwise>
+                                                                    </c:choose>
+                                                                </c:when>
+                                                                <c:otherwise>
+                                                                    <c:choose>
+                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                   or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                                                            <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}">
+                                                                        </c:when>
+                                                                        <c:otherwise>
+                                                                            <c:choose>
+                                                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                                                    <td><a href="javascript:void(0)"
+                                                                                           onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a>
+                                                                                    </td>
+                                                                                </c:when>
+                                                                                <c:otherwise>
+                                                                                    <c:choose>
+                                                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'rar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
+                                                       or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.url}',3)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:when>
+                                                                                        <c:otherwise>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.url}',2)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
+                                                                                        </c:otherwise>
+                                                                                    </c:choose>
+                                                                                </c:otherwise>
+                                                                            </c:choose>
+                                                                        </c:otherwise>
+                                                                    </c:choose>
+                                                                </c:otherwise>
+                                                            </c:choose>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:otherwise>
+                                    </c:choose>
+
+                                    <td>${workClientAttachment.createBy.name}</td>
+                                    <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <td class="op-td">
+                                        <div class="op-btn-box">
+                                                <%--附件下载删除--%>
+                                            <c:choose>
+                                                <c:when test="${officialInfo.uploadMode == 2}">
+                                                    <c:choose>
+                                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                            <a href="${workClientAttachment.temporaryUrl}"
+                                                               target="_blank" class="op-btn op-btn-download"><i
+                                                                    class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <a href="${workClientAttachment.temporaryUrl}"
+                                                               class="op-btn op-btn-download"><i
+                                                                    class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent('${workClientAttachment.url}');"
+                                                       class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                </c:otherwise>
+                                            </c:choose>
+                                            <c:if test="${workClientAttachment.collectFlag != 1}">
+                                                <a href="javascript:void(0)"
+                                                   onclick="collectingAccessory(this,'${ctx}/projectAccessory/projectAccessory/saveCollectAccessory','${workClientAttachment.url}','${workClientAttachment.createBy.id}','${workClientAttachment.fileSize}')"
+                                                   class="op-btn op-btn-delete" style="background-color: #FFB800"><i
+                                                        class="layui-icon layui-icon-rate"></i>&nbsp;收藏</a>
+                                            </c:if>
+<%--                                            <c:if test="${workClientAttachment.createBy.id eq fns:getUser().id}">--%>
+<%--                                                <a href="javascript:void(0)"--%>
+<%--                                                   onclick="deleteFileFromAliyun(this,'${ctx}/sys/workattachment/deleteFilesFromAliyun?url=${workClientAttachment.url}&id=${workClientAttachment.id}&type=2&fileName=${workClientAttachment.attachmentName}','addFile_attachment','_attachment')"--%>
+<%--                                                   class="op-btn op-btn-delete"><i--%>
+<%--                                                        class="fa fa-trash"></i>&nbsp;删除</a>--%>
+<%--                                            </c:if>--%>
+
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:forEach>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row page-end"></div>
+        </form:form>
+    </div>
+</div>
+</body>
+</html>