Ver código fonte

首次提交

wuweihao 3 anos atrás
pai
commit
9752d43dce
44 arquivos alterados com 4282 adições e 0 exclusões
  1. 1 0
      remark.md
  2. 37 0
      src/main/java/com/fourdage/Application.java
  3. 41 0
      src/main/java/com/fourdage/ContextFinalizer.java
  4. 325 0
      src/main/java/com/fourdage/dingding/controller/ExaminationController.java
  5. 16 0
      src/main/java/com/fourdage/dingding/dao/IDepartmentDao.java
  6. 17 0
      src/main/java/com/fourdage/dingding/dao/IProcessCodeDao.java
  7. 95 0
      src/main/java/com/fourdage/dingding/entity/Department.java
  8. 91 0
      src/main/java/com/fourdage/dingding/entity/DingDingSearchBean.java
  9. 55 0
      src/main/java/com/fourdage/dingding/entity/FormComponentValue.java
  10. 99 0
      src/main/java/com/fourdage/dingding/entity/OperationRecords.java
  11. 122 0
      src/main/java/com/fourdage/dingding/entity/PdfVO.java
  12. 77 0
      src/main/java/com/fourdage/dingding/entity/ProcessCode.java
  13. 266 0
      src/main/java/com/fourdage/dingding/entity/ProcessInstance.java
  14. 54 0
      src/main/java/com/fourdage/dingding/entity/TaskTop.java
  15. 24 0
      src/main/java/com/fourdage/dingding/job/ScheduledJob.java
  16. 13 0
      src/main/java/com/fourdage/dingding/service/IDepartmentService.java
  17. 16 0
      src/main/java/com/fourdage/dingding/service/IProcessCodeService.java
  18. 35 0
      src/main/java/com/fourdage/dingding/service/impl/DepartmentServiceImpl.java
  19. 43 0
      src/main/java/com/fourdage/dingding/service/impl/ProcessCodeServiceImpl.java
  20. 240 0
      src/main/java/com/fourdage/dingding/util/DingDingUtil.java
  21. 88 0
      src/main/java/com/fourdage/dingding/util/FileUtil.java
  22. 454 0
      src/main/java/com/fourdage/dingding/util/HtmlPdfUtil.java
  23. 137 0
      src/main/java/com/fourdage/dingding/util/ZipUtil.java
  24. 133 0
      src/main/java/com/fourdage/dingding/util/ZipUtils.java
  25. 78 0
      src/main/java/com/fourdage/system/controller/DataDictionaryController.java
  26. 86 0
      src/main/java/com/fourdage/system/controller/ResourceController.java
  27. 88 0
      src/main/java/com/fourdage/system/controller/RoleController.java
  28. 127 0
      src/main/java/com/fourdage/system/controller/UserController.java
  29. 17 0
      src/main/java/com/fourdage/system/dao/IDataDictionaryDao.java
  30. 26 0
      src/main/java/com/fourdage/system/dao/IResourceDao.java
  31. 15 0
      src/main/java/com/fourdage/system/dao/IRoleDao.java
  32. 17 0
      src/main/java/com/fourdage/system/dao/IUserDao.java
  33. 112 0
      src/main/java/com/fourdage/system/entity/DataDictionary.java
  34. 207 0
      src/main/java/com/fourdage/system/entity/Resource.java
  35. 145 0
      src/main/java/com/fourdage/system/entity/Role.java
  36. 249 0
      src/main/java/com/fourdage/system/entity/User.java
  37. 46 0
      src/main/java/com/fourdage/system/service/IDataDictionaryService.java
  38. 46 0
      src/main/java/com/fourdage/system/service/IResourceService.java
  39. 43 0
      src/main/java/com/fourdage/system/service/IRoleService.java
  40. 61 0
      src/main/java/com/fourdage/system/service/IUserService.java
  41. 101 0
      src/main/java/com/fourdage/system/service/impl/DataDictionaryServiceImpl.java
  42. 112 0
      src/main/java/com/fourdage/system/service/impl/ResourceServiceImpl.java
  43. 101 0
      src/main/java/com/fourdage/system/service/impl/RoleServiceImpl.java
  44. 126 0
      src/main/java/com/fourdage/system/service/impl/UserServiceImpl.java

+ 1 - 0
remark.md

@@ -0,0 +1 @@
+# 钉钉-财务使用 2022-2-24

+ 37 - 0
src/main/java/com/fourdage/Application.java

@@ -0,0 +1,37 @@
+package com.fourdage;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * 登录
+ * http://localhost/admin/login
+ *
+ * admin
+ * 123456
+ *
+ */
+@SpringBootApplication
+@ComponentScan
+public class Application extends SpringBootServletInitializer {
+
+    private static Logger logger = LoggerFactory.getLogger(Application.class);
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(Application.class);
+    }
+
+    /**
+     */
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+        logger.debug("启动成功");
+    }
+
+}

+ 41 - 0
src/main/java/com/fourdage/ContextFinalizer.java

@@ -0,0 +1,41 @@
+package com.fourdage;
+
+import java.sql.*;
+import java.util.Enumeration;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mysql.jdbc.AbandonedConnectionCleanupThread;
+
+@WebListener
+public class ContextFinalizer implements ServletContextListener{
+	
+	private static final Logger LOGGER = LoggerFactory.getLogger(ContextFinalizer.class);
+
+	@Override
+	public void contextInitialized(ServletContextEvent sce) {
+		
+	}
+
+	@Override
+	public void contextDestroyed(ServletContextEvent sce) {
+		Enumeration<Driver> drivers = DriverManager.getDrivers();
+        Driver d = null;
+        while (drivers.hasMoreElements()) {
+            try {
+                d = drivers.nextElement();
+                DriverManager.deregisterDriver(d);
+                System.out.println(String.format("ContextFinalizer:Driver %s deregistered", d));
+            } catch (SQLException ex) {
+                System.out.println(String.format("ContextFinalizer:Error deregistering driver %s", d) + ":" + ex);
+            }
+        }
+        AbandonedConnectionCleanupThread.shutdown();
+	}
+
+}

+ 325 - 0
src/main/java/com/fourdage/dingding/controller/ExaminationController.java

@@ -0,0 +1,325 @@
+package com.fourdage.dingding.controller;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fourdage.base.common.JsonResult;
+import com.fourdage.base.controller.BaseController;
+import com.fourdage.dingding.entity.Department;
+import com.fourdage.dingding.entity.DingDingSearchBean;
+import com.fourdage.dingding.entity.ProcessCode;
+import com.fourdage.dingding.entity.ProcessInstance;
+import com.fourdage.dingding.service.IDepartmentService;
+import com.fourdage.dingding.service.IProcessCodeService;
+import com.fourdage.dingding.util.DingDingUtil;
+import com.fourdage.dingding.util.FileUtil;
+import com.fourdage.dingding.util.HtmlPdfUtil;
+import com.fourdage.dingding.util.ZipUtil;
+import com.fourdage.system.entity.DataDictionary;
+import com.fourdage.system.entity.User;
+import com.fourdage.system.service.IDataDictionaryService;
+
+@Controller
+@RequestMapping("/dingding/examination")
+public class ExaminationController extends BaseController{
+	
+	@Value("${web.pdf.file.path}")
+    private String path;
+	
+	private Logger logger = LoggerFactory.getLogger(getClass());
+	@Autowired
+	private IProcessCodeService processCodeService;
+	@Autowired
+	private HtmlPdfUtil htmlPdfUtil;
+	@Autowired
+	private DingDingUtil dingDingUtil;
+	@Autowired
+	private IDataDictionaryService dataDictionaryService;
+	
+    @RequestMapping("/index")
+    public String index(ModelMap map) {
+    	String region = dingDingUtil.getRegion();
+    	
+    	List<ProcessCode> processes = processCodeService.findByRegion(region);
+    	List<DataDictionary> companys = dataDictionaryService.findByCode("company");
+    	map.put("process", processes);
+    	map.put("companys", companys);
+		return "dingding/examination/index";
+    }
+    
+	@RequestMapping(value = {"/list"}, method = RequestMethod.GET)
+	@ResponseBody
+	public Map<String, Object> list(String datetime, String applyDate, String processCodeId, String businessNum, String companyId){
+		
+		Map<String, Object> result = new HashMap<>();
+		try {
+			String startTime = "";
+			String endTime = "";
+			
+			if (datetime != null){
+				startTime = datetime.split(" - ")[0];
+				endTime = datetime.split(" - ")[1];
+			}
+			
+			DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");    
+			DateTime startDateTime = new DateTime(new DateTime().getYear(), new DateTime().getMonthOfYear(), 1, 0, 0, 0);
+			//默认从钉钉上获取当月第一天,作为提交申请的开始时间;
+			long startTimelong = startDateTime.getMillis();
+			if (StringUtils.isNotEmpty(applyDate)){
+				startTimelong = DateTime.parse(applyDate, format).toDate().getTime();
+			}
+			
+			//用户选择审批时间段, 默认取今天
+			long startTimeSearch = new DateTime().withMillisOfDay(0).getMillis();
+			if (StringUtils.isNotEmpty(startTime)){
+				startTimeSearch = DateTime.parse(startTime, format).toDate().getTime();
+			}
+			long endTimeSearch = new DateTime().millisOfDay().withMaximumValue().toDate().getTime();
+			if (StringUtils.isNotEmpty(endTime)){
+				endTimeSearch = DateTime.parse(endTime, format).toDate().getTime();
+			}
+			
+			ProcessCode processCode = processCodeService.find(Integer.valueOf(processCodeId));
+			List<ProcessInstance> processes = new ArrayList<ProcessInstance>();
+			
+			DingDingSearchBean vo = new DingDingSearchBean();
+			vo.setProcessCode(processCode.getProcessCode());
+			vo.setStartTime(startTimelong);
+			vo.setStartTimeSearch(startTimeSearch);
+			vo.setEndTimeSearch(endTimeSearch);
+			vo.setBusinessNum(businessNum);
+			if (StringUtils.isNotEmpty(companyId)){
+				DataDictionary d = dataDictionaryService.find(Integer.valueOf(companyId));
+				vo.setCompany(d.getDataValue());
+			}
+			
+			dingDingUtil.getProcesses(processes, vo);
+			/*List<ProcessInstance> instances = new ArrayList<>();
+			if (StringUtils.isNotEmpty(deptId) && !"1".equals(deptId) && processes != null && processes.size() > 0){
+				for (ProcessInstance processInstance : processes){
+					if (deptId.equals(processInstance.getOriginatorDeptId())){
+						instances.add(processInstance);
+					}
+				}
+			}else{
+				instances.addAll(processes);
+			}*/
+			result.put("code", 0);
+			result.put("msg", "");
+			result.put("count", processes.size());
+			result.put("data", processes);
+			return result;
+		}
+		catch (Exception e) {
+			result.put("code", 1);
+			result.put("msg", "报500错误啦,请联系管理员!");
+			return result;
+        }
+	}
+
+	/**
+	 * 查看审批详情
+	 * @param processInstanceId
+	 * @param processCodeId
+	 * @param title
+	 * @param businessId
+	 * @param map
+	 * @return
+	 */
+    @RequestMapping(value = "/detail", method = RequestMethod.GET)
+    @ResponseBody
+    public JsonResult detail(String processInstanceId, String processCodeId, String title, String businessId, ModelMap map) {
+    	
+        try {
+        	//首先查找文件是否已经存在
+        	ProcessCode processCode = processCodeService.findById(Integer.valueOf(processCodeId));
+            String fileName = dingDingUtil.getFileName(processCode.getProcessName(), title, businessId);
+    		String filePathName = path + fileName + ".html";
+    		//生成文件夹
+    		File dirFile = new File(path + processCode.getProcessName());
+    		if(!dirFile.exists()){
+    			dirFile.mkdir();
+    		}
+    		File file = new File(filePathName);
+    		if (file.exists()){
+    			return JsonResult.success(fileName + ".html");
+    		}else{
+    			//设置输出文件
+    			file.createNewFile();
+    		}
+    		
+    		htmlPdfUtil.generateHTMLFile(dingDingUtil.getAccessToken(), processInstanceId, fileName);
+        	return JsonResult.success(fileName + ".html");
+        } catch (Exception e) {
+        	logger.error("系统异常:", e);
+            return JsonResult.failure("系统异常:"+e);
+        }finally{
+        }
+    }
+
+    /**
+     * 下载单个pdf
+     * @param processInstanceId
+     * @param processCodeId
+     * @param title
+     * @param businessId
+     * @param res
+     */
+    @RequestMapping(value = "/download", method = RequestMethod.GET)
+    public void download(String processInstanceId, String processCodeId, String title, String businessId, HttpServletResponse res){
+    	
+        //首先查找文件是否已经存在
+    	ProcessCode processCode = processCodeService.findById(Integer.valueOf(processCodeId));
+        String fileName = dingDingUtil.getFileName(processCode.getProcessName(), title, businessId);
+		File file = new File(path + fileName + ".html");
+		if (!file.exists()){
+			//不存在则生成html和pdf文件
+			htmlPdfUtil.generateHtmlAndPDF(dingDingUtil.getAccessToken(), processInstanceId, processCode.getProcessName());
+		}else{
+			//存在则生成pdf文件
+			htmlPdfUtil.generatePdfFile(path + fileName);
+		}
+		
+		BufferedInputStream bis = null;
+		OutputStream os = null;
+		try {
+			String name = title + businessId;
+			String fileRealName = new String(name.getBytes(), "ISO-8859-1");
+			res.setHeader("content-type", "application/octet-stream");
+			res.setContentType("application/octet-stream");
+			res.setHeader("Content-Disposition", "attachment;filename=" + fileRealName + ".pdf");
+			byte[] buff = new byte[1024];
+			os = res.getOutputStream();
+			bis = new BufferedInputStream(new FileInputStream(new File(path + fileName + ".pdf")));
+			int i = bis.read(buff);
+			while (i != -1) {
+				os.write(buff, 0, buff.length);
+				os.flush();
+				i = bis.read(buff);
+			}
+		} catch (IOException e) {
+			logger.error("系统异常:", e);
+		} finally {
+			if (bis != null) {
+				try {
+					bis.close();
+				} catch (IOException e) {
+					logger.error("系统异常:", e);
+				}
+			}
+			FileUtil.deleteFile(path + fileName + ".pdf");
+		}
+		logger.info("Download successfully");
+    }
+
+    /**
+     * 下载打包的pdf文件 
+     * @param filePath
+     * @param fileName
+     * @param res
+     */
+    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
+    public void downloadFile(String filePath, String fileName, HttpServletResponse res){
+    	
+		BufferedInputStream bis = null;
+		OutputStream os = null;
+		try {
+			String fileRealName = new String(fileName.getBytes(), "ISO-8859-1");
+			res.setHeader("content-type", "application/octet-stream");
+			res.setContentType("application/octet-stream");
+			res.setHeader("Content-Disposition", "attachment;filename=" + fileRealName);
+			byte[] buff = new byte[1024];
+			os = res.getOutputStream();
+			bis = new BufferedInputStream(new FileInputStream(new File(filePath)));
+			int i = bis.read(buff);
+			while (i != -1) {
+				os.write(buff, 0, buff.length);
+				os.flush();
+				i = bis.read(buff);
+			}
+		} catch (IOException e) {
+			logger.error("系统异常:", e);
+		} finally {
+			if (bis != null) {
+				try {
+					bis.close();
+				} catch (IOException e) {
+					logger.error("系统异常:", e);
+				}
+			}
+			FileUtil.deleteFile(filePath);
+		}
+		logger.info("Download successfully");
+    }
+    
+    /**
+     * 生成打包文件
+     * @param processInstanceIds
+     * @param processCodeId
+     * @param res
+     * @return
+     */
+    @RequestMapping(value = "/downloadAll", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult downloadAll(String processInstanceIds, String processCodeId, HttpServletResponse res){
+    	ProcessCode processCode = processCodeService.find(Integer.valueOf(processCodeId));
+    	try{
+    		//先删除该目录下所有文件
+        	FileUtil.deleteFolder(path + processCode.getProcessName());
+    		
+    		//生成pdf
+	        String[] processInstanceIdArr = processInstanceIds.split(",");
+	        for (String processInstanceId : processInstanceIdArr){
+	        	htmlPdfUtil.generateHtmlAndPDF(dingDingUtil.getAccessToken(), processInstanceId, processCode.getProcessName());
+	        }
+	        //将pdf打包成zip
+	        String sourceFilePath = path + processCode.getProcessName() + "/";
+	        String zipName = processCode.getProcessName() + new Date().getTime();
+	        
+	        FileOutputStream fos1 = new FileOutputStream(new File(path + zipName + ".zip"));
+	        ZipUtil.toZip(sourceFilePath, fos1, false);
+	        
+	        JSONObject object = new JSONObject();
+	        object.put("fileName", zipName + ".zip");
+	        object.put("filePath", path + zipName + ".zip");
+	        
+	        
+	        return JsonResult.success(object);
+	    } catch (Exception e) {
+	    	logger.error("系统异常:", e);
+	        return JsonResult.failure("系统异常:"+e);
+	    }finally {
+	    	//删除该目录下所有文件
+        	FileUtil.deleteFolder(path + processCode.getProcessName());
+	    }
+    }
+}
+

+ 16 - 0
src/main/java/com/fourdage/dingding/dao/IDepartmentDao.java

@@ -0,0 +1,16 @@
+package com.fourdage.dingding.dao;
+
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.dingding.entity.Department;
+
+@Repository
+public interface IDepartmentDao extends IBaseDao<Department, Integer>{
+
+	public List<Department> findByDeptId(String deptId);
+
+	public List<Department> findByRegion(String region);
+}

+ 17 - 0
src/main/java/com/fourdage/dingding/dao/IProcessCodeDao.java

@@ -0,0 +1,17 @@
+package com.fourdage.dingding.dao;
+
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.dingding.entity.ProcessCode;
+
+@Repository
+public interface IProcessCodeDao extends IBaseDao<ProcessCode, Integer>{
+
+	public List<ProcessCode> findByRegion(String region);
+
+	public ProcessCode findByProcessCode(String processCode);
+
+}

+ 95 - 0
src/main/java/com/fourdage/dingding/entity/Department.java

@@ -0,0 +1,95 @@
+package com.fourdage.dingding.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.hibernate.annotations.Where;
+
+import com.fourdage.base.entity.BaseEntity;
+
+/**
+ * <p>
+ * 钉钉部门
+ * </p>
+ *
+ * @author ajay peng
+ * @since 2018-11-20
+ */
+@Entity
+@Table(name = "tb_department")
+@Where(clause = "rec_status='A'")
+public class Department extends BaseEntity{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3191811728219623858L;
+	
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name = "id", nullable = false)
+	private Integer id;
+	
+	private String deptId;
+	
+	private String deptName;
+	
+	private String region;
+	
+	private String parentId;
+	
+	@Column(length = 2)
+	private String recStatus;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public String getDeptId() {
+		return deptId;
+	}
+
+	public String getDeptName() {
+		return deptName;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public void setDeptId(String deptId) {
+		this.deptId = deptId;
+	}
+
+	public void setDeptName(String deptName) {
+		this.deptName = deptName;
+	}
+
+	public String getRegion() {
+		return region;
+	}
+
+	public void setRegion(String region) {
+		this.region = region;
+	}
+
+	public String getParentId() {
+		return parentId;
+	}
+
+	public void setParentId(String parentId) {
+		this.parentId = parentId;
+	}
+
+	public String getRecStatus() {
+		return recStatus;
+	}
+
+	public void setRecStatus(String recStatus) {
+		this.recStatus = recStatus;
+	}
+}

+ 91 - 0
src/main/java/com/fourdage/dingding/entity/DingDingSearchBean.java

@@ -0,0 +1,91 @@
+package com.fourdage.dingding.entity;
+
+import java.io.Serializable;
+
+public class DingDingSearchBean implements Serializable{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -2302953389421021046L;
+	
+	private String processCode;
+	
+	private String page;
+	
+	private long startTime;
+	
+	private long startTimeSearch;
+	
+	private long endTimeSearch;
+	
+	private String businessNum;
+	
+	private String[] userids;
+	
+	private String company;
+
+	public String getProcessCode() {
+		return processCode;
+	}
+
+	public String getPage() {
+		return page;
+	}
+
+	public long getStartTime() {
+		return startTime;
+	}
+
+	public long getStartTimeSearch() {
+		return startTimeSearch;
+	}
+
+	public long getEndTimeSearch() {
+		return endTimeSearch;
+	}
+
+	public String getBusinessNum() {
+		return businessNum;
+	}
+
+	public String[] getUserids() {
+		return userids;
+	}
+
+	public void setProcessCode(String processCode) {
+		this.processCode = processCode;
+	}
+
+	public void setPage(String page) {
+		this.page = page;
+	}
+
+	public void setStartTime(long startTime) {
+		this.startTime = startTime;
+	}
+
+	public void setStartTimeSearch(long startTimeSearch) {
+		this.startTimeSearch = startTimeSearch;
+	}
+
+	public void setEndTimeSearch(long endTimeSearch) {
+		this.endTimeSearch = endTimeSearch;
+	}
+
+	public void setBusinessNum(String businessNum) {
+		this.businessNum = businessNum;
+	}
+
+	public void setUserids(String[] userids) {
+		this.userids = userids;
+	}
+
+	public String getCompany() {
+		return company;
+	}
+
+	public void setCompany(String company) {
+		this.company = company;
+	}
+}

+ 55 - 0
src/main/java/com/fourdage/dingding/entity/FormComponentValue.java

@@ -0,0 +1,55 @@
+package com.fourdage.dingding.entity;
+
+import java.io.Serializable;
+
+/**
+ * 表单详情
+ * @author ajay peng
+ *
+ */
+public class FormComponentValue implements Serializable{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 44441483526066420L;
+
+	/**
+	 * 标签名
+	 */
+	private String name;
+	
+	/**
+	 * 标签值
+	 */
+	private String value;
+	
+	/**
+	 * 标签扩展值
+	 */
+	private String extValue;
+
+	public String getName() {
+		return name;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public String getExtValue() {
+		return extValue;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	public void setExtValue(String extValue) {
+		this.extValue = extValue;
+	}
+}

+ 99 - 0
src/main/java/com/fourdage/dingding/entity/OperationRecords.java

@@ -0,0 +1,99 @@
+package com.fourdage.dingding.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * 操作记录列表
+ * @author ajay peng
+ *
+ */
+public class OperationRecords implements Serializable{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -4661729697236641880L;
+	
+	/**
+	 * 操作人
+	 */
+	private String userId;
+	
+	/**
+	 * 时间
+	 */
+	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date date;
+	
+	/**
+	 * 作类型,分为
+	 * EXECUTE_TASK_NORMAL(正常执行任务),
+	 * EXECUTE_TASK_AGENT(代理人执行任务),
+	 * APPEND_TASK_BEFORE(前加签任务),
+	 * APPEND_TASK_AFTER(后加签任务),
+	 * REDIRECT_TASK(转交任务),
+	 * START_PROCESS_INSTANCE(发起流程实例),
+	 * TERMINATE_PROCESS_INSTANCE(终止(撤销)流程实例),
+	 * FINISH_PROCESS_INSTANCE(结束流程实例),
+	 * ADD_REMARK(添加评论)
+	 */
+	private String operationType;
+	
+	/**
+	 * 操作结果,分为AGREE(同意),REFUSE(拒绝)
+	 */
+	private String operationResult;
+	
+	/**
+	 * 评论
+	 */
+	private String remark;
+
+	public String getUserId() {
+		return userId;
+	}
+
+	public Date getDate() {
+		return date;
+	}
+
+	public String getOperationType() {
+		return operationType;
+	}
+
+	public String getOperationResult() {
+		return operationResult;
+	}
+
+	public String getRemark() {
+		return remark;
+	}
+
+	public void setUserId(String userId) {
+		this.userId = userId;
+	}
+
+	public void setDate(Date date) {
+		this.date = date;
+	}
+
+	public void setOperationType(String operationType) {
+		this.operationType = operationType;
+	}
+
+	public void setOperationResult(String operationResult) {
+		this.operationResult = operationResult;
+	}
+
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+	
+}

+ 122 - 0
src/main/java/com/fourdage/dingding/entity/PdfVO.java

@@ -0,0 +1,122 @@
+package com.fourdage.dingding.entity;
+
+import java.io.Serializable;
+
+public class PdfVO implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 2153893870223956090L;
+
+	private String title;
+
+	private String corpName;
+
+	private String applyDate;
+
+	private String status;
+
+	private String businessId;
+
+	private String applyUserName;
+
+	private String org;
+
+	private String form;
+
+	private String operations;
+	
+	private String printDate;
+	
+	private String printer;
+
+	public String getTitle() {
+		return title;
+	}
+
+	public String getCorpName() {
+		return corpName;
+	}
+
+	public String getApplyDate() {
+		return applyDate;
+	}
+
+	public String getStatus() {
+		return status;
+	}
+
+	public String getBusinessId() {
+		return businessId;
+	}
+
+	public String getApplyUserName() {
+		return applyUserName;
+	}
+
+	public String getOrg() {
+		return org;
+	}
+
+	public String getForm() {
+		return form;
+	}
+
+	public String getOperations() {
+		return operations;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public void setCorpName(String corpName) {
+		this.corpName = corpName;
+	}
+
+	public void setApplyDate(String applyDate) {
+		this.applyDate = applyDate;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+
+	public void setBusinessId(String businessId) {
+		this.businessId = businessId;
+	}
+
+	public void setApplyUserName(String applyUserName) {
+		this.applyUserName = applyUserName;
+	}
+
+	public void setOrg(String org) {
+		this.org = org;
+	}
+
+	public void setForm(String form) {
+		this.form = form;
+	}
+
+	public void setOperations(String operations) {
+		this.operations = operations;
+	}
+
+	public String getPrintDate() {
+		return printDate;
+	}
+
+	public String getPrinter() {
+		return printer;
+	}
+
+	public void setPrintDate(String printDate) {
+		this.printDate = printDate;
+	}
+
+	public void setPrinter(String printer) {
+		this.printer = printer;
+	}
+
+}

+ 77 - 0
src/main/java/com/fourdage/dingding/entity/ProcessCode.java

@@ -0,0 +1,77 @@
+package com.fourdage.dingding.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.hibernate.annotations.Where;
+
+import com.fourdage.base.entity.BaseEntity;
+
+/**
+ * <p>
+ * 审批表单
+ * </p>
+ *
+ * @author ajay peng
+ * @since 2018-3-26
+ */
+@Entity
+@Table(name = "tb_process")
+@Where(clause = "rec_status='A'")
+public class ProcessCode extends BaseEntity{
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -7712277778301780214L;
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name = "id", nullable = false)
+	private Integer id;
+	
+	private String processCode;
+	
+	private String processName;
+	
+	private String region;
+	
+	@Column(length = 2)
+	private String recStatus;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public String getProcessCode() {
+		return processCode;
+	}
+
+	public String getProcessName() {
+		return processName;
+	}
+
+	public String getRegion() {
+		return region;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public void setProcessCode(String processCode) {
+		this.processCode = processCode;
+	}
+
+	public void setProcessName(String processName) {
+		this.processName = processName;
+	}
+
+	public void setRegion(String region) {
+		this.region = region;
+	}
+
+}

+ 266 - 0
src/main/java/com/fourdage/dingding/entity/ProcessInstance.java

@@ -0,0 +1,266 @@
+package com.fourdage.dingding.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * 审批实例
+ * @author ajay peng
+ *
+ */
+public class ProcessInstance implements Serializable{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3592333141742977489L;
+	
+	/**
+	 * 审批实例id
+	 */
+	private String processInstanceId;
+	
+	/**
+	 * 标题
+	 */
+	private String title;
+	
+	/**
+	 * 开始时间
+	 */
+	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date createTime;
+	
+	/**
+	 * 结束时间
+	 */
+	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date finishTime;
+	
+	/**
+	 * 发起人userid
+	 */
+	private String originatorUserId;
+	
+	/**
+	 * 发起人名称
+	 */
+	private String originatorUserName;
+	
+	/**
+	 * 发起人部门id
+	 */
+	private String originatorDeptId;
+	
+	/**
+	 * 审批状态,分为NEW(刚创建)|RUNNING(运行中)|TERMINATED(被终止)|COMPLETED(完成)|CANCELED(取消)
+	 */
+	private String status;
+	
+	/**
+	 * 审批人列表
+	 */
+	private String[] approverUserIds;
+	
+	/**
+	 * 抄送人列表
+	 */
+	private String[] ccUserIds;
+	
+	/**
+	 * 审批结果,分为agree和refuse
+	 */
+	private String result;
+	
+	/**
+	 * 流程实例业务编号
+	 */
+	private String businessId;
+	
+	/**
+	 * 发起部门
+	 */
+	private String originatorDeptName;
+	
+	/**
+	 * 审批实例业务动作,
+	 * MODIFY表示该审批实例是基于原来的实例修改而来
+	 * REVOKE表示该审批实例是由原来的实例撤销后重新发起的
+	 * NONE表示正常发起
+	 */
+	private String bizAction;
+	
+	/**
+	 * 审批附属实例列表,当已经通过的审批实例被修改或撤销,会生成一个新的实例,作为原有审批实例的附属。
+	 * 如果想知道当前已经通过的审批实例的状态,可以依次遍历它的附属列表,查询里面每个实例的biz_action
+	 */
+	private String attachedProcessInstanceIds;
+	
+	/**
+	 * 表单详情列表 
+	 */
+	private Set<FormComponentValue> formComponentValues;
+	
+	/**
+	 * 操作记录列表
+	 */
+	private Set<OperationRecords> operationRecords;
+	
+	/**
+	 * 任务列表
+	 */
+	private Set<TaskTop> tasks;
+
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public Date getFinishTime() {
+		return finishTime;
+	}
+
+	public String getOriginatorUserId() {
+		return originatorUserId;
+	}
+
+	public String getOriginatorDeptId() {
+		return originatorDeptId;
+	}
+
+	public String getStatus() {
+		return status;
+	}
+
+	public String[] getApproverUserIds() {
+		return approverUserIds;
+	}
+
+	public String[] getCcUserIds() {
+		return ccUserIds;
+	}
+
+	public String getResult() {
+		return result;
+	}
+
+	public String getBusinessId() {
+		return businessId;
+	}
+
+	public String getOriginatorDeptName() {
+		return originatorDeptName;
+	}
+
+	public String getBizAction() {
+		return bizAction;
+	}
+
+	public String getAttachedProcessInstanceIds() {
+		return attachedProcessInstanceIds;
+	}
+
+	public Set<FormComponentValue> getFormComponentValues() {
+		return formComponentValues;
+	}
+
+	public Set<OperationRecords> getOperationRecords() {
+		return operationRecords;
+	}
+
+	public Set<TaskTop> getTasks() {
+		return tasks;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public void setFinishTime(Date finishTime) {
+		this.finishTime = finishTime;
+	}
+
+	public void setOriginatorUserId(String originatorUserId) {
+		this.originatorUserId = originatorUserId;
+	}
+
+	public void setOriginatorDeptId(String originatorDeptId) {
+		this.originatorDeptId = originatorDeptId;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+
+	public void setApproverUserIds(String[] approverUserIds) {
+		this.approverUserIds = approverUserIds;
+	}
+
+	public void setCcUserIds(String[] ccUserIds) {
+		this.ccUserIds = ccUserIds;
+	}
+
+	public void setResult(String result) {
+		this.result = result;
+	}
+
+	public void setBusinessId(String businessId) {
+		this.businessId = businessId;
+	}
+
+	public void setOriginatorDeptName(String originatorDeptName) {
+		this.originatorDeptName = originatorDeptName;
+	}
+
+	public void setBizAction(String bizAction) {
+		this.bizAction = bizAction;
+	}
+
+	public void setAttachedProcessInstanceIds(String attachedProcessInstanceIds) {
+		this.attachedProcessInstanceIds = attachedProcessInstanceIds;
+	}
+
+	public void setFormComponentValues(Set<FormComponentValue> formComponentValues) {
+		this.formComponentValues = formComponentValues;
+	}
+
+	public void setOperationRecords(Set<OperationRecords> operationRecords) {
+		this.operationRecords = operationRecords;
+	}
+
+	public void setTasks(Set<TaskTop> tasks) {
+		this.tasks = tasks;
+	}
+
+	public String getOriginatorUserName() {
+		return originatorUserName;
+	}
+
+	public void setOriginatorUserName(String originatorUserName) {
+		this.originatorUserName = originatorUserName;
+	}
+
+}

+ 54 - 0
src/main/java/com/fourdage/dingding/entity/TaskTop.java

@@ -0,0 +1,54 @@
+package com.fourdage.dingding.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * 任务列表
+ * @author ajay peng
+ *
+ */
+public class TaskTop implements Serializable{
+	
+	/**
+	 * 任务处理人
+	 */
+	private String userId;
+	
+	/**
+	 * 任务状态,分为NEW(未启动),RUNNING(处理中),PAUSED(暂停),CANCELED(取消),COMPLETED(完成),TERMINATED(终止)
+	 */
+	private String taskStatus;
+	
+	/**
+	 * 结果,分为AGREE(同意),REFUSE(拒绝),REDIRECTED(转交)
+	 */
+	private String taskResult;
+	
+	/**
+	 * 开始时间
+	 */
+	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date createTime;
+	
+	/**
+	 * 结束时间
+	 */
+	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date finishTime;
+	
+	/**
+	 * 任务节点id
+	 */
+	private String taskId;
+	
+	
+	
+}

+ 24 - 0
src/main/java/com/fourdage/dingding/job/ScheduledJob.java

@@ -0,0 +1,24 @@
+package com.fourdage.dingding.job;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * Description: 获取钉钉上的部门和用户信息
+ * Designer: ajay peng
+ * Date: 2018/4/20
+ * Version: 1.0.0
+ */
+@Component
+public class ScheduledJob implements ApplicationRunner {
+	
+	private Logger logger = LoggerFactory.getLogger(getClass());
+	
+	@Override
+	public void run(ApplicationArguments arg0) throws Exception {
+		logger.info("获取钉钉部门和用户信息");
+	}
+}

+ 13 - 0
src/main/java/com/fourdage/dingding/service/IDepartmentService.java

@@ -0,0 +1,13 @@
+package com.fourdage.dingding.service;
+
+import java.util.List;
+
+import com.fourdage.base.service.IBaseService;
+import com.fourdage.dingding.entity.Department;
+
+public interface IDepartmentService extends IBaseService<Department, Integer>{
+	
+	public List<Department> findByDeptId(String deptId);
+
+	public List<Department> findByRegion(String region);
+}

+ 16 - 0
src/main/java/com/fourdage/dingding/service/IProcessCodeService.java

@@ -0,0 +1,16 @@
+package com.fourdage.dingding.service;
+
+import java.util.List;
+
+import com.fourdage.base.service.IBaseService;
+import com.fourdage.dingding.entity.ProcessCode;
+
+public interface IProcessCodeService extends IBaseService<ProcessCode, Integer> {
+	
+	public List<ProcessCode> findByRegion(String region);
+	
+	public ProcessCode findByProcessCode(String processCode);
+
+	public ProcessCode findById(Integer processCodeId);
+
+}

+ 35 - 0
src/main/java/com/fourdage/dingding/service/impl/DepartmentServiceImpl.java

@@ -0,0 +1,35 @@
+package com.fourdage.dingding.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.service.impl.BaseServiceImpl;
+import com.fourdage.dingding.dao.IDepartmentDao;
+import com.fourdage.dingding.entity.Department;
+import com.fourdage.dingding.service.IDepartmentService;
+
+@Service
+public class DepartmentServiceImpl extends BaseServiceImpl<Department, Integer> implements IDepartmentService{
+
+	@Autowired
+	private IDepartmentDao dao;
+	
+	@Override
+	public IBaseDao<Department, Integer> getBaseDao() {
+		return this.dao;
+	}
+
+	@Override
+	public List<Department> findByDeptId(String deptId) {
+		return dao.findByDeptId(deptId);
+	}
+
+	@Override
+	public List<Department> findByRegion(String region) {
+		return dao.findByRegion(region);
+	}
+
+}

+ 43 - 0
src/main/java/com/fourdage/dingding/service/impl/ProcessCodeServiceImpl.java

@@ -0,0 +1,43 @@
+package com.fourdage.dingding.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import com.fourdage.base.common.Constats;
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.service.impl.BaseServiceImpl;
+import com.fourdage.dingding.dao.IProcessCodeDao;
+import com.fourdage.dingding.entity.ProcessCode;
+import com.fourdage.dingding.service.IProcessCodeService;
+
+@Service
+public class ProcessCodeServiceImpl extends BaseServiceImpl<ProcessCode, Integer> implements IProcessCodeService{
+	
+	@Autowired
+	private IProcessCodeDao dao;
+	
+    @Override
+    public IBaseDao<ProcessCode, Integer> getBaseDao() {
+        return this.dao;
+    }
+	
+	public List<ProcessCode> findByRegion(String region){
+		return dao.findByRegion(region);
+	}
+	
+	public ProcessCode findByProcessCode(String processCode){
+		return dao.findByProcessCode(processCode);
+	}
+
+	@Override
+	@Cacheable(value = "processCodeCache", key = "#processCodeId")
+	public ProcessCode findById(Integer processCodeId) {
+		return dao.findOne(processCodeId);
+	}
+	
+	
+
+}

+ 240 - 0
src/main/java/com/fourdage/dingding/util/DingDingUtil.java

@@ -0,0 +1,240 @@
+package com.fourdage.dingding.util;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.stereotype.Repository;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fourdage.base.common.HttpHelper;
+import com.fourdage.dingding.entity.DingDingSearchBean;
+import com.fourdage.dingding.entity.ProcessInstance;
+import com.fourdage.system.entity.DataDictionary;
+import com.fourdage.system.entity.User;
+import com.fourdage.system.service.IDataDictionaryService;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+@Repository
+public class DingDingUtil {
+	
+	@Autowired
+	private IDataDictionaryService dataDictionaryService;
+	
+	@Autowired  
+	private EhCacheCacheManager ehCacheCacheManager;
+	
+	public  String getTaskResult(String taskResult) {
+		switch (taskResult) {
+		case "AGREE":
+			taskResult = "同意";
+			break;
+		case "REFUSE":
+			taskResult = "拒绝";
+			break;
+		case "REDIRECTED":
+			taskResult = "转交";
+			break;
+		default:
+			taskResult = "";
+			break;
+		}
+		return taskResult;
+	}
+	
+	public  JSONObject getDingDingJSONResult(String processInstanceId, String accessToken) {
+    	Map<String, Object> processMap = new HashMap<String, Object>();
+    	processMap.put("method", "dingtalk.smartwork.bpms.processinstance.get");
+    	processMap.put("session", accessToken);
+    	processMap.put("timestamp", Long.valueOf(System.currentTimeMillis()).toString());
+    	processMap.put("format", "json");
+    	processMap.put("v", "2.0");
+    	processMap.put("process_instance_id", processInstanceId);
+    	
+    	String resultStr = HttpHelper.sendGetByUrlConnection("https://eco.taobao.com/router/rest", processMap, "UTF-8");
+    	JSONObject resultStrObject = JSON.parseObject(resultStr);
+    	JSONObject jsonResult = resultStrObject.getJSONObject("dingtalk_smartwork_bpms_processinstance_get_response").getJSONObject("result");
+    	return jsonResult;
+    }
+
+	public  String getStatus(String status){
+    	switch (status) {
+		case "NEW":
+			return "刚创建";
+		case "RUNNING":
+			return "运行中";
+		case "TERMINATED":
+			return "被终止";
+		case "COMPLETED":
+			return "完成";
+		case "CANCELED":
+			return "取消";
+		default:
+			return "";
+		}
+    }
+	
+	public  boolean isJSONValid(String test) {
+        try {
+            JSONObject.parseObject(test);
+        } catch (Exception ex) {
+            try {
+                JSONObject.parseArray(test);
+            } catch (Exception ex1) {
+                return false;
+            }
+        }
+        return true;
+    }
+	
+	public List<ProcessInstance> getProcesses(List<ProcessInstance> processes, DingDingSearchBean searchBean){
+    	
+    	DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
+    	
+		Map<String, Object> processMap = new HashMap<String, Object>();
+		processMap.put("method", "dingtalk.smartwork.bpms.processinstance.list");
+		processMap.put("session", getAccessToken());
+		processMap.put("timestamp", Long.valueOf(System.currentTimeMillis()).toString());
+		processMap.put("format", "json");
+		processMap.put("v", "2.0");
+		processMap.put("process_code", searchBean.getProcessCode());
+		processMap.put("start_time", searchBean.getStartTime());
+		processMap.put("cursor", searchBean.getPage() == null ? 0 : searchBean.getPage());
+		
+		String resultStr = HttpHelper.sendGetByUrlConnection("https://eco.taobao.com/router/rest", processMap, "UTF-8");
+		JSONObject resultStrObject = JSON.parseObject(resultStr);
+		JSONObject jsonResult = resultStrObject.getJSONObject("dingtalk_smartwork_bpms_processinstance_list_response").getJSONObject("result");
+		System.out.println("jsonResult:" + jsonResult);
+		
+		if (jsonResult.getBoolean("success")){
+			JSONObject result = jsonResult.getJSONObject("result");
+			JSONObject list =  result.getJSONObject("list");
+			JSONArray processInstanceTop = list.getJSONArray("process_instance_top_vo");
+			if (processInstanceTop != null){
+				for (Object obj : processInstanceTop){
+					JSONObject jobj = (JSONObject)obj;
+					
+					String processInstanceResult = jobj.getString("process_instance_result");
+					String status = jobj.getString("status");
+					if (StringUtils.isEmpty(processInstanceResult) || StringUtils.isEmpty(status) 
+							|| !"COMPLETED".equals(status) 
+							|| !"agree".equals(processInstanceResult)){
+						continue;
+					}
+					if (jobj.getString("finish_time") == null){
+						continue;
+					}
+					
+					DateTime de = DateTime.parse(jobj.getString("finish_time"), format);
+					if (de.isAfter(searchBean.getStartTimeSearch()) && de.isBefore(searchBean.getEndTimeSearch())){
+						if (StringUtils.isNotEmpty(searchBean.getBusinessNum()) 
+								&& !jobj.getString("business_id").contains(searchBean.getBusinessNum())){
+							continue;
+						}
+						
+						if (StringUtils.isNotEmpty(searchBean.getCompany())){
+							try {
+								String company = jobj.getJSONObject("form_component_values").getJSONArray("form_component_value_vo").getJSONObject(0).getString("value");
+								if (searchBean.getCompany().equals(company)){
+									processes.add(getProcessInstance(format, jobj, processInstanceResult, status));
+								}
+							}catch(Exception e){}
+						}else{
+							processes.add(getProcessInstance(format, jobj, processInstanceResult, status));
+						}
+					}
+				}
+				if (result.get("next_cursor") != null){
+					searchBean.setPage(String.valueOf(result.getInteger("next_cursor")));
+					getProcesses(processes, searchBean);
+				}
+			}
+		}
+		return processes;
+    }
+
+	private ProcessInstance getProcessInstance(DateTimeFormatter format, JSONObject jobj, String processInstanceResult,
+			String status) {
+		ProcessInstance process = new ProcessInstance();
+		process.setBusinessId(jobj.getString("business_id"));
+		
+		if (jobj.getString("create_time") != null){
+			process.setCreateTime(DateTime.parse(jobj.getString("create_time"), format).toDate());
+		}
+		if (jobj.getString("finish_time") != null){
+			process.setFinishTime(DateTime.parse(jobj.getString("finish_time"), format).toDate());
+		}
+		process.setOriginatorDeptId(jobj.getString("originator_dept_id"));
+		process.setOriginatorUserId(jobj.getString("originator_userid"));
+		process.setProcessInstanceId(jobj.getString("process_instance_id"));
+		process.setResult(processInstanceResult);
+		process.setStatus(status);
+		process.setTitle(jobj.getString("title"));
+		return process;
+	}
+	
+	public String getRegion(){
+		Subject subject = SecurityUtils.getSubject();
+        Object principal = subject.getPrincipal();
+        String region = "zh";
+        if (principal != null) {
+        	region = ((User) principal).getAddress();
+        }
+        return region;
+	}
+    
+    public String getAccessToken() {
+        String region = getRegion();
+    	
+    	DataDictionary searchCondition = new DataDictionary();
+		searchCondition.setCode("dingding_corp_code");
+		searchCondition.setParam1(region);
+    	
+    	Cache cache = ehCacheCacheManager.getCacheManager().getCache("accessToken");
+    	Element sessionKey = cache.get(searchCondition.getParam1());
+    	if (sessionKey != null){
+    		return (String) sessionKey.getObjectValue();
+    	}
+    	
+    	List<DataDictionary> datas = dataDictionaryService.findByCondition(searchCondition);
+    	
+    	Map<String, Object> tokenMap = new HashMap<String, Object>();
+    	tokenMap.put("corpid", datas.get(0).getDataKey());
+    	tokenMap.put("corpsecret", datas.get(0).getDataValue());
+    	
+    	String accessTokenStr = HttpHelper.sendGetByHttpUrlConnection("https://oapi.dingtalk.com/gettoken", tokenMap, "UTF-8");
+    	JSONObject jsonObject = JSON.parseObject(accessTokenStr);
+    	String accessToken = jsonObject.getString("access_token");
+    	
+    	Element elementSession = new Element(searchCondition.getParam1(), accessToken);
+    	cache.put(elementSession);
+    	cache.flush();
+    	
+    	return accessToken;
+    }
+    
+    public String getFileName(String processCode, String title, String businessId){
+		StringBuffer sb = new StringBuffer();
+		sb.append(processCode).append("/").append(title).append(businessId);
+		return sb.toString();
+		
+	}
+
+	public static void main(String[] args) {
+		DingDingUtil util = new DingDingUtil();
+		System.out.println(util.getAccessToken());
+	}
+
+}

+ 88 - 0
src/main/java/com/fourdage/dingding/util/FileUtil.java

@@ -0,0 +1,88 @@
+package com.fourdage.dingding.util;
+
+import java.io.File;
+
+public class FileUtil {
+
+	private FileUtil() {
+	}
+
+    /**
+     * 删除单个文件
+     *
+     * @param fileName
+     *            要删除的文件的文件名
+     * @return 单个文件删除成功返回true,否则返回false
+     */
+    public static boolean deleteFile(String fileName) {
+        File file = new File(fileName);
+        if (file.exists() && file.isFile()) {
+            if (file.delete()) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+    
+    /** 
+     *  根据路径删除指定的目录,无论存在与否 
+     *@param sPath  要删除的目录path 
+     *@return 删除成功返回 true,否则返回 false。 
+     */  
+    public static boolean deleteFolder(String sPath) {
+        boolean flag = false;
+        File file = new File(sPath);
+        // 判断目录或文件是否存在
+        if (!file.exists()) {  // 不存在返回 false
+            return flag;
+        } else {
+            // 判断是否为文件
+            if (file.isFile()) {  // 为文件时调用删除文件方法
+                return deleteFile(sPath);
+            } else {  // 为目录时调用删除目录方法
+                return deleteDirectory(sPath);
+            }
+        }
+    }
+    
+    /**
+     * 删除目录以及目录下的文件
+     * @param   sPath 被删除目录的路径
+     * @return  目录删除成功返回true,否则返回false
+     */
+    public static boolean deleteDirectory(String sPath) {
+        //如果sPath不以文件分隔符结尾,自动添加文件分隔符
+        if (!sPath.endsWith(File.separator)) {
+            sPath = sPath + File.separator;
+        }
+        File dirFile = new File(sPath);
+        //如果dir对应的文件不存在,或者不是一个目录,则退出
+        if (!dirFile.exists() || !dirFile.isDirectory()) {
+            return false;
+        }
+        boolean flag = true;
+        //删除文件夹下的所有文件(包括子目录)
+        File[] files = dirFile.listFiles();
+        for (int i = 0; i < files.length; i++) {
+            //删除子文件
+            if (files[i].isFile()) {
+                flag = deleteFile(files[i].getAbsolutePath());
+                if (!flag) break;
+            } //删除子目录
+            else {
+                flag = deleteDirectory(files[i].getAbsolutePath());
+                if (!flag) break;
+            }
+        }
+        if (!flag) return false;
+        //删除当前目录
+        if (dirFile.delete()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}

+ 454 - 0
src/main/java/com/fourdage/dingding/util/HtmlPdfUtil.java

@@ -0,0 +1,454 @@
+package com.fourdage.dingding.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fourdage.base.common.HttpHelper;
+import com.fourdage.dingding.entity.PdfVO;
+import com.fourdage.system.entity.DataDictionary;
+import com.fourdage.system.entity.User;
+import com.fourdage.system.service.IDataDictionaryService;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.PageSize;
+import com.itextpdf.text.pdf.PdfWriter;
+import com.itextpdf.tool.xml.XMLWorkerFontProvider;
+import com.itextpdf.tool.xml.XMLWorkerHelper;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+
+@Repository
+public class HtmlPdfUtil {
+
+
+	
+	@Autowired
+	private IDataDictionaryService dataDictionaryService;
+	
+	@Autowired
+	private DingDingUtil dingdingUtil;
+	
+	@Value("${web.pdf.file.path}")
+    private String path;
+	
+	private Logger logger = LoggerFactory.getLogger(HtmlPdfUtil.class);
+	
+	private String blankCode = "            &nbsp;&nbsp;";
+	
+	public void generateHTMLFile(String accessToken, String processInstanceId, String fileName) {
+//		FileWriter out = null;
+		OutputStreamWriter out = null;
+		try {
+			String title = "";
+			String businessId = "";
+			JSONObject jsonResult = dingdingUtil.getDingDingJSONResult(processInstanceId, accessToken);
+			logger.info("钉钉返回数据: {}", jsonResult);
+			if (jsonResult.getBoolean("success")){
+				DataDictionary corp = dataDictionaryService.findByCodeAndDataKey("corp_code", dingdingUtil.getRegion());
+				
+				JSONObject result = jsonResult.getJSONObject("process_instance");
+				//企业名称
+//				String corpName = corp.getDataValue();
+				String corpName = "四维时代 & 中德人工智能研究院";
+				//申请日期
+				String applyDate = result.getString("create_time");
+				//审批编码
+				businessId = result.getString("business_id");
+				String[] titlesArr = null;
+				if(result.getString("title").contains("的")){
+					titlesArr = result.getString("title").split("的");
+				}
+				if(result.getString("title").contains("'s")){
+					titlesArr = result.getString("title").split("'s");
+				}
+				String applyUserName = titlesArr[0];
+				//申请人
+				//模板名称
+				title = titlesArr[1];
+				//申请人部门
+				String org = result.getString("originator_dept_name");
+				
+				PdfVO vo = new PdfVO();
+				vo.setCorpName(corpName);
+				vo.setApplyDate(applyDate);
+				vo.setBusinessId(businessId);
+				vo.setApplyUserName(applyUserName);
+				vo.setTitle(title);
+				vo.setOrg(org);
+				vo.setStatus(dingdingUtil.getStatus(result.getString("status")));
+				vo.setForm(generateForm(result).toString());
+				vo.setOperations(generateOperators(accessToken, result).toString());
+				vo.setPrintDate(new DateTime().toString("yyyy-MM-dd HH:mm"));
+				
+				Subject subject = SecurityUtils.getSubject();
+	            Object principal = subject.getPrincipal();
+	            String userName = "";
+	            if (principal != null) {
+	            	userName = ((User) principal).getNickName();
+	            }
+	            vo.setPrinter(userName);
+				
+				Configuration configuration = new Configuration();
+				configuration.setDirectoryForTemplateLoading(new File(path));
+				configuration.setDefaultEncoding("UTF-8");
+				// 获取或创建一个模版。  
+				Template template = configuration.getTemplate("pdf.ftl");
+				//设置输出流
+				File file = new File(path + fileName + ".html");
+//				out = new FileWriter(file);
+				//设置文件输入流编码,不然生成的html文件会中文乱码
+				out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
+				//模板输出静态文件
+				template.process(vo, out);
+			}
+		}catch (Exception e) {
+    		logger.error("系统异常:", e);
+    	} finally {
+    		if(null != out) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+    	}
+	}
+	
+	public String generateHtmlAndPDF(String accessToken, String processInstanceId, String processCodeName) {
+    	String fileName = "";	
+    	try {
+    		//从钉钉接口获取结果
+    		JSONObject jsonResult = dingdingUtil.getDingDingJSONResult(processInstanceId, accessToken);
+    		if (!jsonResult.getBoolean("success")) {
+    			return "";
+    		}
+    		//生成文件目录
+    		File dirFile = new File(path + processCodeName);
+    		if(!dirFile.exists()){
+    			dirFile.mkdir();
+    		}
+    		JSONObject result = jsonResult.getJSONObject("process_instance");
+    		fileName = result.getString("title") + result.getString("business_id");
+    		String filePathName = path + processCodeName + "/" + fileName;
+    		//生成HTML文件
+    		generateHTMLFile(accessToken, processInstanceId, processCodeName + "/" + fileName);
+    		//生成pdf文件
+    		generatePdfFile(filePathName);
+    		
+    		FileUtil.deleteFile(filePathName + ".html");
+    	} catch (Exception e) {
+    		logger.error("系统异常:", e);
+    	} finally {
+    	}
+    	return fileName;
+    }
+	
+	public void generatePdfFile(String filePathName) {
+		Document document = null;
+		FileInputStream fis = null;
+		BufferedReader br = null;
+		InputStreamReader reader  = null;
+		try {
+//			fis = new FileInputStream(filePathName + ".html"); 
+//			byte[] buf = new byte[1024];  
+//			int length = 0;
+//			//循环读取文件内容,输入流中将最多buf.length个字节的数据读入一个buf数组中,返回类型是读取到的字节数。
+//			//当文件读取到结尾时返回 -1,循环结束。
+//			String content = null;
+//			while((length = fis.read(buf)) != -1){
+//				content = new String(buf,0,length);
+//			    System.out.print(content);
+//			}
+			
+			
+            fis = new FileInputStream(filePathName + ".html");
+            reader = new InputStreamReader(fis, "UTF-8"); 
+            br = new BufferedReader(reader);
+            String content;
+            String ba = null;
+            while ((content = br.readLine()) != null) {
+                System.out.println(content);
+                ba += content;
+            }
+			byte b[] = ba.getBytes("utf-8"); //这里是必须要设置编码的,不然导出中文就会乱码。 
+			ByteArrayInputStream bais = new ByteArrayInputStream(b);//将字节数组包装到流中
+			
+			// step 1
+			document = new Document(PageSize.A4);
+			// step 2
+			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filePathName + ".pdf"));
+			// step 3
+			document.open();
+			// step 4
+			XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
+			fontImp.register("/font/simhei.ttf");
+			XMLWorkerHelper.getInstance().parseXHtml(writer, document, bais, null, Charset.forName("UTF-8"), fontImp);
+			document.close();
+			br.close();
+            reader.close();
+			fis.close();
+		} catch (Exception e) {
+    		logger.error("系统异常:", e);
+    	} finally {
+    		if (document != null) {
+    			document.close();
+    		}
+    		if (fis != null){
+    			try {
+					fis.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+    		}
+    		if (br != null){
+    			try {
+					br.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+    		}
+    		if (reader != null){
+    			try {
+					reader.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+    		}
+    	}
+	}
+	
+	private StringBuffer generateOperators(String accessToken, JSONObject result) {
+		JSONArray userArray = result.getJSONObject("operation_records").getJSONArray("operation_records_vo");
+		StringBuffer userSB = null;
+		if (userArray != null && userArray.size() > 0){
+			userSB = new StringBuffer("<tr><td rowspan=\"").append(userArray.size()-1).append("\">审批人</td>");
+			for (int i = 0; i < userArray.size(); i++){
+				JSONObject ob = (JSONObject) userArray.get(i);
+				if ("START_PROCESS_INSTANCE".equals(ob.getString("operation_type"))){
+					continue;
+				}
+				if (i == 1){
+					userSB.append("<td>");
+				}else{
+					userSB.append("<tr><td>");
+				}
+				
+				//获取用户信息
+		    	Map<String, Object> tokenMap = new HashMap<String, Object>();
+		    	tokenMap.put("access_token", accessToken);
+		    	tokenMap.put("userid", ob.getString("userid"));
+		    	String userStr = HttpHelper.sendGetByHttpUrlConnection("https://oapi.dingtalk.com/user/get", tokenMap, "UTF-8");
+		    	JSONObject userObject = JSON.parseObject(userStr);
+				userSB.append(userObject.getString("name")).append(blankCode);
+				//获取操作结果
+				if ("EXECUTE_TASK_NORMAL".equals(ob.getString("operation_type"))){
+					userSB.append(dingdingUtil.getTaskResult(ob.getString("operation_result")));
+					if (StringUtils.isNotEmpty(ob.getString("remark"))){
+						userSB.append("(").append(ob.getString("remark")).append(")").append(blankCode);
+					}
+					userSB.append(blankCode);
+				}else if ("ADD_REMARK".equals(ob.getString("operation_type"))){
+					userSB.append("添加评论(").append(ob.getString("remark")).append(")").append(blankCode);
+				}else {
+					userSB.append(dingdingUtil.getTaskResult(ob.getString("operation_result"))).append(blankCode);
+				}
+				userSB.append(ob.getString("date") == null ? "" : ob.getString("date")).append("</td></tr>");
+			}
+		}
+		return userSB;
+	}
+	
+	private StringBuffer generateForm(JSONObject result) {
+		JSONArray formArray = result.getJSONObject("form_component_values").getJSONArray("form_component_value_vo");
+		StringBuffer formSB = null;
+		if (formArray != null && formArray.size() > 0){
+			formSB = new StringBuffer();
+			for (Object o : formArray){
+				JSONObject ob = (JSONObject) o;
+				// 图片、附件、说明的行不显示
+				if ("图片".equals(ob.getString("name")) 
+						|| "附件".equals(ob.getString("name")) 
+						|| "说明".equals(ob.getString("name")) 
+						|| "null".equals(ob.getString("name"))
+						|| null == ob.getString("name")){
+					continue;
+				} 
+				// 处理表单中表单名是否是json对象,如[开始时间、结束时间]
+				if (dingdingUtil.isJSONValid(ob.getString("name"))){
+					JSONArray array = JSON.parseArray(ob.getString("name"));
+					if (array != null){
+						formSB.append("<tr><td>");
+						for (int i = 0; i < array.size(); i++){
+							formSB.append(array.get(i)).append(i == array.size() - 1 ? "" : "/");
+						}
+						formSB.append("</td><td>");
+					}
+				}else{
+					formSB.append("<tr><td>").append(ob.getString("name")).append("</td><td>");
+				}
+				//处理表单中表单名对应的表单值,空值不显示
+				String value = ob.getString("value");
+				if ("null".equals(value)){
+					formSB.append("");
+					//处理表单值是否是json对象
+				}else if (dingdingUtil.isJSONValid(value)){
+					JSONArray array = JSON.parseArray(ob.getString("value"));
+					for (int i = 0; i < array.size(); i++){
+						if (array.get(i) instanceof String || array.get(i) instanceof Integer || array.get(i) instanceof BigDecimal){
+							formSB.append(array.get(i)).append(i == array.size() - 1 ? "" : blankCode);
+						}
+						else {
+							JSONObject objecte = (JSONObject)array.get(i);
+							JSONArray rowValue = objecte.getJSONArray("rowValue");
+							if (rowValue != null){
+								for (Object rowObj : rowValue){
+									JSONObject row = (JSONObject)rowObj;
+									formSB.append("<p>");
+									if (dingdingUtil.isJSONValid(row.getString("label"))){
+										JSONArray labelArray = JSON.parseArray(row.getString("label"));
+										if (labelArray != null){
+											for (int j = 0; j < labelArray.size(); j++){
+												formSB.append(labelArray.get(j)).append(j == labelArray.size() - 1 ? "" : "/");
+											}
+										}
+									}else if ("说明".equals(row.getString("label")) 
+											|| "null".equals(row.getString("label"))
+											|| null == row.getString("label")){
+										formSB.append("</p>");
+										continue;
+									}else{
+										formSB.append(row.getString("label"));
+									}
+									formSB.append(":");
+									if (dingdingUtil.isJSONValid(row.getString("value"))){
+										JSONArray valueArray = JSON.parseArray(row.getString("value"));
+										if (valueArray != null){
+											for (int j = 0; j < valueArray.size(); j++){
+												formSB.append(valueArray.get(j)).append(j == valueArray.size() - 1 ? "" : "/");
+											}
+										}
+									}else{
+										formSB.append(row.getString("value")).append(blankCode);
+									}
+									formSB.append("</p>");
+								}
+							}else{
+//								formSB.append("<td><tr>");
+							}
+						}
+						if (i != array.size() - 1){
+							formSB.append("<p>&nbsp;&nbsp;</p>");
+						}
+					}
+
+					// 2022-2-23 by owen 钉钉返回的数据会导致解析异常
+//					if (ob.getString("ext_value") != null){
+//
+//						JSONArray objArr = JSON.parseObject(ob.getString("ext_value")).getJSONArray("statValue");
+//
+//						if (objArr.size() > 0){
+//							formSB.append("<p>&nbsp;&nbsp;</p>");
+//							for (int i = 0; i < objArr.size(); i++){
+//								JSONObject objecte = (JSONObject)objArr.get(i);
+//								formSB.append(objecte.getString("label")).append(":").append(objecte.getString("num")).append("(").append(objecte.getString("upper")).append(")");
+//								if (i != objArr.size() - 1){
+//									formSB.append("<p>&nbsp;&nbsp;</p>");
+//								}
+//							}
+//						}
+//						}
+					
+				}else{
+					formSB.append(value);
+				}
+				formSB.append("</td></tr>");
+			}
+		}
+		return formSB;
+	}
+	
+	private String getDetailHtml(String accessToken, JSONObject jsonResult, String type) {
+		StringBuffer sb = new StringBuffer();
+		JSONObject result = jsonResult.getJSONObject("process_instance");
+		if (result != null){
+			
+			DataDictionary corp = dataDictionaryService.findByCodeAndDataKey("corp_code", dingdingUtil.getRegion());
+			
+			//企业名称
+			String corpName = corp.getDataValue();
+			//申请日期
+			String applyDate = result.getString("create_time");
+			//审批编码
+			String businessId = result.getString("business_id");
+			String[] titles = result.getString("title").split("的");
+			//申请人
+			String applyUserName = titles[0];
+			//模板名称
+			String title = titles[1];
+			//申请人部门
+			String org = result.getString("originator_dept_name");
+			
+			sb.append("<!DOCTYPE html> ")		
+			.append("<html lang=\"en\">").append("<head>")
+			.append("<meta charset=\"UTF-8\" />")
+			.append("<style> ").append("body{font-family:SimHei;} .content{width: 100%; margin: 0 auto; margin-top: 30px;} h2{text-align:center;} .mgrl-10{margin-left:30px;} table tr{height: 30px;} table td {word-wrap:break-word;word-break:break-all;}").append("</style>")
+			.append("</head>").append("<body>") 
+			.append("<div class=\"content\">")
+			.append("<h2>").append(title).append("</h2>")
+			.append("<span>").append(corpName).append("</span>").append("            ").append("<span class=\"mgrl-10\">申请日期:").append(applyDate).append("</span>")
+			.append("            ").append("<span class=\"mgrl-10\" style=\"color: red;\">审批状态:").append(dingdingUtil.getStatus(result.getString("status"))).append("</span>")
+			.append("<table border=\"1\" cellspacing=\"0\" width=100% >")
+			.append("<tr><td style=\"width:20%\">审批编码</td><td>").append(businessId).append("</td></tr>")
+			.append("<tr><td>申请人</td><td>").append(applyUserName).append("</td></tr>")
+			.append("<tr><td>申请人部门</td><td>").append(org).append("</td></tr>");
+			
+			//表单内容,循环生成表单内容
+			StringBuffer formSB = generateForm(result);
+			sb.append(formSB);
+			
+			//审批人
+			StringBuffer userSB = generateOperators(accessToken, result);
+			sb.append(userSB).append("</table>");
+			
+			if ("download".equals(type)){
+				Subject subject = SecurityUtils.getSubject();
+	            Object principal = subject.getPrincipal();
+	            String userName = "";
+	            if (principal != null) {
+	            	userName = ((User) principal).getNickName();
+	            }
+				sb.append("<span>打印时间:").append(new DateTime().toString("yyyy-MM-dd HH:mm")).append("</span>            <span class=\"mgrl-10\">打印人:").append(userName).append("</span></div>");
+			}
+			sb.append("</body></html>");  
+		}
+		return sb.toString();
+	}
+
+}

+ 137 - 0
src/main/java/com/fourdage/dingding/util/ZipUtil.java

@@ -0,0 +1,137 @@
+package com.fourdage.dingding.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ZipUtil {
+	
+private static final int  BUFFER_SIZE = 2 * 1024;
+	
+	/**
+	 * 压缩成ZIP 方法1
+	 * @param srcDir 压缩文件夹路径 
+	 * @param out    压缩文件输出流
+	 * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构; 
+	 * 							false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
+	 * @throws RuntimeException 压缩失败会抛出运行时异常
+	 */
+	public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
+			throws RuntimeException{
+		
+		long start = System.currentTimeMillis();
+		ZipOutputStream zos = null ;
+		try {
+			zos = new ZipOutputStream(out);
+			File sourceFile = new File(srcDir);
+			compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
+			long end = System.currentTimeMillis();
+			System.out.println("压缩完成,耗时:" + (end - start) +" ms");
+		} catch (Exception e) {
+			throw new RuntimeException("zip error from ZipUtils",e);
+		}finally{
+			if(zos != null){
+				try {
+					zos.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		
+	}
+	
+	/**
+	 * 压缩成ZIP 方法2
+	 * @param srcFiles 需要压缩的文件列表
+	 * @param out 	        压缩文件输出流
+	 * @throws RuntimeException 压缩失败会抛出运行时异常
+	 */
+	public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
+		long start = System.currentTimeMillis();
+		ZipOutputStream zos = null ;
+		try {
+			zos = new ZipOutputStream(out);
+			for (File srcFile : srcFiles) {
+				byte[] buf = new byte[BUFFER_SIZE];
+				zos.putNextEntry(new ZipEntry(srcFile.getName()));
+				int len;
+				FileInputStream in = new FileInputStream(srcFile);
+				while ((len = in.read(buf)) != -1){
+					zos.write(buf, 0, len);
+				}
+				zos.closeEntry();
+				in.close();
+			}
+			long end = System.currentTimeMillis();
+			System.out.println("压缩完成,耗时:" + (end - start) +" ms");
+		} catch (Exception e) {
+			throw new RuntimeException("zip error from ZipUtils",e);
+		}finally{
+			if(zos != null){
+				try {
+					zos.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	 * 递归压缩方法
+	 * @param sourceFile 源文件
+	 * @param zos		 zip输出流
+	 * @param name		 压缩后的名称
+	 * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构; 
+	 * 							false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
+	 * @throws Exception
+	 */
+	private static void compress(File sourceFile, ZipOutputStream zos, String name,
+			boolean KeepDirStructure) throws Exception{
+		byte[] buf = new byte[BUFFER_SIZE];
+		if(sourceFile.isFile()){
+			// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
+			zos.putNextEntry(new ZipEntry(name));
+			// copy文件到zip输出流中
+			int len;
+			FileInputStream in = new FileInputStream(sourceFile);
+			while ((len = in.read(buf)) != -1){
+				zos.write(buf, 0, len);
+			}
+			// Complete the entry
+			zos.closeEntry();
+			in.close();
+		} else {
+			File[] listFiles = sourceFile.listFiles();
+			if(listFiles == null || listFiles.length == 0){
+				// 需要保留原来的文件结构时,需要对空文件夹进行处理
+				if(KeepDirStructure){
+					// 空文件夹的处理
+					zos.putNextEntry(new ZipEntry(name + "/"));
+					// 没有文件,不需要文件的copy
+					zos.closeEntry();
+				}
+				
+			}else {
+				for (File file : listFiles) {
+					// 判断是否需要保留原来的文件结构
+					if (KeepDirStructure) {
+						// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
+						// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
+						compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
+					} else {
+						compress(file, zos, file.getName(),KeepDirStructure);
+					}
+					
+				}
+			}
+		}
+	}
+
+}

+ 133 - 0
src/main/java/com/fourdage/dingding/util/ZipUtils.java

@@ -0,0 +1,133 @@
+package com.fourdage.dingding.util;
+
+import java.io.*;
+import java.util.Properties;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarInputStream;
+
+
+public class ZipUtils {
+
+    /**
+     * 构建目录
+     * @param outputDir
+     * @param subDir
+     */
+    public static void createDirectory(String outputDir,String subDir){
+        File file = new File(outputDir);
+        if(!(subDir == null || subDir.trim().equals(""))){//子目录不为空
+            file = new File(outputDir + "/" + subDir);
+        }
+        if(!file.exists()){
+            if(!file.getParentFile().exists())
+                file.getParentFile().mkdirs();
+            file.mkdirs();
+        }
+    }
+
+    //------------------------------------------------------------------------------------------------------
+    /**
+     * 解压tar.gz 文件
+     * @param file 要解压的tar.gz文件对象
+     * @param outputDir 要解压到某个指定的目录下
+     * @throws IOException
+     */
+    public static void unTarGz(File file, String outputDir) throws IOException{
+        TarInputStream tarIn = null;
+        try{
+            tarIn = new TarInputStream(new GZIPInputStream(
+                    new BufferedInputStream(new FileInputStream(file))),
+                    1024 * 2);
+
+            createDirectory(outputDir,null);//创建输出目录
+
+            TarEntry entry = null;
+            while( (entry = tarIn.getNextEntry()) != null ){
+
+                if(entry.isDirectory()){//是目录
+                    entry.getName();
+                    createDirectory(outputDir,entry.getName());//创建空目录
+                }else{//是文件
+                    File tmpFile = new File(outputDir + "/" + entry.getName());
+                    createDirectory(tmpFile.getParent() + "/",null);//创建输出目录
+                    OutputStream out = null;
+                    try{
+                        out = new FileOutputStream(tmpFile);
+                        int length = 0;
+
+                        byte[] b = new byte[2048];
+
+                        while((length = tarIn.read(b)) != -1){
+                            out.write(b, 0, length);
+                        }
+
+                    }catch(IOException ex){
+                        throw ex;
+                    }finally{
+
+                        if(out!=null)
+                            out.close();
+                    }
+                }
+            }
+        }catch(IOException ex){
+            throw new IOException("解压归档文件出现异常",ex);
+        } finally{
+            try{
+                if(tarIn != null){
+                    tarIn.close();
+                }
+            }catch(IOException ex){
+                throw new IOException("关闭tarFile出现异常",ex);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws IOException, InterruptedException {
+        String path = "/data/557662992913661952/";
+        String fileName = "copy.tar.gz";
+        File f = new File(path);
+
+        Properties prop = System.getProperties();
+        String os = prop.getProperty("os.name");
+        if (os != null && os.toLowerCase().indexOf("linux") > -1) {
+            // linux 执行合并文件命令
+            StringBuffer sb = new StringBuffer(" cat ");
+            for (int i = 0; i < f.listFiles().length; i++){
+                sb.append(f.listFiles()[i].getAbsolutePath());
+            }
+            sb.append(" >> ").append(path).append(fileName);
+
+            String[] cmd = new String[]{"/bin/sh", "-c", sb.toString()};
+            Process process = Runtime.getRuntime().exec(cmd);
+            int exitValue = process.waitFor();
+            process.getOutputStream().close();
+            if (0 == exitValue){
+                System.out.println(path+fileName+":合并完成");
+                unTarGz(new File(path + fileName), path);
+                System.out.println(path+fileName+":解压完成");
+            }
+        } else {
+            // windows 执行合并文件命令
+            StringBuffer sb = new StringBuffer("cmd.exe /c copy /b ");
+            for (int i = 0; i < f.listFiles().length; i++){
+                sb.append(f.listFiles()[i].getAbsolutePath());
+                if (i != f.listFiles().length -1){
+                    sb.append("+");
+                }
+            }
+            sb.append(" ").append(path).append(fileName);
+            System.out.println(sb.toString());
+            Process process = Runtime.getRuntime().exec(sb.toString());
+            int exitValue = process.waitFor();
+            process.getOutputStream().close();
+            if (0 == exitValue){
+                System.out.println(path+fileName+":合并完成");
+                unTarGz(new File(path + fileName), path);
+                System.out.println(path+fileName+":解压完成");
+            }
+        }
+    }
+}

+ 78 - 0
src/main/java/com/fourdage/system/controller/DataDictionaryController.java

@@ -0,0 +1,78 @@
+package com.fourdage.system.controller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.fourdage.base.common.JsonResult;
+import com.fourdage.base.controller.BaseController;
+import com.fourdage.system.entity.DataDictionary;
+import com.fourdage.system.service.IDataDictionaryService;
+
+@Controller
+@RequestMapping("/admin/dataDictionary")
+public class DataDictionaryController extends BaseController{
+	
+	private Logger logger = LoggerFactory.getLogger(getClass());
+	
+	@Autowired
+    private IDataDictionaryService dataDictionaryService;
+
+    @RequestMapping(value = {"/index"})
+    public String index(ModelMap modelMap) {
+        Page<DataDictionary> page = dataDictionaryService.findAll(getPageRequest());
+        modelMap.put("pageInfo", page);
+        return "admin/dataDictionary/index";
+    }
+
+    @RequestMapping(value = "/add", method = RequestMethod.GET)
+    public String add(ModelMap map) {
+        return "admin/dataDictionary/form";
+    }
+
+
+    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
+    public String edit(@PathVariable Integer id, ModelMap map) {
+        DataDictionary dataDictionary = dataDictionaryService.find(id);
+        map.put("dataDictionary", dataDictionary);
+        return "admin/dataDictionary/form";
+    }
+
+
+    @RequestMapping(value = {"/edit"}, method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult edit(DataDictionary dataDictionary, ModelMap map) {
+        try {
+        	
+        	DataDictionary dbDictionary = dataDictionaryService.findByCodeAndDataKey(dataDictionary.getCode(), dataDictionary.getDataKey());
+        	if (dbDictionary != null){
+        		return JsonResult.failure("您所输入的数据类型代码和数据键已存在,请修改后再提交!");
+        	}
+        	dataDictionaryService.saveOrUpdate(dataDictionary);
+        } catch (Exception e) {
+        	logger.error("系统异常:", e);
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+    
+    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult delete(@PathVariable Integer id, ModelMap map) {
+        try {
+        	dataDictionaryService.delete(id);
+        } catch (Exception e) {
+        	logger.error("系统异常:", e);
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+}

+ 86 - 0
src/main/java/com/fourdage/system/controller/ResourceController.java

@@ -0,0 +1,86 @@
+package com.fourdage.system.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.fourdage.base.common.JsonResult;
+import com.fourdage.base.controller.BaseController;
+import com.fourdage.base.vo.ZtreeView;
+import com.fourdage.system.entity.Resource;
+import com.fourdage.system.service.IResourceService;
+
+@Controller
+@RequestMapping("/admin/resource")
+public class ResourceController extends BaseController {
+    @Autowired
+    private IResourceService resourceService;
+
+    @RequestMapping("/tree/{resourceId}")
+    @ResponseBody
+    public List<ZtreeView> tree(@PathVariable Integer resourceId) {
+        List<ZtreeView> list = resourceService.tree(resourceId);
+        return list;
+    }
+
+    @RequestMapping("/index")
+    public String index(ModelMap map) {
+        Page<Resource> page = resourceService.findAll(getPageRequest());
+        map.put("pageInfo", page);
+        return "admin/resource/index";
+    }
+
+    @RequestMapping(value = "/add", method = RequestMethod.GET)
+    public String add(ModelMap map) {
+        List<Resource> list = resourceService.findAll();
+        map.put("list", list);
+        return "admin/resource/form";
+    }
+
+
+    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
+    public String edit(@PathVariable Integer id, ModelMap map) {
+        Resource resource = resourceService.find(id);
+        map.put("resource", resource);
+
+        List<Resource> list = resourceService.findAll();
+        map.put("list", list);
+        return "admin/resource/form";
+    }
+
+    @RequestMapping(value = {"/edit"}, method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult edit(Resource resource, Integer parentId, ModelMap map) {
+        try {
+            if (parentId != null) {
+                Resource parent = new Resource();
+                parent.setId(parentId);
+                resource.setParent(parent);
+            }
+            resourceService.saveOrUpdate(resource);
+        } catch (Exception e) {
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult delete(@PathVariable Integer id, ModelMap map) {
+        try {
+            resourceService.delete(id);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+}

+ 88 - 0
src/main/java/com/fourdage/system/controller/RoleController.java

@@ -0,0 +1,88 @@
+package com.fourdage.system.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.fourdage.base.common.JsonResult;
+import com.fourdage.base.controller.BaseController;
+import com.fourdage.system.entity.Role;
+import com.fourdage.system.service.IRoleService;
+
+@Controller
+@RequestMapping("/admin/role")
+public class RoleController extends BaseController {
+
+    @Autowired
+    private IRoleService roleService;
+
+    @RequestMapping(value = {"/index"})
+    public String index(ModelMap modelMap) {
+        Page<Role> page = roleService.findAll(getPageRequest());
+        modelMap.put("pageInfo", page);
+        return "admin/role/index";
+    }
+
+    @RequestMapping(value = "/add", method = RequestMethod.GET)
+    public String add(ModelMap map) {
+        return "admin/role/form";
+    }
+
+
+    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
+    public String edit(@PathVariable Integer id, ModelMap map) {
+        Role role = roleService.find(id);
+        map.put("role", role);
+        return "admin/role/form";
+    }
+
+
+    @RequestMapping(value = {"/edit"}, method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult edit(Role role, ModelMap map) {
+        try {
+            roleService.saveOrUpdate(role);
+        } catch (Exception e) {
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult delete(@PathVariable Integer id, ModelMap map) {
+        try {
+            roleService.delete(id);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+    @RequestMapping(value = "/grant/{id}", method = RequestMethod.GET)
+    public String grant(@PathVariable Integer id, ModelMap map) {
+        Role role = roleService.find(id);
+        map.put("role", role);
+        return "admin/role/grant";
+    }
+
+    @RequestMapping(value = "/grant/{id}", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult grant(@PathVariable Integer id,
+                            @RequestParam(required = false) String[] resourceIds, ModelMap map) {
+        try {
+            roleService.grant(id, resourceIds);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+}

+ 127 - 0
src/main/java/com/fourdage/system/controller/UserController.java

@@ -0,0 +1,127 @@
+package com.fourdage.system.controller;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.fourdage.base.common.JsonResult;
+import com.fourdage.base.controller.BaseController;
+import com.fourdage.system.entity.Role;
+import com.fourdage.system.entity.User;
+import com.fourdage.system.service.IRoleService;
+import com.fourdage.system.service.IUserService;
+
+@Controller
+@RequestMapping("/admin/user")
+public class UserController extends BaseController {
+
+    @Autowired
+    private IUserService userService;
+    @Autowired
+    private IRoleService roleService;
+
+    @RequestMapping(value = {"/index"})
+    public String index(ModelMap modelMap) {
+        Page<User> page = userService.findAll(getPageRequest());
+        modelMap.put("pageInfo", page);
+        return "admin/user/index";
+    }
+
+    @RequestMapping(value = "/add", method = RequestMethod.GET)
+    public String add(ModelMap map) {
+        return "admin/user/form";
+    }
+
+    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
+    public String edit(@PathVariable Integer id, ModelMap map) {
+        User user = userService.find(id);
+        map.put("user", user);
+        return "admin/user/form";
+    }
+
+    @RequestMapping(value = {"/edit"}, method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult edit(User user, ModelMap map) {
+        try {
+            userService.saveOrUpdate(user);
+        } catch (Exception e) {
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult delete(@PathVariable Integer id, ModelMap map) {
+        try {
+            userService.delete(id);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+    @RequestMapping(value = "/grant/{id}", method = RequestMethod.GET)
+    public String grant(@PathVariable Integer id, ModelMap map) {
+        User user = userService.find(id);
+        map.put("user", user);
+
+        Set<Role> set = user.getRoles();
+        List<Integer> roleIds = new ArrayList<Integer>();
+        for (Role role : set) {
+            roleIds.add(role.getId());
+        }
+        map.put("roleIds", roleIds);
+
+        List<Role> roles = roleService.findAll();
+        map.put("roles", roles);
+        return "admin/user/grant";
+    }
+
+    @ResponseBody
+    @RequestMapping(value = "/grant/{id}", method = RequestMethod.POST)
+    public JsonResult grant(@PathVariable Integer id, String[] roleIds, ModelMap map) {
+        try {
+            userService.grant(id, roleIds);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+
+    @RequestMapping(value = "/updatePwd", method = RequestMethod.GET)
+    public String updatePwd() {
+        return "admin/user/updatePwd";
+    }
+
+    @RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
+    @ResponseBody
+    public JsonResult updatePwd(String oldPassword, String password1, String password2) {
+        try {
+            Subject subject = SecurityUtils.getSubject();
+            Object principal = subject.getPrincipal();
+            if (principal == null) {
+                return JsonResult.failure("您尚未登录");
+            }
+            userService.updatePwd((User) principal, oldPassword, password1, password2);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonResult.failure("系统异常:"+e);
+        }
+        return JsonResult.success();
+    }
+}

+ 17 - 0
src/main/java/com/fourdage/system/dao/IDataDictionaryDao.java

@@ -0,0 +1,17 @@
+package com.fourdage.system.dao;
+
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.system.entity.DataDictionary;
+
+@Repository
+public interface IDataDictionaryDao extends IBaseDao<DataDictionary, Integer>{
+
+	DataDictionary findByCodeAndDataKey(String code, String dataKey);
+
+	List<DataDictionary> findByCode(String code);
+
+}

+ 26 - 0
src/main/java/com/fourdage/system/dao/IResourceDao.java

@@ -0,0 +1,26 @@
+package com.fourdage.system.dao;
+
+import java.util.List;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.system.entity.Resource;
+
+@Repository
+public interface IResourceDao extends IBaseDao<Resource, Integer> {
+
+    @Modifying
+    @Query(nativeQuery = true, value = "DELETE FROM tb_role_resource WHERE resource_id = :id")
+    void deleteGrant(@Param("id") Integer id);
+
+    Page<Resource> findAllByNameContaining(String searchText, Pageable pageable);
+
+    List<Resource> findAllByOrderByParentAscIdAscSortAsc();
+
+}

+ 15 - 0
src/main/java/com/fourdage/system/dao/IRoleDao.java

@@ -0,0 +1,15 @@
+package com.fourdage.system.dao;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Repository;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.system.entity.Role;
+
+@Repository
+public interface IRoleDao extends IBaseDao<Role, Integer> {
+
+    Page<Role> findAllByNameContainingOrDescriptionContaining(String searchText1, String searchText2, Pageable pageable);
+
+}

+ 17 - 0
src/main/java/com/fourdage/system/dao/IUserDao.java

@@ -0,0 +1,17 @@
+package com.fourdage.system.dao;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Repository;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.system.entity.User;
+
+@Repository
+public interface IUserDao extends IBaseDao<User, Integer> {
+
+    User findByUserName(String username);
+
+    Page<User> findAllByNickNameContaining(String searchText, Pageable pageable);
+
+}

+ 112 - 0
src/main/java/com/fourdage/system/entity/DataDictionary.java

@@ -0,0 +1,112 @@
+package com.fourdage.system.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fourdage.base.entity.BaseEntity;
+
+/**
+ * <p>
+ * 数据字典表
+ * </p>
+ *
+ * @author ajay peng
+ * @since 2018-5-2
+ */
+@Entity
+@Table(name = "tb_data_dictionary")
+public class DataDictionary extends BaseEntity{
+
+	private static final long serialVersionUID = 8298772755860196L;
+	
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "id", nullable = false)
+    private Integer id;
+	
+    @Column(length = 24)
+    private String code;
+    
+    private String dataKey;
+    
+    private String dataValue;
+    
+    private String description;
+    
+    private String param1;
+    
+    private String param2;
+    
+    private String param3;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+		public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getDataKey() {
+		return dataKey;
+	}
+
+	public void setDataKey(String dataKey) {
+		this.dataKey = dataKey;
+	}
+
+	public String getDataValue() {
+		return dataValue;
+	}
+
+	public void setDataValue(String dataValue) {
+		this.dataValue = dataValue;
+	}
+
+	public String getParam1() {
+		return param1;
+	}
+
+	public String getParam2() {
+		return param2;
+	}
+
+	public String getParam3() {
+		return param3;
+	}
+
+	public void setParam1(String param1) {
+		this.param1 = param1;
+	}
+
+	public void setParam2(String param2) {
+		this.param2 = param2;
+	}
+
+	public void setParam3(String param3) {
+		this.param3 = param3;
+	}
+    
+    
+
+}

+ 207 - 0
src/main/java/com/fourdage/system/entity/Resource.java

@@ -0,0 +1,207 @@
+package com.fourdage.system.entity;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fourdage.base.entity.BaseEntity;
+
+/**
+ * <p>
+ * 资源表
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+@Entity
+@Table(name = "tb_resource")
+public class Resource extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 资源id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "id", nullable = false)
+    private Integer id;
+
+    /**
+     * 资源名称
+     */
+    private String name;
+
+    /**
+     * 资源唯一标识
+     */
+    private String sourceKey;
+
+    /**
+     * 资源类型,0:目录;1:菜单;2:按钮
+     */
+    private Integer type;
+
+    /**
+     * 资源url
+     */
+    private String sourceUrl;
+
+    /**
+     * 层级
+     */
+    private Integer level;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 图标
+     */
+    private String icon;
+
+    /**
+     * 是否隐藏
+     * <p>
+     * 0显示 1隐藏
+     */
+    private Integer isHide;
+
+    /**
+     * 描述
+     */
+    private String description;
+
+    /**
+     * 创建时间
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "parent_id")
+    private Resource parent;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSourceKey() {
+        return sourceKey;
+    }
+
+    public void setSourceKey(String sourceKey) {
+        this.sourceKey = sourceKey;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public String getSourceUrl() {
+        return sourceUrl;
+    }
+
+    public void setSourceUrl(String sourceUrl) {
+        this.sourceUrl = sourceUrl;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Integer getSort() {
+        return sort;
+    }
+
+    public void setSort(Integer sort) {
+        this.sort = sort;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public Integer getIsHide() {
+        return isHide;
+    }
+
+    public void setIsHide(Integer isHide) {
+        this.isHide = isHide;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public Resource getParent() {
+        return parent;
+    }
+
+    public void setParent(Resource parent) {
+        this.parent = parent;
+    }
+
+}

+ 145 - 0
src/main/java/com/fourdage/system/entity/Role.java

@@ -0,0 +1,145 @@
+package com.fourdage.system.entity;
+
+import java.util.Date;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fourdage.base.entity.BaseEntity;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+@Entity
+@Table(name = "tb_role")
+public class Role extends BaseEntity {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -1894163644285296223L;
+
+    /**
+     * 角色id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "id", nullable = false)
+    private Integer id;
+
+    /**
+     * 角色名称
+     */
+    private String name;
+
+    /**
+     * 角色key
+     */
+    private String roleKey;
+
+    /**
+     * 角色状态,0:正常;1:删除
+     */
+    private Integer status;
+
+    /**
+     * 角色描述
+     */
+    private String description;
+
+    /**
+     * 创建时间
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.LAZY)
+    @JoinTable(name = "tb_role_resource", joinColumns = {@JoinColumn(name = "role_id")}, inverseJoinColumns = {@JoinColumn(name = "resource_id")})
+    private java.util.Set<Resource> resources;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getRoleKey() {
+        return roleKey;
+    }
+
+    public void setRoleKey(String roleKey) {
+        this.roleKey = roleKey;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public java.util.Set<Resource> getResources() {
+        return resources;
+    }
+
+    public void setResources(java.util.Set<Resource> resources) {
+        this.resources = resources;
+    }
+
+}

+ 249 - 0
src/main/java/com/fourdage/system/entity/User.java

@@ -0,0 +1,249 @@
+package com.fourdage.system.entity;
+
+import java.util.Date;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fourdage.base.entity.BaseEntity;
+
+/**
+ * <p>
+ * 用户账户表
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+@Entity
+@Table(name = "tb_user")
+public class User extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "id", nullable = false)
+    private Integer id;
+
+    /**
+     * 账户名
+     */
+    private String userName;
+
+    /**
+     * 昵称
+     */
+    private String nickName;
+
+    /**
+     * 头像地址
+     */
+    private String avatar;
+
+    /**
+     * 用户密码
+     */
+    private String password;
+
+    /**
+     * 性别 0 女 1 男
+     */
+    private Integer sex;
+
+    /**
+     * 出生日期
+     */
+    @JSONField(format = "yyyy-MM-dd")
+    private Date birthday;
+
+    /**
+     * 电话
+     */
+    private String telephone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 住址
+     */
+    private String address;
+
+    /**
+     * 逻辑删除状态 0 未删除 1 删除
+     */
+    private Integer deleteStatus;
+
+    /**
+     * 是否锁定
+     * <p>
+     * 0 未锁定 1 锁定
+     */
+    private Integer locked;
+
+    /**
+     * 用户描述
+     */
+    private String description;
+
+    /**
+     * 创建时间
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.LAZY)
+    @JoinTable(name = "tb_user_role", joinColumns = {@JoinColumn(name = "user_id")}, inverseJoinColumns = {@JoinColumn(name = "role_id")})
+    private java.util.Set<Role> roles;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getNickName() {
+        return nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public Integer getSex() {
+        return sex;
+    }
+
+    public void setSex(Integer sex) {
+        this.sex = sex;
+    }
+
+    public Date getBirthday() {
+        return birthday;
+    }
+
+    public void setBirthday(Date birthday) {
+        this.birthday = birthday;
+    }
+
+    public String getTelephone() {
+        return telephone;
+    }
+
+    public void setTelephone(String telephone) {
+        this.telephone = telephone;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public Integer getDeleteStatus() {
+        return deleteStatus;
+    }
+
+    public void setDeleteStatus(Integer deleteStatus) {
+        this.deleteStatus = deleteStatus;
+    }
+
+    public Integer getLocked() {
+        return locked;
+    }
+
+    public void setLocked(Integer locked) {
+        this.locked = locked;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public Set<Role> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(Set<Role> roles) {
+        this.roles = roles;
+    }
+}

+ 46 - 0
src/main/java/com/fourdage/system/service/IDataDictionaryService.java

@@ -0,0 +1,46 @@
+package com.fourdage.system.service;
+
+import java.util.List;
+
+import com.fourdage.base.service.IBaseService;
+import com.fourdage.system.entity.DataDictionary;
+
+/**
+ * <p>
+ * 数据字典服务类
+ * </p>
+ *
+ * @author ajay peng
+ * @since 2018-05-02
+ */
+public interface IDataDictionaryService extends IBaseService<DataDictionary, Integer>{
+	
+    /**
+     * 修改或者新增资源
+     *
+     * @param DataDictionary
+     */
+    void saveOrUpdate(DataDictionary dataDictionary);
+    
+    /**
+     * 根据code和dateKey查找
+     *
+     * @param DataDictionary
+     */
+    DataDictionary findByCodeAndDataKey(String code, String dataKey);
+
+    /**
+     * 根据code查找
+     *
+     * @param DataDictionary
+     */
+	List<DataDictionary> findByCode(String code);
+	
+    /**
+     * 根据条件查找
+     *
+     * @param DataDictionary
+     */
+	List<DataDictionary> findByCondition(DataDictionary dataDictionary);
+
+}

+ 46 - 0
src/main/java/com/fourdage/system/service/IResourceService.java

@@ -0,0 +1,46 @@
+package com.fourdage.system.service;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+
+import com.fourdage.base.service.IBaseService;
+import com.fourdage.base.vo.ZtreeView;
+import com.fourdage.system.entity.Resource;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 资源服务类
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+public interface IResourceService extends IBaseService<Resource, Integer> {
+
+    /**
+     * 获取角色的权限树
+     *
+     * @param roleId
+     * @return
+     */
+    List<ZtreeView> tree(int roleId);
+
+    /**
+     * 修改或者新增资源
+     *
+     * @param resource
+     */
+    void saveOrUpdate(Resource resource);
+
+    /**
+     * 关键字分页
+     *
+     * @param searchText
+     * @param pageRequest
+     * @return
+     */
+    Page<Resource> findAllByLike(String searchText, PageRequest pageRequest);
+
+}

+ 43 - 0
src/main/java/com/fourdage/system/service/IRoleService.java

@@ -0,0 +1,43 @@
+package com.fourdage.system.service;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+
+import com.fourdage.base.service.IBaseService;
+import com.fourdage.system.entity.Role;
+
+/**
+ * <p>
+ * 角色服务类
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+public interface IRoleService extends IBaseService<Role, Integer> {
+
+    /**
+     * 添加或者修改角色
+     *
+     * @param role
+     */
+    void saveOrUpdate(Role role);
+
+    /**
+     * 给角色分配资源
+     *
+     * @param id          角色ID
+     * @param resourceIds 资源ids
+     */
+    void grant(Integer id, String[] resourceIds);
+
+    /**
+     * 根据关键字查询分页
+     *
+     * @param searchText
+     * @param pageRequest
+     * @return
+     */
+    Page<Role> findAllByLike(String searchText, PageRequest pageRequest);
+
+}

+ 61 - 0
src/main/java/com/fourdage/system/service/IUserService.java

@@ -0,0 +1,61 @@
+package com.fourdage.system.service;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+
+import com.fourdage.base.service.IBaseService;
+import com.fourdage.system.entity.User;
+
+/**
+ * <p>
+ * 用户服务类
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+public interface IUserService extends IBaseService<User, Integer> {
+
+    /**
+     * 根据用户名查找用户
+     *
+     * @param username
+     * @return
+     */
+    User findByUserName(String username);
+
+    /**
+     * 增加或者修改用户
+     *
+     * @param user
+     */
+    void saveOrUpdate(User user);
+
+    /**
+     * 给用户分配角色
+     *
+     * @param id      用户ID
+     * @param roleIds 角色Ids
+     */
+    void grant(Integer id, String[] roleIds);
+
+    /**
+     * 根据关键字获取分页
+     *
+     * @param searchText
+     * @param pageRequest
+     * @return
+     */
+    Page<User> findAllByLike(String searchText, PageRequest pageRequest);
+
+    /**
+     * 修改用户密码
+     *
+     * @param user
+     * @param oldPassword
+     * @param password1
+     * @param password2
+     */
+    void updatePwd(User user, String oldPassword, String password1, String password2);
+
+}

+ 101 - 0
src/main/java/com/fourdage/system/service/impl/DataDictionaryServiceImpl.java

@@ -0,0 +1,101 @@
+package com.fourdage.system.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.service.impl.BaseServiceImpl;
+import com.fourdage.system.dao.IDataDictionaryDao;
+import com.fourdage.system.entity.DataDictionary;
+import com.fourdage.system.service.IDataDictionaryService;
+
+/**
+ * <p>
+ *  数据字典 服务实现类
+ * </p>
+ *
+ * @author ajay peng
+ * @since 2016-12-28
+ */
+@Service
+public class DataDictionaryServiceImpl extends BaseServiceImpl<DataDictionary, Integer> implements IDataDictionaryService {
+
+    @Autowired
+    private IDataDictionaryDao dataDictionaryDao;
+
+    @Override
+    public IBaseDao<DataDictionary, Integer> getBaseDao() {
+        return this.dataDictionaryDao;
+    }
+    
+    @Override
+    public void saveOrUpdate(DataDictionary dataDictionary) {
+        if (dataDictionary.getId() != null) {
+        	DataDictionary dbDictionary = find(dataDictionary.getId());
+        	dbDictionary.setDataKey(dataDictionary.getDataKey());
+        	dbDictionary.setDataValue(dataDictionary.getDataValue());
+        	dbDictionary.setCode(dataDictionary.getCode());
+        	dbDictionary.setDescription(dataDictionary.getDescription());
+        	dbDictionary.setParam1(dataDictionary.getParam1());
+        	dbDictionary.setParam2(dataDictionary.getParam2());
+        	dbDictionary.setParam3(dataDictionary.getParam3());
+            update(dbDictionary);
+        } else {
+            save(dataDictionary);
+        }
+    }
+
+	@Override
+	public DataDictionary findByCodeAndDataKey(String code, String dataKey) {
+		return dataDictionaryDao.findByCodeAndDataKey(code, dataKey);
+	}
+	
+	@Override
+	public List<DataDictionary> findByCode(String code){
+		return dataDictionaryDao.findByCode(code);
+	}
+
+	@Override
+	public List<DataDictionary> findByCondition(final DataDictionary dataDictionary) {
+		return dataDictionaryDao.findAll(new Specification<DataDictionary>(){
+			@Override
+			public Predicate toPredicate(Root<DataDictionary> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+				List<Predicate> predicates = new ArrayList<Predicate>();
+				if(dataDictionary.getId() != null){ 
+					predicates.add(cb.equal(root.get("id").as(Integer.class), dataDictionary.getId()));
+				}
+				if (dataDictionary.getCode() != null){
+					predicates.add(cb.equal(root.get("code").as(String.class), dataDictionary.getCode()));
+				}
+				if (dataDictionary.getDataKey() != null){
+					predicates.add(cb.equal(root.get("data_key").as(String.class), dataDictionary.getDataKey()));
+				}
+				if (dataDictionary.getDataValue() != null){
+					predicates.add(cb.equal(root.get("data_value").as(String.class), dataDictionary.getDataValue()));
+				}
+				if (dataDictionary.getDescription() != null){
+					predicates.add(cb.equal(root.get("description").as(String.class), dataDictionary.getDescription()));
+				}
+				if (dataDictionary.getParam1() != null){
+					predicates.add(cb.equal(root.get("param1").as(String.class), dataDictionary.getParam1()));
+				}
+				if (dataDictionary.getParam2() != null){
+					predicates.add(cb.equal(root.get("param2").as(String.class), dataDictionary.getParam2()));
+				}
+				if (dataDictionary.getParam3() != null){
+					predicates.add(cb.equal(root.get("param3").as(String.class), dataDictionary.getParam3()));
+				}
+				return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+			}
+		});
+	}
+}

+ 112 - 0
src/main/java/com/fourdage/system/service/impl/ResourceServiceImpl.java

@@ -0,0 +1,112 @@
+package com.fourdage.system.service.impl;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import com.fourdage.base.common.Constats;
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.service.impl.BaseServiceImpl;
+import com.fourdage.base.vo.ZtreeView;
+import com.fourdage.system.dao.IResourceDao;
+import com.fourdage.system.entity.Resource;
+import com.fourdage.system.entity.Role;
+import com.fourdage.system.service.IResourceService;
+import com.fourdage.system.service.IRoleService;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * <p>
+ * 资源表 服务实现类
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+@Service
+public class ResourceServiceImpl extends BaseServiceImpl<Resource, Integer>
+        implements IResourceService {
+
+    @Autowired
+    private IResourceDao resourceDao;
+
+    @Autowired
+    private IRoleService roleService;
+
+    @Override
+    public IBaseDao<Resource, Integer> getBaseDao() {
+        return this.resourceDao;
+    }
+
+    @Override
+    @Cacheable(value = Constats.RESOURCECACHENAME, key = "'tree_' + #roleId")
+    public List<ZtreeView> tree(int roleId) {
+        List<ZtreeView> resulTreeNodes = new ArrayList<ZtreeView>();
+        Role role = roleService.find(roleId);
+        Set<Resource> roleResources = role.getResources();
+        resulTreeNodes.add(new ZtreeView(-1L, null, "系统菜单", true));
+        ZtreeView node;
+        List<Resource> all = resourceDao.findAllByOrderByParentAscIdAscSortAsc();
+        for (Resource resource : all) {
+            node = new ZtreeView();
+            node.setId(Long.valueOf(resource.getId()));
+            if (resource.getParent() == null) {
+                node.setpId(-1L);
+            } else {
+                node.setpId(Long.valueOf(resource.getParent().getId()));
+            }
+            node.setName(resource.getName());
+            if (roleResources != null && roleResources.contains(resource)) {
+                node.setChecked(true);
+            }
+            resulTreeNodes.add(node);
+        }
+        return resulTreeNodes;
+    }
+
+    @Override
+    public void saveOrUpdate(Resource resource) {
+        if (resource.getId() != null) {
+            Resource dbResource = find(resource.getId());
+            dbResource.setUpdateTime(new Date());
+            dbResource.setName(resource.getName());
+            dbResource.setSourceKey(resource.getSourceKey());
+            dbResource.setType(resource.getType());
+            dbResource.setSourceUrl(resource.getSourceUrl());
+            dbResource.setLevel(resource.getLevel());
+            dbResource.setSort(resource.getSort());
+            dbResource.setIsHide(resource.getIsHide());
+            dbResource.setIcon(resource.getIcon());
+            dbResource.setDescription(resource.getDescription());
+            dbResource.setUpdateTime(new Date());
+            dbResource.setParent(resource.getParent());
+            update(dbResource);
+        } else {
+            resource.setCreateTime(new Date());
+            resource.setUpdateTime(new Date());
+            save(resource);
+        }
+    }
+
+    @Override
+    public void delete(Integer id) {
+        resourceDao.deleteGrant(id);
+        super.delete(id);
+    }
+
+    @Override
+    public Page<Resource> findAllByLike(String searchText, PageRequest pageRequest) {
+        if (StringUtils.isBlank(searchText)) {
+            searchText = "";
+        }
+        return resourceDao.findAllByNameContaining(searchText, pageRequest);
+    }
+
+}

+ 101 - 0
src/main/java/com/fourdage/system/service/impl/RoleServiceImpl.java

@@ -0,0 +1,101 @@
+package com.fourdage.system.service.impl;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import com.fourdage.base.common.Constats;
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.service.impl.BaseServiceImpl;
+import com.fourdage.system.dao.IRoleDao;
+import com.fourdage.system.entity.Resource;
+import com.fourdage.system.entity.Role;
+import com.fourdage.system.service.IResourceService;
+import com.fourdage.system.service.IRoleService;
+
+/**
+ * <p>
+ * 角色表  服务实现类
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+@Service
+public class RoleServiceImpl extends BaseServiceImpl<Role, Integer> implements IRoleService {
+
+    @Autowired
+    private IRoleDao roleDao;
+    @Autowired
+    private IResourceService resourceService;
+
+    @Override
+    public IBaseDao<Role, Integer> getBaseDao() {
+        return this.roleDao;
+    }
+
+    @Override
+    public void saveOrUpdate(Role role) {
+        if (role.getId() != null) {
+            Role dbRole = find(role.getId());
+            dbRole.setUpdateTime(new Date());
+            dbRole.setName(role.getName());
+            dbRole.setDescription(role.getDescription());
+            dbRole.setUpdateTime(new Date());
+            dbRole.setStatus(role.getStatus());
+            update(dbRole);
+        } else {
+            role.setCreateTime(new Date());
+            role.setUpdateTime(new Date());
+            save(role);
+        }
+    }
+
+
+    @Override
+    public void delete(Integer id) {
+        Role role = find(id);
+        Assert.state(!"administrator".equals(role.getRoleKey()), "超级管理员角色不能删除");
+        super.delete(id);
+    }
+
+    @Override
+    @CacheEvict(value = Constats.RESOURCECACHENAME, key = "'tree_' + #id")
+    public void grant(Integer id, String[] resourceIds) {
+        Role role = find(id);
+        Assert.notNull(role, "角色不存在");
+
+        Assert.state(!"administrator".equals(role.getRoleKey()), "超级管理员角色不能进行资源分配");
+        Resource resource;
+        Set<Resource> resources = new HashSet<Resource>();
+        if (resourceIds != null) {
+            for (int i = 0; i < resourceIds.length; i++) {
+                if (StringUtils.isBlank(resourceIds[i]) || "-1".equals(resourceIds[i])) {
+                    continue;
+                }
+                Integer rid = Integer.parseInt(resourceIds[i]);
+                resource = resourceService.find(rid);
+                resources.add(resource);
+            }
+        }
+        role.setResources(resources);
+        update(role);
+    }
+
+    @Override
+    public Page<Role> findAllByLike(String searchText, PageRequest pageRequest) {
+        if (StringUtils.isBlank(searchText)) {
+            searchText = "";
+        }
+        return roleDao.findAllByNameContainingOrDescriptionContaining(searchText, searchText, pageRequest);
+    }
+
+}

+ 126 - 0
src/main/java/com/fourdage/system/service/impl/UserServiceImpl.java

@@ -0,0 +1,126 @@
+package com.fourdage.system.service.impl;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import com.fourdage.base.common.utils.MD5Utils;
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.service.impl.BaseServiceImpl;
+import com.fourdage.system.dao.IUserDao;
+import com.fourdage.system.entity.Role;
+import com.fourdage.system.entity.User;
+import com.fourdage.system.service.IRoleService;
+import com.fourdage.system.service.IUserService;
+
+/**
+ * <p>
+ * 用户账户表  服务实现类
+ * </p>
+ *
+ * @author SPPan
+ * @since 2016-12-28
+ */
+@Service
+public class UserServiceImpl extends BaseServiceImpl<User, Integer> implements IUserService {
+
+    @Autowired
+    private IUserDao userDao;
+
+    @Autowired
+    private IRoleService roleService;
+
+    @Override
+    public IBaseDao<User, Integer> getBaseDao() {
+        return this.userDao;
+    }
+
+    @Override
+    public User findByUserName(String username) {
+        return userDao.findByUserName(username);
+    }
+
+    @Override
+    public void saveOrUpdate(User user) {
+        if (user.getId() != null) {
+            User dbUser = find(user.getId());
+            dbUser.setNickName(user.getNickName());
+            dbUser.setSex(user.getSex());
+            dbUser.setBirthday(user.getBirthday());
+            dbUser.setTelephone(user.getTelephone());
+            dbUser.setEmail(user.getEmail());
+            dbUser.setAddress(user.getAddress());
+            dbUser.setLocked(user.getLocked());
+            dbUser.setDescription(user.getDescription());
+            dbUser.setUpdateTime(new Date());
+            dbUser.setAvatar(user.getAvatar());
+            update(dbUser);
+        } else {
+            user.setCreateTime(new Date());
+            user.setUpdateTime(new Date());
+            user.setDeleteStatus(0);
+            user.setPassword(MD5Utils.md5("111111"));
+            save(user);
+        }
+    }
+
+
+    @Override
+    public void delete(Integer id) {
+        User user = find(id);
+        Assert.state(!"admin".equals(user.getUserName()), "超级管理员用户不能删除");
+        super.delete(id);
+    }
+
+    @Override
+    public void grant(Integer id, String[] roleIds) {
+        User user = find(id);
+        Assert.notNull(user, "用户不存在");
+        Assert.state(!"admin".equals(user.getUserName()), "超级管理员用户不能修改管理角色");
+        Role role;
+        Set<Role> roles = new HashSet<Role>();
+        if (roleIds != null) {
+            for (int i = 0; i < roleIds.length; i++) {
+                Integer rid = Integer.parseInt(roleIds[i]);
+                role = roleService.find(rid);
+                roles.add(role);
+            }
+        }
+        user.setRoles(roles);
+        update(user);
+    }
+
+    @Override
+    public Page<User> findAllByLike(String searchText, PageRequest pageRequest) {
+        if (StringUtils.isBlank(searchText)) {
+            searchText = "";
+        }
+        return userDao.findAllByNickNameContaining(searchText, pageRequest);
+    }
+
+
+    @Override
+    public void updatePwd(User user, String oldPassword, String password1, String password2) {
+        Assert.notNull(user, "用户不能为空");
+        Assert.notNull(oldPassword, "原始密码不能为空");
+        Assert.notNull(password1, "新密码不能为空");
+        Assert.notNull(password2, "重复密码不能为空");
+
+        User dbUser = userDao.findByUserName(user.getUserName());
+        Assert.notNull(dbUser, "用户不存在");
+
+        Assert.isTrue(user.getPassword().equals(MD5Utils.md5(oldPassword)), "原始密码不正确");
+        ;
+        Assert.isTrue(password1.equals(password2), "两次密码不一致");
+        dbUser.setPassword(MD5Utils.md5(password1));
+        userDao.saveAndFlush(dbUser);
+    }
+
+}