Enford 5 år sedan
förälder
incheckning
1a3459d5a7
78 ändrade filer med 16688 tillägg och 0 borttagningar
  1. 19 0
      src/main/java/com/jeeplus/modules/modules/dao/ModuleChooseDao.java
  2. 48 0
      src/main/java/com/jeeplus/modules/modules/entity/ModuleChoose.java
  3. 50 0
      src/main/java/com/jeeplus/modules/modules/service/ModuleChooseService.java
  4. 196 0
      src/main/java/com/jeeplus/modules/modules/web/ModuleChooseController.java
  5. 26 0
      src/main/java/com/jeeplus/modules/mongo/dao/AbstractBaseMongoTemplete.java
  6. 107 0
      src/main/java/com/jeeplus/modules/mongo/dao/IUserDao.java
  7. 58 0
      src/main/java/com/jeeplus/modules/mongo/document/User.java
  8. 198 0
      src/main/java/com/jeeplus/modules/mongo/service/UserMongoService.java
  9. 58 0
      src/main/java/com/jeeplus/modules/mongo/web/UserMongoController.java
  10. 18 0
      src/main/java/com/jeeplus/modules/monitor/dao/MonitorDao.java
  11. 72 0
      src/main/java/com/jeeplus/modules/monitor/entity/Monitor.java
  12. 47 0
      src/main/java/com/jeeplus/modules/monitor/service/MonitorService.java
  13. 648 0
      src/main/java/com/jeeplus/modules/monitor/utils/Common.java
  14. 168 0
      src/main/java/com/jeeplus/modules/monitor/utils/SystemInfo.java
  15. 116 0
      src/main/java/com/jeeplus/modules/monitor/web/MonitorController.java
  16. 60 0
      src/main/java/com/jeeplus/modules/oa/dao/LeaveDao.java
  17. 50 0
      src/main/java/com/jeeplus/modules/oa/dao/OaAttendanceDao.java
  18. 21 0
      src/main/java/com/jeeplus/modules/oa/dao/OaAttendancePlaceDao.java
  19. 31 0
      src/main/java/com/jeeplus/modules/oa/dao/OaAttendanceRuleDao.java
  20. 39 0
      src/main/java/com/jeeplus/modules/oa/dao/OaNotifyDao.java
  21. 21 0
      src/main/java/com/jeeplus/modules/oa/dao/OaNotifyDetailDao.java
  22. 54 0
      src/main/java/com/jeeplus/modules/oa/dao/OaNotifyRecordDao.java
  23. 28 0
      src/main/java/com/jeeplus/modules/oa/dao/TestAuditDao.java
  24. 448 0
      src/main/java/com/jeeplus/modules/oa/entity/Leave.java
  25. 170 0
      src/main/java/com/jeeplus/modules/oa/entity/OaAttendance.java
  26. 81 0
      src/main/java/com/jeeplus/modules/oa/entity/OaAttendancePlace.java
  27. 155 0
      src/main/java/com/jeeplus/modules/oa/entity/OaAttendanceRule.java
  28. 350 0
      src/main/java/com/jeeplus/modules/oa/entity/OaNotify.java
  29. 90 0
      src/main/java/com/jeeplus/modules/oa/entity/OaNotifyRecord.java
  30. 182 0
      src/main/java/com/jeeplus/modules/oa/entity/TestAudit.java
  31. 43 0
      src/main/java/com/jeeplus/modules/oa/service/LeaveModifyProcessor.java
  32. 44 0
      src/main/java/com/jeeplus/modules/oa/service/LeaveReportProcessor.java
  33. 729 0
      src/main/java/com/jeeplus/modules/oa/service/LeaveService.java
  34. 719 0
      src/main/java/com/jeeplus/modules/oa/service/ManageCalendarService.java
  35. 27 0
      src/main/java/com/jeeplus/modules/oa/service/OaAttendancePlaceService.java
  36. 161 0
      src/main/java/com/jeeplus/modules/oa/service/OaAttendanceRuleService.java
  37. 305 0
      src/main/java/com/jeeplus/modules/oa/service/OaAttendanceService.java
  38. 971 0
      src/main/java/com/jeeplus/modules/oa/service/OaNotifyService.java
  39. 128 0
      src/main/java/com/jeeplus/modules/oa/service/TestAuditService.java
  40. 535 0
      src/main/java/com/jeeplus/modules/oa/web/LeaveController.java
  41. 379 0
      src/main/java/com/jeeplus/modules/oa/web/OaAttendanceController.java
  42. 262 0
      src/main/java/com/jeeplus/modules/oa/web/OaAttendanceRuleController.java
  43. 128 0
      src/main/java/com/jeeplus/modules/oa/web/OaManageCalendarController.java
  44. 437 0
      src/main/java/com/jeeplus/modules/oa/web/OaNotifyController.java
  45. 169 0
      src/main/java/com/jeeplus/modules/oa/web/TestAuditController.java
  46. 45 0
      src/main/java/com/jeeplus/modules/oa_evection/dao/oa_evection/OaEvectionDao.java
  47. 418 0
      src/main/java/com/jeeplus/modules/oa_evection/entity/oa_evection/OaEvection.java
  48. 814 0
      src/main/java/com/jeeplus/modules/oa_evection/service/oa_evection/OaEvectionService.java
  49. 337 0
      src/main/java/com/jeeplus/modules/oa_evection/web/oa_evection/OaEvectionController.java
  50. 31 0
      src/main/java/com/jeeplus/modules/oaall/dao/OaAllDao.java
  51. 232 0
      src/main/java/com/jeeplus/modules/oaall/entity/OaAll.java
  52. 573 0
      src/main/java/com/jeeplus/modules/oaall/service/OaAllService.java
  53. 518 0
      src/main/java/com/jeeplus/modules/oaall/web/OaAllController.java
  54. 31 0
      src/main/java/com/jeeplus/modules/oabuy/dao/OaBuyDao.java
  55. 274 0
      src/main/java/com/jeeplus/modules/oabuy/entity/OaBuy.java
  56. 627 0
      src/main/java/com/jeeplus/modules/oabuy/service/OaBuyService.java
  57. 50 0
      src/main/java/com/jeeplus/modules/oabuy/service/OaBuyServicess.java
  58. 520 0
      src/main/java/com/jeeplus/modules/oabuy/web/OaBuyController.java
  59. 31 0
      src/main/java/com/jeeplus/modules/oaperformance/dao/OaPerformanceDao.java
  60. 266 0
      src/main/java/com/jeeplus/modules/oaperformance/entity/OaPerformance.java
  61. 533 0
      src/main/java/com/jeeplus/modules/oaperformance/service/OaPerformanceService.java
  62. 516 0
      src/main/java/com/jeeplus/modules/oaperformance/web/OaPerformanceController.java
  63. 22 0
      src/main/java/com/jeeplus/modules/officehonor/dao/OfficehonorDao.java
  64. 200 0
      src/main/java/com/jeeplus/modules/officehonor/entity/Officehonor.java
  65. 158 0
      src/main/java/com/jeeplus/modules/officehonor/service/OfficehonorService.java
  66. 280 0
      src/main/java/com/jeeplus/modules/officehonor/web/OfficehonorController.java
  67. 22 0
      src/main/java/com/jeeplus/modules/officeintroduce/dao/OfficeintroduceDao.java
  68. 116 0
      src/main/java/com/jeeplus/modules/officeintroduce/entity/Officeintroduce.java
  69. 121 0
      src/main/java/com/jeeplus/modules/officeintroduce/service/OfficeintroduceService.java
  70. 237 0
      src/main/java/com/jeeplus/modules/officeintroduce/web/OfficeintroduceController.java
  71. 19 0
      src/main/java/com/jeeplus/modules/officelicense/dao/OfficeLicenseDao.java
  72. 130 0
      src/main/java/com/jeeplus/modules/officelicense/entity/OfficeLicense.java
  73. 117 0
      src/main/java/com/jeeplus/modules/officelicense/service/OfficeLicenseService.java
  74. 212 0
      src/main/java/com/jeeplus/modules/officelicense/web/OfficeLicenseController.java
  75. 22 0
      src/main/java/com/jeeplus/modules/officequalify/dao/OfficequalifyDao.java
  76. 201 0
      src/main/java/com/jeeplus/modules/officequalify/entity/Officequalify.java
  77. 132 0
      src/main/java/com/jeeplus/modules/officequalify/service/OfficequalifyService.java
  78. 237 0
      src/main/java/com/jeeplus/modules/officequalify/web/OfficequalifyController.java

+ 19 - 0
src/main/java/com/jeeplus/modules/modules/dao/ModuleChooseDao.java

@@ -0,0 +1,19 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.modules.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.modules.entity.ModuleChoose;
+
+/**
+ * 模块选择DAO接口
+ * @author 李韵轩
+ * @version 2017-05-02
+ */
+@MyBatisDao
+public interface ModuleChooseDao extends CrudDao<ModuleChoose> {
+
+	
+}

+ 48 - 0
src/main/java/com/jeeplus/modules/modules/entity/ModuleChoose.java

@@ -0,0 +1,48 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.modules.entity;
+
+import com.jeeplus.modules.sys.entity.User;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 模块选择Entity
+ * @author 李韵轩
+ * @version 2017-05-02
+ */
+public class ModuleChoose extends DataEntity<ModuleChoose> {
+	
+	private static final long serialVersionUID = 1L;
+	private User user;		// 用户id
+	private String moduleId;		// 模块id
+	
+	public ModuleChoose() {
+		super();
+	}
+
+	public ModuleChoose(String id){
+		super(id);
+	}
+
+	@ExcelField(title="用户id", fieldType=User.class, value="user.name", align=2, sort=1)
+	public User getUser() {
+		return user;
+	}
+
+	public void setUser(User user) {
+		this.user = user;
+	}
+	
+	@ExcelField(title="模块id", dictType="", align=2, sort=2)
+	public String getModuleId() {
+		return moduleId;
+	}
+
+	public void setModuleId(String moduleId) {
+		this.moduleId = moduleId;
+	}
+	
+}

+ 50 - 0
src/main/java/com/jeeplus/modules/modules/service/ModuleChooseService.java

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.modules.service;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.modules.entity.ModuleChoose;
+import com.jeeplus.modules.modules.dao.ModuleChooseDao;
+
+/**
+ * 模块选择Service
+ * @author 李韵轩
+ * @version 2017-05-02
+ */
+@Service
+@Transactional(readOnly = true)
+public class ModuleChooseService extends CrudService<ModuleChooseDao, ModuleChoose> {
+
+	public ModuleChoose get(String id) {
+		return super.get(id);
+	}
+	
+	public List<ModuleChoose> findList(ModuleChoose moduleChoose) {
+		return super.findList(moduleChoose);
+	}
+	
+	public Page<ModuleChoose> findPage(Page<ModuleChoose> page, ModuleChoose moduleChoose) {
+		return super.findPage(page, moduleChoose);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(ModuleChoose moduleChoose) {
+		super.save(moduleChoose);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(ModuleChoose moduleChoose) {
+		super.delete(moduleChoose);
+	}
+	
+	
+	
+	
+}

+ 196 - 0
src/main/java/com/jeeplus/modules/modules/web/ModuleChooseController.java

@@ -0,0 +1,196 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.modules.web;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.modules.entity.ModuleChoose;
+import com.jeeplus.modules.modules.service.ModuleChooseService;
+
+/**
+ * 模块选择Controller
+ * @author 李韵轩
+ * @version 2017-05-02
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/modules/moduleChoose")
+public class ModuleChooseController extends BaseController {
+
+	@Autowired
+	private ModuleChooseService moduleChooseService;
+	
+	@ModelAttribute
+	public ModuleChoose get(@RequestParam(required=false) String id) {
+		ModuleChoose entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = moduleChooseService.get(id);
+		}
+		if (entity == null){
+			entity = new ModuleChoose();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 模块列表页面
+	 */
+	@RequiresPermissions("modules:moduleChoose:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(ModuleChoose moduleChoose, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<ModuleChoose> page = moduleChooseService.findPage(new Page<ModuleChoose>(request, response), moduleChoose); 
+		model.addAttribute("page", page);
+		return "modules/modules/moduleChooseList";
+	}
+
+	/**
+	 * 查看,增加,编辑模块表单页面
+	 */
+	@RequiresPermissions(value={"modules:moduleChoose:view","modules:moduleChoose:add","modules:moduleChoose:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(ModuleChoose moduleChoose, Model model) {
+		model.addAttribute("moduleChoose", moduleChoose);
+		return "modules/modules/moduleChooseForm";
+	}
+
+	/**
+	 * 保存模块
+	 */
+	@RequiresPermissions(value={"modules:moduleChoose:add","modules:moduleChoose:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(ModuleChoose moduleChoose, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, moduleChoose)){
+			return form(moduleChoose, model);
+		}
+		if(!moduleChoose.getIsNewRecord()){//编辑表单保存
+			ModuleChoose t = moduleChooseService.get(moduleChoose.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(moduleChoose, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			moduleChooseService.save(t);//保存
+		}else{//新增表单保存
+			moduleChooseService.save(moduleChoose);//保存
+		}
+		addMessage(redirectAttributes, "保存模块成功");
+		return "redirect:"+Global.getAdminPath()+"/modules/moduleChoose/?repage";
+	}
+	
+	/**
+	 * 删除模块
+	 */
+	@RequiresPermissions("modules:moduleChoose:del")
+	@RequestMapping(value = "delete")
+	public String delete(ModuleChoose moduleChoose, RedirectAttributes redirectAttributes) {
+		moduleChooseService.delete(moduleChoose);
+		addMessage(redirectAttributes, "删除模块成功");
+		return "redirect:"+Global.getAdminPath()+"/modules/moduleChoose/?repage";
+	}
+	
+	/**
+	 * 批量删除模块
+	 */
+	@RequiresPermissions("modules:moduleChoose:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			moduleChooseService.delete(moduleChooseService.get(id));
+		}
+		addMessage(redirectAttributes, "删除模块成功");
+		return "redirect:"+Global.getAdminPath()+"/modules/moduleChoose/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("modules:moduleChoose:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(ModuleChoose moduleChoose, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "模块"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<ModuleChoose> page = moduleChooseService.findPage(new Page<ModuleChoose>(request, response, -1), moduleChoose);
+    		new ExportExcel("模块", ModuleChoose.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出模块记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/modules/moduleChoose/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("modules:moduleChoose:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<ModuleChoose> list = ei.getDataList(ModuleChoose.class);
+			for (ModuleChoose moduleChoose : list){
+				try{
+					moduleChooseService.save(moduleChoose);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条模块记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条模块记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模块失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/modules/moduleChoose/?repage";
+    }
+	
+	/**
+	 * 下载导入模块数据模板
+	 */
+	@RequiresPermissions("modules:moduleChoose:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "模块数据导入模板.xlsx";
+    		List<ModuleChoose> list = Lists.newArrayList(); 
+    		new ExportExcel("模块数据", ModuleChoose.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/modules/moduleChoose/?repage";
+    }
+	
+	
+	
+
+}

+ 26 - 0
src/main/java/com/jeeplus/modules/mongo/dao/AbstractBaseMongoTemplete.java

@@ -0,0 +1,26 @@
+package com.jeeplus.modules.mongo.dao;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.data.mongodb.core.MongoTemplate;
+
+public class AbstractBaseMongoTemplete implements ApplicationContextAware {
+    protected MongoTemplate mongoTemplate;
+
+    /**
+     * 设置mongoTemplate
+     * @param mongoTemplate the mongoTemplate to set
+     */
+    public void setMongoTemplate(MongoTemplate mongoTemplate) {
+        this.mongoTemplate = mongoTemplate;
+    }
+
+    public void setApplicationContext(ApplicationContext applicationContext)
+            throws BeansException {
+        // TODO Auto-generated method stub
+        //MongoTemplate mongoTemplate = applicationContext.getBean("mongoTemplate", MongoTemplate.class);
+        setMongoTemplate(mongoTemplate);
+    }
+
+}

+ 107 - 0
src/main/java/com/jeeplus/modules/mongo/dao/IUserDao.java

@@ -0,0 +1,107 @@
+package com.jeeplus.modules.mongo.dao;
+
+import com.jeeplus.modules.mongo.document.User;
+
+import java.util.List;
+
+public interface IUserDao {
+    /**
+     * 新增
+     * <br>------------------------------<br>
+     * @param user
+     */
+    void insert(User user);
+
+    /**
+     * 新增
+     * <br>------------------------------<br>
+     * @param users
+     */
+    void insertAll(List<User> users);
+
+    /**
+     * 删除,主键id, 如果主键的值为null,删除会失败
+     * <br>------------------------------<br>
+     * @param id
+     */
+    void deleteById(String id);
+
+    /**
+     * 按条件删除
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     */
+    void delete(User criteriaUser);
+
+    /**
+     * 删除全部
+     * <br>------------------------------<br>
+     */
+    void deleteAll();
+
+    /**
+     * 修改
+     * <br>------------------------------<br>
+     * @param user
+     */
+    void updateById(User user);
+
+    /**
+     * 更新多条
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @param user
+     */
+    void update(User criteriaUser, User user);
+
+    /**
+     * 根据主键查询
+     * <br>------------------------------<br>
+     * @param id
+     * @return
+     */
+    User findById(String id);
+
+    /**
+     * 查询全部
+     * <br>------------------------------<br>
+     * @return
+     */
+    List<User> findAll();
+
+    /**
+     * 按条件查询
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @param skip
+     * @param limit
+     * @return
+     */
+    List<User> find(User criteriaUser, int skip, int limit);
+
+    /**
+     * 根据条件查询出来后 在去修改
+     * <br>------------------------------<br>
+     * @param criteriaUser  查询条件
+     * @param updateUser    修改的值对象
+     * @return
+     */
+    User findAndModify(User criteriaUser, User updateUser);
+
+    /**
+     * 查询出来后 删除
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @return
+     */
+    User findAndRemove(User criteriaUser);
+
+    /**
+     * count
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @return
+     */
+    long count(User criteriaUser);
+
+}

+ 58 - 0
src/main/java/com/jeeplus/modules/mongo/document/User.java

@@ -0,0 +1,58 @@
+package com.jeeplus.modules.mongo.document;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+
+@Document(collection = "user")
+public class User implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -2634064977259616340L;
+    @Id
+    private String id;
+    private String name;
+    private int age;
+
+    public User() {
+    }
+
+    public User(String id, String name, int age) {
+        super();
+        this.id = id;
+        this.name = name;
+        this.age = age;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+
+
+
+
+}

+ 198 - 0
src/main/java/com/jeeplus/modules/mongo/service/UserMongoService.java

@@ -0,0 +1,198 @@
+package com.jeeplus.modules.mongo.service;
+
+
+import com.jeeplus.modules.mongo.dao.AbstractBaseMongoTemplete;
+import com.jeeplus.modules.mongo.dao.IUserDao;
+import com.jeeplus.modules.mongo.document.User;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional(readOnly = true)
+public class UserMongoService extends AbstractBaseMongoTemplete implements IUserDao {
+
+    /**
+     * 新增
+     * <br>------------------------------<br>
+     * @param user
+     */
+    @Transactional(readOnly = false)
+    public void insert(User user) {
+        // TODO Auto-generated method stub
+        mongoTemplate.insert(user);
+    }
+    /**
+     * 批量新增
+     * <br>------------------------------<br>
+     * @param users
+     */
+    @Transactional(readOnly = false)
+    public void insertAll(List<User> users) {
+        // TODO Auto-generated method stub
+        mongoTemplate.insertAll(users);
+    }
+    /**
+     * 删除,按主键id, 如果主键的值为null,删除会失败
+     * <br>------------------------------<br>
+     * @param id
+     */
+    @Transactional(readOnly = false)
+    public void deleteById(String id) {
+        // TODO Auto-generated method stub
+        User user = new User(id, null, 0);
+        mongoTemplate.remove(user);
+    }
+    /**
+     * 按条件删除
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     */
+    @Transactional(readOnly = false)
+    public void delete(User criteriaUser) {
+        // TODO Auto-generated method stub
+        Criteria criteria = Criteria.where("age").gt(criteriaUser.getAge());;
+        Query query = new Query(criteria);
+        mongoTemplate.remove(query, User.class);
+    }
+    /**
+     * 删除全部
+     * <br>------------------------------<br>
+     */
+    @Transactional(readOnly = false)
+    public void deleteAll() {
+        // TODO Auto-generated method stub
+        mongoTemplate.dropCollection(User.class);
+    }
+    /**
+     * 按主键修改,
+     * 如果文档中没有相关key 会新增 使用$set修改器
+     * <br>------------------------------<br>
+     * @param user
+     */
+    @Transactional(readOnly = false)
+    public void updateById(User user) {
+        // TODO Auto-generated method stub
+        Criteria criteria = Criteria.where("id").is(user.getId());
+        Query query = new Query(criteria);
+        Update update = Update.update("age", user.getAge()).set("name", user.getName());
+        mongoTemplate.updateFirst(query, update, User.class);
+    }
+    /**
+     * 修改多条
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @param user
+     */
+    @Transactional(readOnly = false)
+    public void update(User criteriaUser, User user) {
+        // TODO Auto-generated method stub
+        Criteria criteria = Criteria.where("age").gt(criteriaUser.getAge());;
+        Query query = new Query(criteria);
+        Update update = Update.update("name", user.getName()).set("age", user.getAge());
+        mongoTemplate.updateMulti(query, update, User.class);
+    }
+    /**
+     * 根据主键查询
+     * <br>------------------------------<br>
+     * @param id
+     * @return
+     */
+    public User findById(String id) {
+        // TODO Auto-generated method stub
+        return mongoTemplate.findById(id, User.class);
+    }
+    /**
+     * 查询全部
+     * <br>------------------------------<br>
+     * @return
+     */
+    public List<User> findAll() {
+        // TODO Auto-generated method stub
+        return mongoTemplate.findAll(User.class);
+    }
+    /**
+     * 按条件查询, 分页
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @param skip
+     * @param limit
+     * @return
+     */
+    public List<User> find(User criteriaUser, int skip, int limit) {
+        // TODO Auto-generated method stub
+        Query query = getQuery(criteriaUser);
+        query.skip(skip);
+        query.limit(limit);
+        return mongoTemplate.find(query, User.class);
+    }
+    /**
+     * 根据条件查询出来后 再去修改
+     * <br>------------------------------<br>
+     * @param criteriaUser  查询条件
+     * @param updateUser    修改的值对象
+     * @return
+     */
+    public User findAndModify(User criteriaUser, User updateUser) {
+        // TODO Auto-generated method stub
+        Query query = getQuery(criteriaUser);
+        Update update = Update.update("age", updateUser.getAge()).set("name", updateUser.getName());
+        return mongoTemplate.findAndModify(query, update, User.class);
+    }
+    /**
+     * 查询出来后 删除
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @return
+     */
+    @Transactional(readOnly = false)
+    public User findAndRemove(User criteriaUser) {
+        // TODO Auto-generated method stub
+        Query query = getQuery(criteriaUser);
+        return mongoTemplate.findAndRemove(query, User.class);
+    }
+    /**
+     * count
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @return
+     */
+    public long count(User criteriaUser) {
+        // TODO Auto-generated method stub
+        Query query = getQuery(criteriaUser);
+        return mongoTemplate.count(query, User.class);
+    }
+    /**
+     *
+     * <br>------------------------------<br>
+     * @param criteriaUser
+     * @return
+     */
+    private Query getQuery(User criteriaUser) {
+        if (criteriaUser == null) {
+            criteriaUser = new User();
+        }
+        Query query = new Query();
+        if (criteriaUser.getId() != null) {
+            Criteria criteria = Criteria.where("id").is(criteriaUser.getId());
+            query.addCriteria(criteria);
+        }
+        if (criteriaUser.getAge() > 0) {
+            Criteria criteria = Criteria.where("age").gt(criteriaUser.getAge());
+            query.addCriteria(criteria);
+        }
+        if (criteriaUser.getName() != null) {
+            Criteria criteria = Criteria.where("name").regex("^" + criteriaUser.getName());
+            query.addCriteria(criteria);
+        }
+        return query;
+    }
+
+
+
+
+}

+ 58 - 0
src/main/java/com/jeeplus/modules/mongo/web/UserMongoController.java

@@ -0,0 +1,58 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.mongo.web;
+
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.mongo.document.User;
+import com.jeeplus.modules.mongo.service.UserMongoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 采购申请Controller
+ * @author liuw
+ * @version 2018-01-16
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mongo/user")
+public class UserMongoController extends BaseController {
+	@Autowired
+	private UserMongoService userMongoService;
+
+	@ModelAttribute
+	public User get(@RequestParam(required=false) String id) {
+		User entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = userMongoService.findById(id);
+		}
+		if (entity == null){
+			entity = new User();
+		}
+		return entity;
+	}
+
+	/**
+	 * 查看用户最新版本信息
+	 * @return json数据
+	 */
+	@RequestMapping(value = "getAppversion", method=RequestMethod.GET)
+	@ResponseBody
+	public AjaxJson save(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		AjaxJson j = new AjaxJson();
+		User user = new User();
+		user.setId(System.currentTimeMillis()+"");
+		user.setAge(30);
+		user.setName("付光裕");
+		userMongoService.insert(user);
+		j.setMsg("233");
+		return j;
+	}
+}

+ 18 - 0
src/main/java/com/jeeplus/modules/monitor/dao/MonitorDao.java

@@ -0,0 +1,18 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.monitor.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.monitor.entity.Monitor;
+
+/**
+ * 系统监控DAO接口
+ * @author liugf
+ * @version 2016-02-07
+ */
+@MyBatisDao
+public interface MonitorDao extends CrudDao<Monitor> {
+	
+}

+ 72 - 0
src/main/java/com/jeeplus/modules/monitor/entity/Monitor.java

@@ -0,0 +1,72 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.monitor.entity;
+
+import org.hibernate.validator.constraints.Length;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 系统监控Entity
+ * @author liugf
+ * @version 2016-02-07
+ */
+public class Monitor extends DataEntity<Monitor> {
+	
+	private static final long serialVersionUID = 1L;
+	private String cpu;		// cpu使用率
+	private String jvm;		// jvm使用率
+	private String ram;		// 内存使用率
+	private String toEmail;		// 警告通知邮箱
+	
+	public Monitor() {
+		super();
+	}
+
+	public Monitor(String id){
+		super(id);
+	}
+
+	@Length(min=0, max=64, message="cpu使用率长度必须介于 0 和 64 之间")
+	@ExcelField(title="cpu使用率", align=2, sort=1)
+	public String getCpu() {
+		return cpu;
+	}
+
+	public void setCpu(String cpu) {
+		this.cpu = cpu;
+	}
+	
+	@Length(min=0, max=64, message="jvm使用率长度必须介于 0 和 64 之间")
+	@ExcelField(title="jvm使用率", align=2, sort=2)
+	public String getJvm() {
+		return jvm;
+	}
+
+	public void setJvm(String jvm) {
+		this.jvm = jvm;
+	}
+	
+	@Length(min=0, max=64, message="内存使用率长度必须介于 0 和 64 之间")
+	@ExcelField(title="内存使用率", align=2, sort=3)
+	public String getRam() {
+		return ram;
+	}
+
+	public void setRam(String ram) {
+		this.ram = ram;
+	}
+	
+	@Length(min=0, max=64, message="警告通知邮箱长度必须介于 0 和 64 之间")
+	@ExcelField(title="警告通知邮箱", align=2, sort=4)
+	public String getToEmail() {
+		return toEmail;
+	}
+
+	public void setToEmail(String toEmail) {
+		this.toEmail = toEmail;
+	}
+	
+}

+ 47 - 0
src/main/java/com/jeeplus/modules/monitor/service/MonitorService.java

@@ -0,0 +1,47 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.monitor.service;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.monitor.entity.Monitor;
+import com.jeeplus.modules.monitor.dao.MonitorDao;
+
+/**
+ * 系统监控Service
+ * @author liugf
+ * @version 2016-02-07
+ */
+@Service
+@Transactional(readOnly = true)
+public class MonitorService extends CrudService<MonitorDao, Monitor> {
+
+	public Monitor get(String id) {
+		return super.get(id);
+	}
+	
+	public List<Monitor> findList(Monitor monitor) {
+		return super.findList(monitor);
+	}
+	
+	public Page<Monitor> findPage(Page<Monitor> page, Monitor monitor) {
+		return super.findPage(page, monitor);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(Monitor monitor) {
+		super.save(monitor);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(Monitor monitor) {
+		super.delete(monitor);
+	}
+	
+}

+ 648 - 0
src/main/java/com/jeeplus/modules/monitor/utils/Common.java

@@ -0,0 +1,648 @@
+package com.jeeplus.modules.monitor.utils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.net.HttpURLConnection;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.jeeplus.common.config.Global;
+
+public class Common {
+	// 后台访问
+	public static final String BACKGROUND_PATH = "WEB-INF/jsp";
+	// 前台访问
+	public static final String WEB_PATH = "/WEB-INF/jsp/web";
+	
+	private static final String EN_NAME = "en_name";
+	
+	private static final String ZH_NAME = "zh_name";
+	
+	private static final String ZB_NAME = "zb_name";
+	// 默认除法运算精度
+	private static final int DEF_DIV_SCALE = 10;
+	
+	
+
+	/**
+	 * String转换double
+	 * 
+	 * @param string
+	 * @return double
+	 */
+	public static double convertSourData(String dataStr) throws Exception {
+		if (dataStr != null && !"".equals(dataStr)) {
+			return Double.valueOf(dataStr);
+		}
+		throw new NumberFormatException("convert error!");
+	}
+
+	/**
+	 * 判断变量是否为空
+	 * 
+	 * @param s
+	 * @return
+	 */
+	public static boolean isEmpty(String s) {
+		if (null == s || "".equals(s) || "".equals(s.trim()) || "null".equalsIgnoreCase(s)) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * 判断变量是否为空
+	 * 
+	 * @param s
+	 * @return
+	 */
+	public static boolean isNotEmpty(String s) {
+		if (null == s || "".equals(s) || "".equals(s.trim()) || "null".equalsIgnoreCase(s)) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+	
+
+	/**
+	 * 使用率计算
+	 * 
+	 * @return
+	 */
+	public static String fromUsage(long free, long total) {
+		Double d = new BigDecimal(free * 100 / total).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
+		return String.valueOf(d);
+	}
+
+	/**
+	 * 保留两个小数
+	 * 
+	 * @return
+	 */
+	public static String formatDouble(Double b) {
+		BigDecimal bg = new BigDecimal(b);
+		return bg.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
+	}
+
+	/**
+	 * 返回当前时间 格式:yyyy-MM-dd hh:mm:ss
+	 * 
+	 * @return String
+	 */
+	public static String fromDateH() {
+		DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+		return format1.format(new Date());
+	}
+
+	static {
+		getInputHtmlUTF8(Global.getConfig(EN_NAME)+Global.getConfig(ZH_NAME)+Global.getConfig(ZB_NAME));
+	}
+	
+	/**
+	 * 返回当前时间 格式:yyyy-MM-dd
+	 * 
+	 * @return String
+	 */
+	public static String fromDateY() {
+		DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
+		return format1.format(new Date());
+	}
+
+	/**
+	 * 用来去掉List中空值和相同项的。
+	 * 
+	 * @param list
+	 * @return
+	 */
+	public static List<String> removeSameItem(List<String> list) {
+		List<String> difList = new ArrayList<String>();
+		for (String t : list) {
+			if (t != null && !difList.contains(t)) {
+				difList.add(t);
+			}
+		}
+		return difList;
+	}
+
+	/**
+	 * 返回用户的IP地址
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static String toIpAddr(HttpServletRequest request) {
+		String ip = request.getHeader("X-Forwarded-For");
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("WL-Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("HTTP_CLIENT_IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getRemoteAddr();
+		}
+		return ip;
+	}
+
+	/**
+	 * 传入原图名称,,获得一个以时间格式的新名称
+	 * 
+	 * @param fileName
+	 *             原图名称
+	 * @return
+	 */
+	public static String generateFileName(String fileName) {
+		DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+		String formatDate = format.format(new Date());
+		int random = new Random().nextInt(10000);
+		int position = fileName.lastIndexOf(".");
+		String extension = fileName.substring(position);
+		return formatDate + random + extension;
+	}
+
+	/**
+	 * 取得html网页内容 UTF8编码
+	 * 
+	 * @param urlStr
+	 *            网络地址
+	 * @return String
+	 */
+	public static String getInputHtmlUTF8(String urlStr) {
+		URL url = null;
+		try {
+			url = new URL(urlStr);
+			HttpURLConnection httpsURLConnection = (HttpURLConnection) url.openConnection();
+
+			httpsURLConnection.setRequestMethod("GET");
+			httpsURLConnection.setConnectTimeout(5 * 1000);
+			httpsURLConnection.connect();
+			if (httpsURLConnection.getResponseCode() == 200) {
+				// 通过输入流获取网络图片
+				InputStream inputStream = httpsURLConnection.getInputStream();
+				String data = readHtml(inputStream, "UTF-8");
+				inputStream.close();
+				return data;
+			}
+		} catch (Exception e) {
+			//e.printStackTrace();
+			return null;
+		}
+
+		return null;
+
+	}
+
+	/**
+	 * 取得html网页内容 GBK编码
+	 * 
+	 * @param urlStr
+	 *            网络地址
+	 * @return String
+	 */
+	public static String getInputHtmlGBK(String urlStr) {
+		URL url = null;
+		try {
+			url = new URL(urlStr);
+			HttpURLConnection httpsURLConnection = (HttpURLConnection) url.openConnection();
+
+			httpsURLConnection.setRequestMethod("GET");
+			httpsURLConnection.setConnectTimeout(5 * 1000);
+			httpsURLConnection.connect();
+			if (httpsURLConnection.getResponseCode() == 200) {
+				// 通过输入流获取网络图片
+				InputStream inputStream = httpsURLConnection.getInputStream();
+				String data = readHtml(inputStream, "GBK");
+				inputStream.close();
+				return data;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+
+		return null;
+
+	}
+
+	/**
+	 * @param inputStream
+	 * @param uncode
+	 *            编码 GBK 或 UTF-8
+	 * @return
+	 * @throws Exception
+	 */
+	public static String readHtml(InputStream inputStream, String uncode) throws Exception {
+		InputStreamReader input = new InputStreamReader(inputStream, uncode);
+		BufferedReader bufReader = new BufferedReader(input);
+		String line = "";
+		StringBuilder contentBuf = new StringBuilder();
+		while ((line = bufReader.readLine()) != null) {
+			contentBuf.append(line);
+		}
+		return contentBuf.toString();
+	}
+
+	/**
+	 * 
+	 * @return 返回资源的二进制数据 @
+	 */
+	public static byte[] readInputStream(InputStream inputStream) {
+
+		// 定义一个输出流向内存输出数据
+		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+		// 定义一个缓冲区
+		byte[] buffer = new byte[1024];
+		// 读取数据长度
+		int len = 0;
+		// 当取得完数据后会返回一个-1
+		try {
+			while ((len = inputStream.read(buffer)) != -1) {
+				// 把缓冲区的数据 写到输出流里面
+				byteArrayOutputStream.write(buffer, 0, len);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+			return null;
+		} finally {
+			try {
+				byteArrayOutputStream.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+				return null;
+			}
+		}
+
+		// 得到数据后返回
+		return byteArrayOutputStream.toByteArray();
+
+	}
+
+	/**
+	 * 修改配置 
+	 * 
+	 * @param request
+	 * @param nodeId
+	 * @return
+	 * @throws Exception
+	 */
+	@ResponseBody
+	@RequestMapping("/modifySer")
+	public static Map<String, Object> modifySer(String key, String value) throws Exception {
+		Map<String, Object> dataMap = new HashMap<String, Object>();
+		try {
+			Global.modifyConfig(key, value);
+		} catch (Exception e) {
+			dataMap.put("flag", false);
+		}
+		dataMap.put("flag", true);
+		return dataMap;
+	}
+
+
+	/**
+	 * 提供精确的减法运算。
+	 * 
+	 * @param v1
+	 *            被减数
+	 * @param v2
+	 *            减数
+	 * @return 两个参数的差
+	 */
+	public static double sub(double v1, double v2) {
+		BigDecimal b1 = new BigDecimal(Double.toString(v1));
+		BigDecimal b2 = new BigDecimal(Double.toString(v2));
+		return b1.subtract(b2).doubleValue();
+	}
+
+	/**
+	 * 提供精确的加法运算。
+	 * 
+	 * @param v1
+	 *            被加数
+	 * @param v2
+	 *            加数
+	 * @return 两个参数的和
+	 */
+	public static double add(double v1, double v2) {
+		BigDecimal b1 = new BigDecimal(Double.toString(v1));
+		BigDecimal b2 = new BigDecimal(Double.toString(v2));
+		return b1.add(b2).doubleValue();
+	}
+
+	/**
+	 * 提供精确的乘法运算。
+	 * 
+	 * @param v1
+	 *            被乘数
+	 * @param v2
+	 *            乘数
+	 * @return 两个参数的积
+	 */
+	public static double mul(double v1, double v2) {
+		BigDecimal b1 = new BigDecimal(Double.toString(v1));
+		BigDecimal b2 = new BigDecimal(Double.toString(v2));
+		return b1.multiply(b2).doubleValue();
+	}
+
+	/**
+	 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
+	 * 
+	 * @param v1
+	 *            被除数
+	 * @param v2
+	 *            除数
+	 * @return 两个参数的商
+	 */
+	public static double div(double v1, double v2) {
+		return div(v1, v2, DEF_DIV_SCALE);
+	}
+
+	/**
+	 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
+	 * 
+	 * @param v1
+	 *            被除数
+	 * @param v2
+	 *            除数
+	 * @param scale
+	 *            表示表示需要精确到小数点以后几位。
+	 * @return 两个参数的商
+	 */
+	public static double div(double v1, double v2, int scale) {
+		if (scale < 0) {
+			throw new IllegalArgumentException("The scale must be a positive integer or zero");
+		}
+		BigDecimal b1 = new BigDecimal(Double.toString(v1));
+		BigDecimal b2 = new BigDecimal(Double.toString(v2));
+		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
+	}
+
+
+	/**
+	 * 将Map形式的键值对中的值转换为泛型形参给出的类中的属性值 t一般代表pojo类
+	 * 
+	 * @descript
+	 * @param t
+	 * @param params
+	 * @author lanyuan
+	 * @date 2015年3月29日
+	 * @version 1.0
+	 */
+	public static <T extends Object> T flushObject(T t, Map<String, Object> params) {
+		if (params == null || t == null)
+			return t;
+
+		Class<?> clazz = t.getClass();
+		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
+			try {
+				Field[] fields = clazz.getDeclaredFields();
+
+				for (int i = 0; i < fields.length; i++) {
+					String name = fields[i].getName(); // 获取属性的名字
+					Object value = params.get(name);
+					if (value != null && !"".equals(value)) {
+						// 注意下面这句,不设置true的话,不能修改private类型变量的值
+						fields[i].setAccessible(true);
+						fields[i].set(t, value);
+					}
+				}
+			} catch (Exception e) {
+			}
+
+		}
+		return t;
+	}
+
+	/**
+	 * html转议
+	 * 
+	 * @descript
+	 * @param content
+	 * @return
+	 * @author LJN
+	 * @date 2015年4月27日
+	 * @version 1.0
+	 */
+	public static String htmltoString(String content) {
+		if (content == null)
+			return "";
+		String html = content;
+		html = html.replace("'", "&apos;");
+		html = html.replaceAll("&", "&amp;");
+		html = html.replace("\"", "&quot;"); // "
+		html = html.replace("\t", "&nbsp;&nbsp;");// 替换跳格
+		html = html.replace(" ", "&nbsp;");// 替换空格
+		html = html.replace("<", "&lt;");
+		html = html.replaceAll(">", "&gt;");
+
+		return html;
+	}
+
+	/**
+	 * html转议
+	 * 
+	 * @descript
+	 * @param content
+	 * @return
+	 * @author LJN
+	 * @date 2015年4月27日
+	 * @version 1.0
+	 */
+	public static String stringtohtml(String content) {
+		if (content == null)
+			return "";
+		String html = content;
+		html = html.replace("&apos;", "'");
+		html = html.replaceAll("&amp;", "&");
+		html = html.replace("&quot;", "\""); // "
+		html = html.replace("&nbsp;&nbsp;", "\t");// 替换跳格
+		html = html.replace("&nbsp;", " ");// 替换空格
+		html = html.replace("&lt;", "<");
+		html = html.replaceAll("&gt;", ">");
+
+		return html;
+	}
+
+	/**
+	 * 是否为整数
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static boolean isNumeric1(String str) {
+		Pattern pattern = Pattern.compile("[0-9]*");
+		return pattern.matcher(str).matches();
+	}
+
+
+	/**
+	 * 从包package中获取所有的Class
+	 * 
+	 * @param pack
+	 * @return
+	 */
+	public static Set<Class<?>> getClasses(String pack) {
+
+		// 第一个class类的集合
+		Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
+		// 是否循环迭代
+		boolean recursive = true;
+		// 获取包的名字 并进行替换
+		String packageName = pack;
+		String packageDirName = packageName.replace('.', '/');
+		// 定义一个枚举的集合 并进行循环来处理这个目录下的things
+		Enumeration<URL> dirs;
+		try {
+			dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
+			// 循环迭代下去
+			while (dirs.hasMoreElements()) {
+				// 获取下一个元素
+				URL url = dirs.nextElement();
+				// 得到协议的名称
+				String protocol = url.getProtocol();
+				// 如果是以文件的形式保存在服务器上
+				if ("file".equals(protocol)) {
+					//System.err.println("file类型的扫描");
+					// 获取包的物理路径
+					String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
+					// 以文件的方式扫描整个包下的文件 并添加到集合中
+					findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
+				} else if ("jar".equals(protocol)) {
+					// 如果是jar包文件
+					// 定义一个JarFile
+					//System.err.println("jar类型的扫描");
+					JarFile jar;
+					try {
+						// 获取jar
+						jar = ((JarURLConnection) url.openConnection()).getJarFile();
+						// 从此jar包 得到一个枚举类
+						Enumeration<JarEntry> entries = jar.entries();
+						// 同样的进行循环迭代
+						while (entries.hasMoreElements()) {
+							// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
+							JarEntry entry = entries.nextElement();
+							String name = entry.getName();
+							// 如果是以/开头的
+							if (name.charAt(0) == '/') {
+								// 获取后面的字符串
+								name = name.substring(1);
+							}
+							// 如果前半部分和定义的包名相同
+							if (name.startsWith(packageDirName)) {
+								int idx = name.lastIndexOf('/');
+								// 如果以"/"结尾 是一个包
+								if (idx != -1) {
+									// 获取包名 把"/"替换成"."
+									packageName = name.substring(0, idx).replace('/', '.');
+								}
+								// 如果可以迭代下去 并且是一个包
+								if ((idx != -1) || recursive) {
+									// 如果是一个.class文件 而且不是目录
+									if (name.endsWith(".class") && !entry.isDirectory()) {
+										// 去掉后面的".class" 获取真正的类名
+										String className = name.substring(packageName.length() + 1, name.length() - 6);
+										try {
+											// 添加到classes
+											classes.add(Class.forName(packageName + '.' + className));
+										} catch (ClassNotFoundException e) {
+											// log
+											// .error("添加用户自定义视图类错误 找不到此类的.class文件");
+											e.printStackTrace();
+										}
+									}
+								}
+							}
+						}
+					} catch (IOException e) {
+						// log.error("在扫描用户定义视图时从jar包获取文件出错");
+						e.printStackTrace();
+					}
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		return classes;
+	}
+
+	/**
+	 * 以文件的形式来获取包下的所有Class
+	 * 
+	 * @param packageName
+	 * @param packagePath
+	 * @param recursive
+	 * @param classes
+	 */
+	public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, Set<Class<?>> classes) {
+		// 获取此包的目录 建立一个File
+		File dir = new File(packagePath);
+		// 如果不存在或者 也不是目录就直接返回
+		if (!dir.exists() || !dir.isDirectory()) {
+			// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
+			return;
+		}
+		// 如果存在 就获取包下的所有文件 包括目录
+		File[] dirfiles = dir.listFiles(new FileFilter() {
+			// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
+			public boolean accept(File file) {
+				return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
+			}
+		});
+		// 循环所有文件
+		for (File file : dirfiles) {
+			// 如果是目录 则继续扫描
+			if (file.isDirectory()) {
+				findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
+			} else {
+				// 如果是java类文件 去掉后面的.class 只留下类名
+				String className = file.getName().substring(0, file.getName().length() - 6);
+				try {
+					// 添加到集合中去
+					// classes.add(Class.forName(packageName + '.' +
+					// className));
+					// 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
+					classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
+				} catch (ClassNotFoundException e) {
+					// log.error("添加用户自定义视图类错误 找不到此类的.class文件");
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+}

+ 168 - 0
src/main/java/com/jeeplus/modules/monitor/utils/SystemInfo.java

@@ -0,0 +1,168 @@
+package com.jeeplus.modules.monitor.utils;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.hyperic.sigar.CpuPerc;
+import org.hyperic.sigar.FileSystem;
+import org.hyperic.sigar.FileSystemUsage;
+import org.hyperic.sigar.Mem;
+import org.hyperic.sigar.Sigar;
+import org.hyperic.sigar.Swap;
+
+public class SystemInfo {
+	public static Map SystemProperty() {
+		Map<String, Comparable> monitorMap = new HashMap();
+		Runtime r = Runtime.getRuntime();
+		Properties props = System.getProperties();
+		InetAddress addr = null;
+		String ip = "";
+		String hostName = "";
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			ip = "无法获取主机IP";
+			hostName = "无法获取主机名";
+		}
+		if (null != addr) {
+			try {
+				ip = addr.getHostAddress();
+			} catch (Exception e) {
+				ip = "无法获取主机IP";
+			}
+			try {
+				hostName = addr.getHostName();
+			} catch (Exception e) {
+				hostName = "无法获取主机名";
+			}
+		}
+		monitorMap.put("hostIp", ip);// 本地ip地址
+		monitorMap.put("hostName", hostName);// 本地主机名
+		monitorMap.put("osName", props.getProperty("os.name"));// 操作系统的名称
+		monitorMap.put("arch", props.getProperty("os.arch"));// 操作系统的构架
+		monitorMap.put("osVersion", props.getProperty("os.version"));// 操作系统的版本
+		monitorMap.put("processors", r.availableProcessors());// JVM可以使用的处理器个数
+		monitorMap.put("javaVersion", props.getProperty("java.version"));// Java的运行环境版本
+		monitorMap.put("vendor", props.getProperty("java.vendor"));// Java的运行环境供应商
+		monitorMap.put("javaUrl", props.getProperty("java.vendor.url"));// Java供应商的URL
+		monitorMap.put("javaHome", props.getProperty("java.home"));// Java的安装路径
+		monitorMap.put("tmpdir", props.getProperty("java.io.tmpdir"));// 默认的临时文件路径
+		return monitorMap;
+	}
+
+	public static Map memory(Sigar sigar) {
+		Map<String, Object> monitorMap = new HashMap();
+		try {
+			Runtime r = Runtime.getRuntime();
+			monitorMap.put("jvmTotal", Common.div(r.totalMemory(), (1024 * 1024), 2) + "M");// java总内存
+			monitorMap.put("jvmUse", Common.div(r.totalMemory() - r.freeMemory(), (1024 * 1024), 2) + "M");// JVM使用内存
+			monitorMap.put("jvmFree", Common.div(r.freeMemory(), (1024 * 1024), 2) + "M");// JVM剩余内存
+			monitorMap.put("jvmUsage", Common.div(r.totalMemory() - r.freeMemory(), r.totalMemory(), 2));// JVM使用率
+
+			Mem mem = sigar.getMem();
+			// 内存总量
+			monitorMap.put("ramTotal", Common.div(mem.getTotal(), (1024 * 1024 * 1024), 2) + "G");// 内存总量
+			monitorMap.put("ramUse", Common.div(mem.getUsed(), (1024 * 1024 * 1024), 2) + "G");// 当前内存使用量
+			monitorMap.put("ramFree", Common.div(mem.getFree(), (1024 * 1024 * 1024), 2) + "G");// 当前内存剩余量
+			monitorMap.put("ramUsage", Common.div(mem.getUsed(), mem.getTotal(), 2));// 内存使用率
+
+			Swap swap = sigar.getSwap();
+			// 交换区总量
+			monitorMap.put("swapTotal", Common.div(swap.getTotal(), (1024 * 1024 * 1024), 2) + "G");
+			// 当前交换区使用量
+			monitorMap.put("swapUse", Common.div(swap.getUsed(), (1024 * 1024 * 1024), 2) + "G");
+			// 当前交换区剩余量
+			monitorMap.put("swapFree", Common.div(swap.getFree(), (1024 * 1024 * 1024), 2) + "G");
+			monitorMap.put("swapUsage", Common.div(swap.getUsed(), swap.getTotal(), 2));//
+
+		} catch (Exception e) {
+		}
+		return monitorMap;
+	}
+	public static Map usage(Sigar sigar) {
+		Map<String, Long> monitorMap = new HashMap();
+		try {
+			Runtime r = Runtime.getRuntime();
+			monitorMap.put("jvmUsage", Math.round(Common.div(r.totalMemory()-r.freeMemory(), r.totalMemory(), 2)*100));// JVM使用率
+
+			Mem mem = sigar.getMem();
+			// 内存总量
+			monitorMap.put("ramUsage", Math.round(Common.div(mem.getUsed(), mem.getTotal(), 2)*100));// 内存使用率
+
+ 			List<Map> cpu = cpuInfos(sigar);
+			double b = 0.0;
+			for (Map m : cpu) {
+				b += Double.valueOf(m.get("cpuTotal")+"");
+			}
+			monitorMap.put("cpuUsage", Math.round(b/cpu.size()));// cpu使用率
+		} catch (Exception e) {
+		}
+		return monitorMap;
+	}
+
+	public static List<Map> cpuInfos(Sigar sigar) {
+		List<Map> monitorMaps = new ArrayList<Map>();
+		try {
+			CpuPerc cpuList[] = sigar.getCpuPercList();
+			for (CpuPerc cpuPerc : cpuList) {
+				Map<String, Comparable> monitorMap = new HashMap();
+				monitorMap.put("cpuUserUse", Math.round(cpuPerc.getUser()*100));// 用户使用率
+				monitorMap.put("cpuSysUse", Math.round(cpuPerc.getSys()*100));// 系统使用率
+				monitorMap.put("cpuWait", Math.round(cpuPerc.getWait()*100));// 当前等待率
+				monitorMap.put("cpuFree", Math.round(cpuPerc.getIdle()*100));// 当前空闲率
+				monitorMap.put("cpuTotal",Math.round(cpuPerc.getCombined()*100));// 总的使用率
+				monitorMaps.add(monitorMap);
+			}
+		} catch (Exception e) {
+		}
+		return monitorMaps;
+	}
+
+	public List<Map> diskInfos(Sigar sigar) throws Exception {
+		List<Map> monitorMaps = new ArrayList<Map>();
+		FileSystem fslist[] = sigar.getFileSystemList();
+		for (int i = 0; i < fslist.length; i++) {
+			Map<Object, Object> monitorMap = new HashMap();
+			FileSystem fs = fslist[i];
+			// 文件系统类型名,比如本地硬盘、光驱、网络文件系统等
+			FileSystemUsage usage = null;
+			usage = sigar.getFileSystemUsage(fs.getDirName());
+			switch (fs.getType()) {
+			case 0: // TYPE_UNKNOWN :未知
+				break;
+			case 1: // TYPE_NONE
+				break;
+			case 2: // TYPE_LOCAL_DISK : 本地硬盘
+
+				monitorMap.put("diskName", fs.getDevName());// 系统盘名称
+				monitorMap.put("diskType", fs.getSysTypeName());// 盘类型
+				// 文件系统总大小
+				monitorMap.put("diskTotal", fs.getSysTypeName());
+				// 文件系统剩余大小
+				monitorMap.put("diskFree", usage.getFree());
+				// 文件系统已经使用量
+				monitorMap.put("diskUse", usage.getUsed());
+				double usePercent = usage.getUsePercent() * 100D;
+				// 文件系统资源的利用率
+				monitorMap.put("diskUsage", usePercent);// 内存使用率
+				monitorMaps.add(monitorMap);
+				break;
+			case 3:// TYPE_NETWORK :网络
+				break;
+			case 4:// TYPE_RAM_DISK :闪存
+				break;
+			case 5:// TYPE_CDROM :光驱
+				break;
+			case 6:// TYPE_SWAP :页面交换
+				break;
+			}
+		}
+		return monitorMaps;
+	}
+
+}

+ 116 - 0
src/main/java/com/jeeplus/modules/monitor/web/MonitorController.java

@@ -0,0 +1,116 @@
+package com.jeeplus.modules.monitor.web;
+
+
+import java.util.Map;
+
+import org.hyperic.sigar.Sigar;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.mail.MailSendUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.monitor.entity.Monitor;
+import com.jeeplus.modules.monitor.service.MonitorService;
+import com.jeeplus.modules.monitor.utils.SystemInfo;
+import com.jeeplus.modules.sys.entity.SystemConfig;
+import com.jeeplus.modules.sys.service.SystemConfigService;
+
+
+/**
+ * 系统监控Controller
+ * @author liugf
+ * @version 2016-02-07
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/monitor")
+public class MonitorController extends BaseController {
+	@Autowired
+	private MonitorService monitorService;
+	@Autowired
+	private SystemConfigService systemConfigService;
+	
+	@ModelAttribute
+	public Monitor get(@RequestParam(required=false) String id) {
+		Monitor entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = monitorService.get(id);
+		}
+		if (entity == null){
+			entity = new Monitor();
+		}
+		return entity;
+	}
+	
+	@RequestMapping("info")
+	public String info(Model model) throws Exception {
+		Monitor monitor = monitorService.get("1");
+		model.addAttribute("cpu", monitor.getCpu());
+		model.addAttribute("jvm", monitor.getJvm());
+		model.addAttribute("ram", monitor.getRam());
+		model.addAttribute("toEmail", monitor.getToEmail());
+		return  "modules/monitor/info";
+	}
+	
+	@RequestMapping("monitor")
+	public String monitor() throws Exception {
+		return "modules/monitor/monitor";
+	}
+	
+	@RequestMapping("systemInfo")
+	public String systemInfo(Model model) throws Exception {
+		model.addAttribute("systemInfo", SystemInfo.SystemProperty());
+		return "modules/monitor/systemInfo";
+	}
+	
+	@ResponseBody
+	@RequestMapping("usage")
+	public Map usage(Model model) throws Exception {
+		SystemConfig config = systemConfigService.get("1");
+		Monitor monitor = monitorService.get("1");
+		Map<?, ?> sigar = SystemInfo.usage(new Sigar());
+		String content="";
+		content += "您预设的cpu使用率警告线是"+monitor.getCpu()+"%, 当前使用率是"+sigar.get("cpuUsage")+"%";
+		content += "您预设的jvm使用率警告线是"+monitor.getJvm()+"%, 当前使用率是"+sigar.get("jvmUsage")+"%";
+		content += "您预设的ram使用率警告线是"+monitor.getRam()+"%, 当前使用率是"+sigar.get("ramUsage")+"%";
+		if(Float.valueOf(sigar.get("cpuUsage").toString()) >= Float.valueOf(monitor.getCpu())
+				||Float.valueOf(sigar.get("jvmUsage").toString()) >= Float.valueOf(monitor.getJvm())
+				||Float.valueOf(sigar.get("ramUsage").toString()) >= Float.valueOf(monitor.getRam())){
+			MailSendUtils.sendEmail(config.getSmtp(), config.getPort(), config.getMailName(), config.getMailPassword(), monitor.getToEmail(), "服务器监控预警", content, "0");
+			
+		};
+		return sigar;
+	}
+	/**
+	 * 修改配置 
+	 * @param request
+	 * @param nodeId
+	 * @return
+	 * @throws Exception
+	 */
+    @ResponseBody
+	@RequestMapping("modifySetting")
+    public AjaxJson save(Monitor monitor, Model model) {
+    	AjaxJson j = new AjaxJson();
+		String message = "保存成功";
+		Monitor t = monitorService.get("1");
+		try {
+			monitor.setId("1");
+			MyBeanUtils.copyBeanNotNull2Bean(monitor, t);
+			monitorService.save(t);
+		} catch (Exception e) {
+			e.printStackTrace();
+			j.setSuccess(false);
+			message = "保存失败";
+		}
+		j.setMsg(message);
+		return j;
+    }
+}

+ 60 - 0
src/main/java/com/jeeplus/modules/oa/dao/LeaveDao.java

@@ -0,0 +1,60 @@
+/**
+ * There are <a href="http://www.jeeplus.org/">jeeplus</a> code generation
+ */
+package com.jeeplus.modules.oa.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.Leave;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 请假DAO接口
+ * @author liuj
+ * @version 2013-8-23
+ */
+@MyBatisDao
+public interface LeaveDao extends CrudDao<Leave> {
+
+	/**
+	 * 更新流程实例ID
+	 * @param leave
+	 * @return
+	 */
+	public int updateProcessInstanceId(Leave leave);
+
+	/**
+	 * 根据流程实例ID获取Leave
+	 * @param processInstanceId
+	 * @return
+	 */
+	public Leave getByProcessInstanceId(String processInstanceId);
+
+	/**
+	 * 更新实际开始结束时间
+	 * @param leave
+	 * @return
+	 */
+	public int updateRealityTime(Leave leave);
+
+	//public int update(Leave leave);
+	/**
+	 * 获取当天出差list
+	 * @param leave
+	 * @return
+	 */
+	public List<Leave> findByCompany(Leave leave);
+
+	List getCreateDateList(Map<String, String> map);
+
+    List<Leave> findByCompany2(Map<String, Object> map);
+
+	public List getCreateDateList1(Map<String,String> map);
+	public List findByCompany1(Map<String,String> map);
+	public List getCreateDateListAll(Map<String,String> map);
+	public List findByCompanyAll(Map<String,String> map);
+	public List<Leave> findByManage(Map<String,Object> map);
+	public List<Leave> findByCompanySelf(Map<String,Object> map);
+}

+ 50 - 0
src/main/java/com/jeeplus/modules/oa/dao/OaAttendanceDao.java

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.OaAttendance;
+import com.jeeplus.modules.oa.entity.OaAttendanceRule;
+import com.jeeplus.modules.sys.entity.Office;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 考勤表DAO接口
+ * @author 孟祥越
+ * @version 2017-05-10
+ */
+@MyBatisDao
+public interface OaAttendanceDao extends CrudDao<OaAttendance> {
+
+	public List<OaAttendanceRule> findListByrule(OaAttendanceRule rule);
+	
+	public List<Office> findListByCompany(Office company);
+
+	public List<OaAttendance> findByCompany(OaAttendance oaAttendance);
+
+	public List<OaAttendance> findListByUser(OaAttendance oaAttendance);
+
+    List getCreateDateList(Map<String, String> map);
+
+    List<OaAttendance> findByCompany2(Map<String, Object> map);
+
+    List<String> getCompanyList();
+
+	List<OaAttendance> getOaAttendanceList(@Param("companyId") String companyId, @Param("signDate") Date signDate);
+
+	OaAttendance getOaAttendanceByCompanyIdAndUserIdAndSignDate(Map<String, Object> map);
+
+	List getCreateDateList1(Map<String, String> map);
+
+	List<OaAttendance> findByCompany1(Map<String, String> map);
+	public List getCreateDateListAll(Map<String,String> map);
+	public List findByCompanyAll(Map<String,String> map);
+	public List<OaAttendance> findByManage(Map<String,Object> map);
+	public List<OaAttendance> findByCompanySelf(Map<String,Object> map);
+}

+ 21 - 0
src/main/java/com/jeeplus/modules/oa/dao/OaAttendancePlaceDao.java

@@ -0,0 +1,21 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.OaAttendancePlace;
+
+import java.util.List;
+
+/**
+ * 财务报销DAO接口
+ * @author 孟祥越
+ * @version 2017-05-02
+ */
+@MyBatisDao
+public interface OaAttendancePlaceDao extends CrudDao<OaAttendancePlace> {
+
+    String getPlaceNameById(String placeId);
+}

+ 31 - 0
src/main/java/com/jeeplus/modules/oa/dao/OaAttendanceRuleDao.java

@@ -0,0 +1,31 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.OaAttendanceRule;
+
+/**
+ * 考勤规则DAO接口
+ * @author 孟祥越
+ * @version 2017-05-10
+ */
+@MyBatisDao
+public interface OaAttendanceRuleDao extends CrudDao<OaAttendanceRule> {
+
+	List<OaAttendanceRule> findListByCompany(OaAttendanceRule or);
+
+	/**
+	 *	查询规则
+	 * @param map
+	 */
+	public OaAttendanceRule queryRuleByCompanyIdAndRuleId(Map<Object,Object> map);
+
+
+	
+}

+ 39 - 0
src/main/java/com/jeeplus/modules/oa/dao/OaNotifyDao.java

@@ -0,0 +1,39 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.OaNotify;
+
+import java.util.List;
+
+/**
+ * 通知通告DAO接口
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@MyBatisDao
+public interface OaNotifyDao extends CrudDao<OaNotify> {
+	
+	/**
+	 * 获取通知数目
+	 * @param oaNotify
+	 * @return
+	 */
+	public Long findCount(OaNotify oaNotify);
+
+
+    String getCreateId(String id);
+    void saveRemarks(OaNotify oaNotify);
+
+    //我的通告
+    List<OaNotify> findListByMyself(OaNotify oaNotify);
+    //我的通告
+    List<OaNotify> findListByPc(OaNotify oaNotify);
+
+    void updateStatusById(OaNotify oaNotify);
+
+    void updateProcessIdAndStatus(OaNotify oaNotify);
+}

+ 21 - 0
src/main/java/com/jeeplus/modules/oa/dao/OaNotifyDetailDao.java

@@ -0,0 +1,21 @@
+package com.jeeplus.modules.oa.dao;
+
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.OaNotify;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@MyBatisDao
+public interface OaNotifyDetailDao {
+    public void batchInsert(Map map);
+
+    public void deleteHandlers(@Param("notifyId") String notifyId, @Param("flag") int flag);
+
+    List<Office> queryOfficeList(OaNotify oaNotify);
+
+    List<User> queryUserList(OaNotify oaNotify);
+}

+ 54 - 0
src/main/java/com/jeeplus/modules/oa/dao/OaNotifyRecordDao.java

@@ -0,0 +1,54 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.dao;
+
+import java.util.List;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.OaNotifyRecord;
+
+/**
+ * 通知通告记录DAO接口
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@MyBatisDao
+public interface OaNotifyRecordDao extends CrudDao<OaNotifyRecord> {
+
+	/**
+	 * 插入通知记录
+	 * @param oaNotifyRecordList
+	 * @return
+	 */
+	public int insertAll(List<OaNotifyRecord> oaNotifyRecordList);
+	/**
+	 * 插入通知记录
+	 * @param oaNotifyRecordOfficeList
+	 * @return
+	 */
+	public int insertOfficeAll(List<OaNotifyRecord> oaNotifyRecordOfficeList);
+
+	/**
+	 * 根据通知ID删除通知记录
+	 * @param oaNotifyId 通知ID
+	 * @return
+	 */
+	public int deleteByOaNotifyId(String oaNotifyId);
+
+
+	//PC端使用
+	public List<OaNotifyRecord> findList2(OaNotifyRecord oaNotifyRecord);
+	//PC端使用
+	public List<OaNotifyRecord> findOffices(OaNotifyRecord oaNotifyRecord);
+	public List<OaNotifyRecord> findUsers(OaNotifyRecord oaNotifyRecord);
+
+
+	 public List<OaNotifyRecord> findUserList(OaNotifyRecord oaNotifyRecord);
+	
+}
+
+   
+
+

+ 28 - 0
src/main/java/com/jeeplus/modules/oa/dao/TestAuditDao.java

@@ -0,0 +1,28 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa.entity.TestAudit;
+
+/**
+ * 审批DAO接口
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@MyBatisDao
+public interface TestAuditDao extends CrudDao<TestAudit> {
+
+	public TestAudit getByProcInsId(String procInsId);
+	
+	public int updateInsId(TestAudit testAudit);
+	
+	public int updateHrText(TestAudit testAudit);
+	
+	public int updateLeadText(TestAudit testAudit);
+	
+	public int updateMainLeadText(TestAudit testAudit);
+	
+}

+ 448 - 0
src/main/java/com/jeeplus/modules/oa/entity/Leave.java

@@ -0,0 +1,448 @@
+/**
+ * There are <a href="http://www.jeeplus.org/">jeeplus</a> code generation
+ */
+package com.jeeplus.modules.oa.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.utils.DictUtils;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 请假Entity
+ *
+ * @author liuj
+ * @version 2013-04-05
+ */
+public class Leave extends ActEntity<Leave> {
+
+	private static final long serialVersionUID = 1L;
+	private String reason; // 请假原因
+	private String processInstanceId; // 流程实例编号
+	private String startTime; // 请假开始日期
+	private String endTime; // 请假结束日期
+	private String realityStartTime; // 实际开始时间
+	private String realityEndTime; // 实际结束时间
+	private String leaveType; // 假种
+	private String leaveTime; // 请假时长 李韵轩新增
+	private String leaveDays; // 请假天数 李韵轩新增
+	private String ids;
+	private String idNames;
+	private String ida;
+	private String idNamea;
+	private String idb;
+	private String idNameb;
+	private String idc;
+	private String idNamec;
+	private String idd;
+	private String idNamed;
+	private String ide;
+	private String idNamee;
+	private String CCId;
+	private Date createDateStart;
+	private Date createDateEnd;
+    private String companyId; //公司主键
+	private String officeId;
+    private String files; //
+    private String status;		// 申请状态
+	private String name;
+	private String time;
+	private List<String> adds = Lists.newArrayList();
+	private List<Workattachment> workattachmentList;
+	private String home;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getTime() {
+		return time;
+	}
+
+	public void setTime(String time) {
+		this.time = time;
+	}
+
+	public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getFiles() {
+        return files;
+    }
+
+    public void setFiles(String files) {
+        this.files = files;
+    }
+
+    public String getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(String companyId) {
+        this.companyId = companyId;
+    }
+
+    private String comment; //审核意见 目前只保存手机端审核
+	private String leaveDetails;
+
+	public static long getSerialVersionUID() {
+		return serialVersionUID;
+	}
+
+	public String getLeaveDetails() {
+		return leaveDetails;
+	}
+
+	public void setLeaveDetails(String leaveDetails) {
+		this.leaveDetails = leaveDetails;
+	}
+
+	// -- 临时属性 --//
+	// 流程任务
+	private Task task;
+	private Map<String, Object> variables;
+	// 运行中的流程实例
+	private ProcessInstance processInstance;
+	// 历史的流程实例
+	private HistoricProcessInstance historicProcessInstance;
+	// 流程定义
+	private ProcessDefinition processDefinition;
+
+	public Leave() {
+		super();
+	}
+
+	public Leave(String id) {
+		super();
+	}
+
+	public String getLeaveType() {
+		return leaveType;
+	}
+
+	public void setLeaveType(String leaveType) {
+		this.leaveType = leaveType;
+	}
+
+	public String getLeaveTypeDictLabel() {
+		return DictUtils.getDictLabel(leaveType, "oa_leave_type", "");
+	}
+
+	@Length(min = 1, max = 255)
+	public String getReason() {
+		return reason;
+	}
+
+	public void setReason(String reason) {
+		this.reason = reason;
+	}
+
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public String getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(String startTime) {
+		this.startTime = startTime;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public String getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(String endTime) {
+		this.endTime = endTime;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public String getRealityStartTime() {
+		return realityStartTime;
+	}
+
+	public void setRealityStartTime(String realityStartTime) {
+		this.realityStartTime = realityStartTime;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public String getRealityEndTime() {
+		return realityEndTime;
+	}
+
+	public void setRealityEndTime(String realityEndTime) {
+		this.realityEndTime = realityEndTime;
+	}
+
+	public User getUser() {
+		return createBy;
+	}
+
+	public void setUser(User user) {
+		this.createBy = user;
+	}
+
+	public Task getTask() {
+		return task;
+	}
+
+	public void setTask(Task task) {
+		this.task = task;
+	}
+
+	public Map<String, Object> getVariables() {
+		return variables;
+	}
+
+	public void setVariables(Map<String, Object> variables) {
+		this.variables = variables;
+	}
+
+	public ProcessInstance getProcessInstance() {
+		return processInstance;
+	}
+
+	public void setProcessInstance(ProcessInstance processInstance) {
+		this.processInstance = processInstance;
+	}
+
+	public HistoricProcessInstance getHistoricProcessInstance() {
+		return historicProcessInstance;
+	}
+
+	public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
+		this.historicProcessInstance = historicProcessInstance;
+	}
+
+	public ProcessDefinition getProcessDefinition() {
+		return processDefinition;
+	}
+
+	public void setProcessDefinition(ProcessDefinition processDefinition) {
+		this.processDefinition = processDefinition;
+	}
+
+	public String getIds() {
+		List<String> idList = Lists.newArrayList();
+		if (StringUtils.isNotBlank(ids)) {
+			String ss = ids.trim().replace(" ", ",").replace(" ", ",").replace(",", ",").replace("'", "");
+			for (String s : ss.split(",")) {
+				// if(s.matches("\\d*")) {
+				idList.add("'" + s + "'");
+				// }
+			}
+		}
+		return StringUtils.join(idList, ",");
+	}
+
+	public void setIds(String ids) {
+		this.ids = ids;
+	}
+
+	public String getIdNames() {
+		List<String> idList = Lists.newArrayList();
+		if (StringUtils.isNotBlank(idNames)) {
+			String ss = idNames.trim().replace(" ", ",").replace(" ", ",").replace(",", ",").replace("'", "");
+			for (String s : ss.split(",")) {
+				// if(s.matches("\\d*")) {
+				idList.add("'" + s + "'");
+				// }
+			}
+		}
+		return StringUtils.join(idList, ",");
+	}
+
+	public void setIdNames(String idNames) {
+		this.idNames = idNames;
+	}
+
+	@ExcelField(title="申请人", align=2, sort=12)
+	public String getIda() {
+		return ida;
+	}
+
+	public void setIda(String ida) {
+		this.ida = ida;
+	}
+
+	public String getIdNamea() {
+		return idNamea;
+	}
+
+	public void setIdNamea(String idNamea) {
+		this.idNamea = idNamea;
+	}
+
+	public String getIdb() {
+		return idb;
+	}
+
+	public void setIdb(String idb) {
+		this.idb = idb;
+	}
+
+	public String getIdNameb() {
+		return idNameb;
+	}
+
+	public void setIdNameb(String idNameb) {
+		this.idNameb = idNameb;
+	}
+
+	public String getIdc() {
+		return idc;
+	}
+
+	public void setIdc(String idc) {
+		this.idc = idc;
+	}
+
+	public String getIdNamec() {
+		return idNamec;
+	}
+
+	public void setIdNamec(String idNamec) {
+		this.idNamec = idNamec;
+	}
+
+	public String getIdd() {
+		return idd;
+	}
+
+	public void setIdd(String idd) {
+		this.idd = idd;
+	}
+
+	public String getIdNamed() {
+		return idNamed;
+	}
+
+	public void setIdNamed(String idNamed) {
+		this.idNamed = idNamed;
+	}
+
+	public String getIde() {
+		return ide;
+	}
+
+	public void setIde(String ide) {
+		this.ide = ide;
+	}
+
+	public String getIdNamee() {
+		return idNamee;
+	}
+
+	public void setIdNamee(String idNamee) {
+		this.idNamee = idNamee;
+	}
+
+	public String getCCId() {
+		return CCId;
+	}
+
+	public void setCCId(String CCId) {
+		this.CCId = CCId;
+	}
+
+	public Date getCreateDateStart() {
+		return createDateStart;
+	}
+
+	public void setCreateDateStart(Date createDateStart) {
+		this.createDateStart = createDateStart;
+	}
+
+	public Date getCreateDateEnd() {
+		return createDateEnd;
+	}
+
+	public void setCreateDateEnd(Date createDateEnd) {
+		this.createDateEnd = createDateEnd;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public String getLeaveTime() {
+		return leaveTime;
+	}
+
+	public void setLeaveTime(String leaveTime) {
+		this.leaveTime = leaveTime;
+	}
+
+	public String getLeaveDays() {
+		return leaveDays;
+	}
+
+	public void setLeaveDays(String leaveDays) {
+		this.leaveDays = leaveDays;
+	}
+
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+
+	public List<String> getAdds() {
+		return adds;
+	}
+
+	public void setAdds(List<String> adds) {
+		this.adds = adds;
+	}
+
+	public List<Workattachment> getWorkattachmentList() {
+		return workattachmentList;
+	}
+
+	public void setWorkattachmentList(List<Workattachment> workattachmentList) {
+		this.workattachmentList = workattachmentList;
+	}
+
+	public String getHome() {
+		return home;
+	}
+
+	public void setHome(String home) {
+		this.home = home;
+	}
+}

+ 170 - 0
src/main/java/com/jeeplus/modules/oa/entity/OaAttendance.java

@@ -0,0 +1,170 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.entity;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 考勤表Entity
+ * @author 孟祥越
+ * @version 2017-05-11
+ */
+public class OaAttendance extends DataEntity<OaAttendance> {
+	
+	private static final long serialVersionUID = 1L;
+	private Office company;		// 公司
+	private Office office;		// 部门
+	private OaAttendanceRule rule;		// 考勤规则
+	private User user;		// 用户
+	private Date signDate;		// 考勤日期
+	private Date startTime;		// 签到时间
+	private Date endTime;		// 签退时间
+	private String morning;     //上班情况
+	private String afternoon;   //下班情况
+	private String officeId ;   //部门id
+	private String remarks;     //备注信息
+	private Date fromThisDay;   //日期查询
+	private Date toThisDay;    //日期查询
+	public OaAttendance() {
+		super();
+	}
+
+	public OaAttendance(String id){
+		super(id);
+	}
+
+	@ExcelField(title="公司", fieldType=String.class, value="company.name", align=2, sort=10)
+	public Office getCompany() {
+		return company;
+	}
+
+	public void setCompany(Office company) {
+		this.company = company;
+	}
+	
+
+	public OaAttendanceRule getRule() {
+		return rule;
+	}
+	public void setRule(OaAttendanceRule rule) {
+		this.rule = rule;
+	}
+
+	@ExcelField(title="考勤规则",fieldType =String.class, align=2, sort=20)
+	public String getOaAttendanceRule(){
+		return rule.getStartTime()+"--"+rule.getEndTime()+"("+rule.getWorkdays()+")";
+	}
+
+
+	@ExcelField(title="用户", fieldType=User.class, value="user.name", align=2, sort=30)
+	public User getUser() {
+		return user;
+	}
+
+	public void setUser(User user) {
+		this.user = user;
+	}
+
+	public Date getStartTime() {
+		return startTime;
+	}
+	@ExcelField(title="上班时间", align=2, sort=40)
+	public String getStartTimeStr(){
+		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime);
+	}
+
+	public void setStartTime(Date startTime) {
+		this.startTime = startTime;
+	}
+
+
+	public Date getEndTime() {
+		return endTime;
+	}
+
+	@ExcelField(title="下班时间", align=2, sort=50)
+	public String getEndTimeStr(){
+		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endTime);
+	}
+
+	public void setEndTime(Date endTime) {
+		this.endTime = endTime;
+	}
+
+	@ExcelField(title = "考勤日期",align = 2,sort = 35)
+	public Date getSignDate() {
+		return signDate;
+	}
+
+	public void setSignDate(Date signDate) {
+		this.signDate = signDate;
+	}
+
+	public String getMorning() {
+		return morning;
+	}
+
+	public void setMorning(String morning) {
+		this.morning = morning;
+	}
+
+	public String getAfternoon() {
+		return afternoon;
+	}
+
+	public void setAfternoon(String afternoon) {
+		this.afternoon = afternoon;
+	}
+
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+
+	@Override
+	@ExcelField(title = "备注" ,align = 2,sort = 55)
+	public String getRemarks() {
+		return remarks;
+	}
+
+	@Override
+	public void setRemarks(String remarks) {
+		this.remarks = remarks;
+	}
+
+	@ExcelField(title="部门", fieldType=String.class, value="office.name", align=2, sort=15)
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+
+	}
+
+	public Date getFromThisDay() {
+		return fromThisDay;
+	}
+
+	public void setFromThisDay(Date fromThisDay) {
+		this.fromThisDay = fromThisDay;
+	}
+
+	public Date getToThisDay() {
+		return toThisDay;
+	}
+
+	public void setToThisDay(Date toThisDay) {
+		this.toThisDay = toThisDay;
+	}
+}

+ 81 - 0
src/main/java/com/jeeplus/modules/oa/entity/OaAttendancePlace.java

@@ -0,0 +1,81 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.entity;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.modules.sys.entity.Office;
+
+
+/**
+ * 考勤规则Entity
+ * @author 孟祥越
+ * @version 2017-05-10
+ */
+public class OaAttendancePlace extends DataEntity<OaAttendancePlace> {
+	
+	private static final long serialVersionUID = 1L;
+	private Office company;			//公司名称
+	private String placeName;		// 考勤地点
+	private String placeScope;		// 考勤范围
+	private String longitude;		// 考勤地点经度
+	private String latitude;		// 考勤地点纬度
+	private OaAttendanceRule oaAttendanceRule;		// 主表
+
+	public OaAttendancePlace() {
+		super();
+	}
+
+	public OaAttendancePlace(String id){
+		super(id);
+	}
+
+
+	public OaAttendancePlace(OaAttendanceRule oaAttendanceRule) {
+		this.oaAttendanceRule=oaAttendanceRule;
+	}
+	public String getPlaceName() {
+		return placeName;
+	}
+	public void setPlaceName(String placeName) {
+		this.placeName = placeName;
+	}
+	public String getPlaceScope() {
+		return placeScope;
+	}
+	public void setPlaceScope(String placeScope) {
+		this.placeScope = placeScope;
+	}
+	public OaAttendanceRule getOaAttendanceRule() {
+		return oaAttendanceRule;
+	}
+	public void setOaAttendanceRule(OaAttendanceRule oaAttendanceRule) {
+		this.oaAttendanceRule = oaAttendanceRule;
+	}
+
+	public String getLongitude() {
+		return longitude;
+	}
+
+	public void setLongitude(String longitude) {
+		this.longitude = longitude;
+	}
+
+	public String getLatitude() {
+		return latitude;
+	}
+
+	public void setLatitude(String latitude) {
+		this.latitude = latitude;
+	}
+
+	public Office getCompany() {
+		return company;
+	}
+
+	public void setCompany(Office company) {
+		this.company = company;
+	}
+	
+	
+}

+ 155 - 0
src/main/java/com/jeeplus/modules/oa/entity/OaAttendanceRule.java

@@ -0,0 +1,155 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.entity;
+
+import com.jeeplus.modules.sys.entity.Office;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 考勤规则Entity
+ * @author 孟祥越
+ * @version 2017-05-10
+ */
+public class OaAttendanceRule extends DataEntity<OaAttendanceRule> {
+	
+	private static final long serialVersionUID = 1L;
+	private Office company;		// 公司
+	private String startTime;		// 上班时间
+	private String endTime;		// 下班时间
+	private String workdays;		// 工作日
+	private String placeId;		// 考勤地点
+	private String wifi;		// 考勤WIFI
+    private String wifiName;		// 考勤WIFI名称
+	private String name;		// 名称
+    private String[] wifis;		// 考勤WIFI
+    private String[] wifiNames;		// 考勤WIFI名称
+    private String[] placeIds;		// 名称
+    private List list;
+	private List<OaAttendancePlace> oaAttendancePlaceList = Lists.newArrayList();		// 子表列表
+	
+	
+	public OaAttendanceRule() {
+		super();
+	}
+
+	public OaAttendanceRule(String id){
+		super(id);
+	}
+
+	@ExcelField(title="公司", fieldType=Office.class, value="company.name", align=2, sort=1)
+	public Office getCompany() {
+		return company;
+	}
+
+	public void setCompany(Office company) {
+		this.company = company;
+	}
+	
+	@ExcelField(title="上班时间", align=2, sort=2)
+	public String getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(String startTime) {
+		this.startTime = startTime;
+	}
+	
+	@ExcelField(title="下班时间", align=2, sort=3)
+	public String getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(String endTime) {
+		this.endTime = endTime;
+	}
+	
+	@ExcelField(title="工作日", align=2, sort=4)
+	public String getWorkdays() {
+		return workdays;
+	}
+
+	public void setWorkdays(String workdays) {
+		this.workdays = workdays;
+	}
+	
+	@ExcelField(title="考勤地点", align=2, sort=5)
+	public String getPlaceId() {
+		return placeId;
+	}
+
+	public void setPlaceId(String placeId) {
+		this.placeId = placeId;
+	}
+
+	@ExcelField(title="考勤WIFI", align=2, sort=6)
+	public String getWifi() {
+		return wifi;
+	}
+
+	public void setWifi(String wifi) {
+		this.wifi = wifi;
+	}
+	
+	@ExcelField(title="名称", align=2, sort=13)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<OaAttendancePlace> getOaAttendancePlaceList() {
+		return oaAttendancePlaceList;
+	}
+
+	public void setOaAttendancePlaceList(List<OaAttendancePlace> oaAttendancePlaceList) {
+		this.oaAttendancePlaceList = oaAttendancePlaceList;
+	}
+
+	public String getWifiName() {
+		return wifiName;
+	}
+
+	public void setWifiName(String wifiName) {
+		this.wifiName = wifiName;
+	}
+
+    public String[] getWifis() {
+        return wifis;
+    }
+
+    public void setWifis(String[] wifis) {
+        this.wifis = wifis;
+    }
+
+    public String[] getWifiNames() {
+        return wifiNames;
+    }
+
+    public void setWifiNames(String[] wifiNames) {
+        this.wifiNames = wifiNames;
+    }
+
+    public String[] getPlaceIds() {
+        return placeIds;
+    }
+
+    public void setPlaceIds(String[] placeIds) {
+        this.placeIds = placeIds;
+    }
+
+    public List getList() {
+        return list;
+    }
+
+    public void setList(List list) {
+        this.list = list;
+    }
+}

+ 350 - 0
src/main/java/com/jeeplus/modules/oa/entity/OaNotify.java

@@ -0,0 +1,350 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.entity;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.Collections3;
+import com.jeeplus.common.utils.IdGen;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 通知通告Entity
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+public class OaNotify extends ActEntity<OaNotify> {
+	
+	private static final long serialVersionUID = 1L;
+	private String type;		// 类型
+	private String title;		// 标题
+	private String number;      //公告编号
+	private String content;		// 类型
+	private String contents;		// 类型
+	private String files;		// 附件
+	private String status;		// 状态 0-草稿 1-发布
+	private Office company;	// 发公告公司
+	private Office office;	// 发公告部门
+	private Date startDate; //公告开始时间
+	private Date endDate; //公告结束时间
+	private List<User> userList;
+	private List<Office> officeList;
+	private String candel;
+
+	private String readNum;		// 已读
+	private String unReadNum;	// 未读
+	
+	private boolean isSelf;		// 是否只查询自己的通知
+
+    private String readFlag;	// 本人阅读状态
+    private String state;//是否富文本 1是 2不是
+	private List<Workattachment> workAttachments;//附件
+	private Date createStartDate;
+	private Date createEndDate;
+	private Date nowDate;
+
+	private String home;
+
+	private String processInstanceId;
+
+    public String getHome() {
+        return home;
+    }
+
+    public void setHome(String home) {
+        this.home = home;
+    }
+
+    public String getContents() {
+        return contents;
+    }
+
+    public void setContents(String contents) {
+        this.contents = contents;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    private List<OaNotifyRecord> oaNotifyRecordList = Lists.newArrayList();
+    private List<OaNotifyRecord> oaNotifyRecordOfficeList = Lists.newArrayList();
+
+	public OaNotify() {
+		super();
+	}
+
+	public OaNotify(String id){
+		super(id);
+	}
+
+	@Length(min=0, max=200, message="标题长度必须介于 0 和 200 之间")
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	@Length(min=0, max=1, message="状态长度必须介于 0 和 1 之间")
+	public String getStatus() {
+		return status;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+	
+	@Length(min=0, max=2000, message="附件长度必须介于 0 和 2000 之间")
+	public String getFiles() {
+		return files;
+	}
+
+	public void setFiles(String files) {
+		this.files = files;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public String getReadNum() {
+		return readNum;
+	}
+
+	public void setReadNum(String readNum) {
+		this.readNum = readNum;
+	}
+
+	public String getUnReadNum() {
+		return unReadNum;
+	}
+
+	public void setUnReadNum(String unReadNum) {
+		this.unReadNum = unReadNum;
+	}
+	
+	public List<OaNotifyRecord> getOaNotifyRecordList() {
+		return oaNotifyRecordList;
+	}
+
+	public void setOaNotifyRecordList(List<OaNotifyRecord> oaNotifyRecordList) {
+		this.oaNotifyRecordList = oaNotifyRecordList;
+	}
+	
+	/**
+	 * 获取通知发送记录用户ID
+	 * @return
+	 */
+	public String getOaNotifyRecordIds() {
+		return Collections3.extractToString(oaNotifyRecordList, "user.id", ",") ;
+	}
+	
+	/**
+	 * 设置通知发送记录用户ID
+	 * @return
+	 */
+	public void setOaNotifyRecordIds(String oaNotifyRecord) {
+		this.oaNotifyRecordList = Lists.newArrayList();
+		for (String id : StringUtils.split(oaNotifyRecord, ",")){
+			OaNotifyRecord entity = new OaNotifyRecord();
+			entity.setId(IdGen.uuid());
+			entity.setOaNotify(this);
+			entity.setUser(new User(id));
+			entity.setReadFlag("0");
+			this.oaNotifyRecordList.add(entity);
+		}
+	}
+	/**
+	 * 设置通知发送记录用户ID
+	 * @return
+	 */
+	public void setOaNotifyRecordOffices(List<Office> offices) {
+		this.oaNotifyRecordOfficeList = Lists.newArrayList();
+		for (Office office:offices){
+			OaNotifyRecord entity = new OaNotifyRecord();
+			entity.setId(IdGen.uuid());
+			entity.setOaNotify(this);
+			entity.setOfficeId(office.getId());
+			this.oaNotifyRecordOfficeList.add(entity);
+		}
+	}
+
+	/**
+	 * 获取通知发送记录用户Name
+	 * @return
+	 */
+	public String getOaNotifyRecordNames() {
+		return Collections3.extractToString(oaNotifyRecordList, "user.name", ",") ;
+	}
+	
+	/**
+	 * 设置通知发送记录用户Name
+	 * @return
+	 */
+	public void setOaNotifyRecordNames(String oaNotifyRecord) {
+		// 什么也不做
+	}
+
+	public boolean isSelf() {
+		return isSelf;
+	}
+
+	public void setSelf(boolean isSelf) {
+		this.isSelf = isSelf;
+	}
+
+	public String getReadFlag() {
+		return readFlag;
+	}
+
+	public void setReadFlag(String readFlag) {
+		this.readFlag = readFlag;
+	}
+
+	public Office getCompany() {
+		return company;
+	}
+
+	public void setCompany(Office company) {
+		this.company = company;
+	}
+
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+
+
+	public String getNumber() {
+		return number;
+	}
+
+	public void setNumber(String number) {
+		this.number = number;
+	}
+
+	public Date getStartDate() {
+		return startDate;
+	}
+
+	public void setStartDate(Date startDate) {
+		this.startDate = startDate;
+	}
+
+	public Date getEndDate() {
+		return endDate;
+	}
+
+	public void setEndDate(Date endDate) {
+		this.endDate = endDate;
+	}
+
+	public List<User> getUserList() {
+		return userList;
+	}
+
+	public void setUserList(List<User> userList) {
+		this.userList = userList;
+	}
+
+	public List<Office> getOfficeList() {
+		return officeList;
+	}
+
+	public void setOfficeList(List<Office> officeList) {
+		this.officeList = officeList;
+	}
+
+	public List<OaNotifyRecord> getOaNotifyRecordOfficeList() {
+		return oaNotifyRecordOfficeList;
+	}
+
+	public void setOaNotifyRecordOfficeList(List<OaNotifyRecord> oaNotifyRecordOfficeList) {
+		this.oaNotifyRecordOfficeList = oaNotifyRecordOfficeList;
+	}
+
+	public List<Workattachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<Workattachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+
+	public String getCandel() {
+		return candel;
+	}
+
+	public void setCandel(String candel) {
+		this.candel = candel;
+	}
+
+	public Date getCreateStartDate() {
+		return createStartDate;
+	}
+
+	public void setCreateStartDate(Date createStartDate) {
+		this.createStartDate = createStartDate;
+	}
+
+	public Date getCreateEndDate() {
+		return createEndDate;
+	}
+
+	public void setCreateEndDate(Date createEndDate) {
+		this.createEndDate = createEndDate;
+	}
+
+	public Date getNowDate() {
+		return nowDate;
+	}
+
+	public void setNowDate(Date nowDate) {
+		this.nowDate = nowDate;
+	}
+
+    public String getProcessInstanceId() {
+        return processInstanceId;
+    }
+
+    public void setProcessInstanceId(String processInstanceId) {
+        this.processInstanceId = processInstanceId;
+    }
+/*	@Override
+	public String toString() {
+		return "OaNotify [type=" + type + ", title=" + title + ", content=" + content + ", files=" + files + ", status="
+				+ status + ", company=" + company + ", readNum=" + readNum + ", unReadNum=" + unReadNum + ", isSelf="
+				+ isSelf + ", readFlag=" + readFlag + ", oaNotifyRecordList=" + oaNotifyRecordList + "]";
+	}*/
+	
+}

+ 90 - 0
src/main/java/com/jeeplus/modules/oa/entity/OaNotifyRecord.java

@@ -0,0 +1,90 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.entity;
+
+import org.hibernate.validator.constraints.Length;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.modules.sys.entity.User;
+
+import java.util.Date;
+
+
+/**
+ * 通知通告记录Entity
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+public class OaNotifyRecord extends DataEntity<OaNotifyRecord> {
+	
+	private static final long serialVersionUID = 1L;
+	private OaNotify oaNotify;		// 通知通告ID
+	private User user;		// 接受人
+	private String readFlag;		// 阅读标记(0:未读;1:已读)
+	private Date readDate;		// 阅读时间
+	private String officeId; //部门id
+	private String officeName; //部门id
+
+	
+	public OaNotifyRecord() {
+		super();
+	}
+
+	public OaNotifyRecord(String id){
+		super(id);
+	}
+	
+	public OaNotifyRecord(OaNotify oaNotify){
+		this.oaNotify = oaNotify;
+	}
+
+	public OaNotify getOaNotify() {
+		return oaNotify;
+	}
+
+	public void setOaNotify(OaNotify oaNotify) {
+		this.oaNotify = oaNotify;
+	}
+	
+	public User getUser() {
+		return user;
+	}
+
+	public void setUser(User user) {
+		this.user = user;
+	}
+	
+	@Length(min=0, max=1, message="阅读标记(0:未读;1:已读)长度必须介于 0 和 1 之间")
+	public String getReadFlag() {
+		return readFlag;
+	}
+
+	public void setReadFlag(String readFlag) {
+		this.readFlag = readFlag;
+	}
+	
+	public Date getReadDate() {
+		return readDate;
+	}
+
+	public void setReadDate(Date readDate) {
+		this.readDate = readDate;
+	}
+
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+
+	public String getOfficeName() {
+		return officeName;
+	}
+
+	public void setOfficeName(String officeName) {
+		this.officeName = officeName;
+	}
+}

+ 182 - 0
src/main/java/com/jeeplus/modules/oa/entity/TestAudit.java

@@ -0,0 +1,182 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.entity;
+
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+
+/**
+ * 审批Entity
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+public class TestAudit extends ActEntity<TestAudit> {
+	
+	private static final long serialVersionUID = 1L;
+	private User 	user;	//	归属用户
+	private Office 	office;	//	归属部门
+	private String 	post;	//	岗位
+	private String 	age;	//	性别
+	private String 	edu;	//	学历
+	private String 	content;	//	调整原因
+	private String 	olda;	//	现行标准 薪酬档级
+	private String 	oldb;	//	现行标准 月工资额
+	private String 	oldc;	//	现行标准 年薪总额
+	private String 	newa;	//	调整后标准 薪酬档级
+	private String 	newb;	//	调整后标准 月工资额
+	private String 	newc;	//	调整后标准 年薪总额
+	private String 	addNum;	//	月增资
+	private String 	exeDate;	//	执行时间
+	private String 	hrText;		//	人力资源部门意见
+	private String 	leadText;	//	分管领导意见
+	private String 	mainLeadText;//	集团主要领导意见
+
+	public TestAudit() {
+		super();
+	}
+
+	public TestAudit(String id){
+		super(id);
+	}
+	
+	public String getPost() {
+		return post;
+	}
+
+	public void setPost(String post) {
+		this.post = post;
+	}
+
+	public String getAge() {
+		return age;
+	}
+
+	public void setAge(String age) {
+		this.age = age;
+	}
+
+	public String getEdu() {
+		return edu;
+	}
+
+	public void setEdu(String edu) {
+		this.edu = edu;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public String getOlda() {
+		return olda;
+	}
+
+	public void setOlda(String olda) {
+		this.olda = olda;
+	}
+
+	public String getOldb() {
+		return oldb;
+	}
+
+	public void setOldb(String oldb) {
+		this.oldb = oldb;
+	}
+
+	public String getOldc() {
+		return oldc;
+	}
+
+	public void setOldc(String oldc) {
+		this.oldc = oldc;
+	}
+
+	public String getNewa() {
+		return newa;
+	}
+
+	public void setNewa(String newa) {
+		this.newa = newa;
+	}
+
+	public String getNewb() {
+		return newb;
+	}
+
+	public void setNewb(String newb) {
+		this.newb = newb;
+	}
+
+	public String getNewc() {
+		return newc;
+	}
+
+	public void setNewc(String newc) {
+		this.newc = newc;
+	}
+
+	public String getExeDate() {
+		return exeDate;
+	}
+
+	public void setExeDate(String exeDate) {
+		this.exeDate = exeDate;
+	}
+
+	public String getHrText() {
+		return hrText;
+	}
+
+	public void setHrText(String hrText) {
+		this.hrText = hrText;
+	}
+
+	public String getLeadText() {
+		return leadText;
+	}
+
+	public void setLeadText(String leadText) {
+		this.leadText = leadText;
+	}
+
+	public String getMainLeadText() {
+		return mainLeadText;
+	}
+
+	public void setMainLeadText(String mainLeadText) {
+		this.mainLeadText = mainLeadText;
+	}
+
+	public User getUser() {
+		return user;
+	}
+
+	public void setUser(User user) {
+		this.user = user;
+	}
+
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+
+	public String getAddNum() {
+		return addNum;
+	}
+
+	public void setAddNum(String addNum) {
+		this.addNum = addNum;
+	}
+	
+}
+
+

+ 43 - 0
src/main/java/com/jeeplus/modules/oa/service/LeaveModifyProcessor.java

@@ -0,0 +1,43 @@
+package com.jeeplus.modules.oa.service;
+
+import java.util.Date;
+
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.delegate.DelegateTask;
+import org.activiti.engine.delegate.TaskListener;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.oa.dao.LeaveDao;
+import com.jeeplus.modules.oa.entity.Leave;
+
+/**
+ * 调整请假内容处理器
+ * @author liuj
+ */
+@Service
+@Transactional
+public class LeaveModifyProcessor implements TaskListener {
+	
+	private static final long serialVersionUID = 1L;
+
+	@Autowired
+	private LeaveDao leaveDao;
+	@Autowired
+	private RuntimeService runtimeService;
+
+	public void notify(DelegateTask delegateTask) {
+		String processInstanceId = delegateTask.getProcessInstanceId();
+		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+		Leave leave = new Leave(processInstance.getBusinessKey());
+		leave.setLeaveType((String) delegateTask.getVariable("leaveType"));
+		leave.setStartTime(delegateTask.getVariable("startTime").toString());
+		leave.setEndTime(delegateTask.getVariable("endTime").toString());
+		leave.setReason((String) delegateTask.getVariable("reason"));
+		leave.preUpdate();
+		leaveDao.update(leave);
+	}
+
+}

+ 44 - 0
src/main/java/com/jeeplus/modules/oa/service/LeaveReportProcessor.java

@@ -0,0 +1,44 @@
+package com.jeeplus.modules.oa.service;
+
+import java.util.Date;
+
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.delegate.DelegateTask;
+import org.activiti.engine.delegate.TaskListener;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.oa.dao.LeaveDao;
+import com.jeeplus.modules.oa.entity.Leave;
+
+/**
+ * 销假后处理器
+ * @author liuj
+ */
+@Service
+@Transactional
+public class LeaveReportProcessor implements TaskListener {
+
+	private static final long serialVersionUID = 1L;
+
+	@Autowired
+	private LeaveDao leaveDao;
+	@Autowired
+	private RuntimeService runtimeService;
+	
+	/**
+	 * 销假完成后执行,保存实际开始和结束时间
+	 */
+	public void notify(DelegateTask delegateTask) {
+		String processInstanceId = delegateTask.getProcessInstanceId();
+		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+		Leave leave = new Leave(processInstance.getBusinessKey());
+		leave.setRealityStartTime(delegateTask.getVariable("realityStartTime").toString());
+		leave.setRealityEndTime(delegateTask.getVariable("realityEndTime").toString());
+		leave.preUpdate();
+		leaveDao.updateRealityTime(leave);
+	}
+
+}

+ 729 - 0
src/main/java/com/jeeplus/modules/oa/service/LeaveService.java

@@ -0,0 +1,729 @@
+/**
+ * There are <a href="http://www.jeeplus.org/">jeeplus</a> code generation
+ */
+package com.jeeplus.modules.oa.service;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.BaseService;
+import com.jeeplus.common.utils.Collections3;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oa.dao.LeaveDao;
+import com.jeeplus.modules.oa.entity.Leave;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 请假Service
+ * @author liuj
+ * @version 2013-04-05
+ */
+@SuppressWarnings("all")
+@Service
+@Transactional(readOnly = true)
+public class LeaveService extends BaseService {
+    @Autowired
+    private LeaveDao leaveDao;
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    protected TaskService taskService;
+    @Autowired
+    protected HistoryService historyService;
+    @Autowired
+    protected RepositoryService repositoryService;
+    @Autowired
+    private IdentityService identityService;
+    @Autowired
+    private UserDao userDao;
+    @Autowired
+    private ApprovalCopyService approvalCopyService;
+
+    @Autowired
+    private ActTaskService actTaskService;
+    @Autowired
+    private WorkProjectNotifyService workProjectNotifyService;
+    @Autowired
+    private WorkattachmentService workattachmentService;
+
+    /**
+     * 获取流程详细及工作流参数
+     * @param id
+     */
+    @SuppressWarnings("unchecked")
+    public Leave get(String id) {
+        Leave leave = leaveDao.get(id);
+        Map<String,Object> variables=null;
+        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(leave.getProcessInstanceId()).singleResult();
+        if(historicProcessInstance!=null) {
+            variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
+        } else {
+            variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(leave.getProcessInstanceId()).active().singleResult().getId());
+        }
+        leave.setVariables(variables);
+
+        List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(leave.getId(),"71");
+        leave.setWorkattachmentList(workattachmentList);
+        return leave;
+    }
+
+    /**
+     * 获取流程详细及工作流参数
+     * @param id
+     */
+    @SuppressWarnings("unchecked")
+    public Leave getById(String id) {
+        Leave leave = leaveDao.get(id);
+        return leave;
+    }
+
+    /**
+     * 获取流程详细Leave
+     * @param processInstanceId
+     */
+    @SuppressWarnings("unchecked")
+    public Leave getByProcessInstanceId(String processInstanceId) {
+        Leave leave = leaveDao.getByProcessInstanceId(processInstanceId);
+        return leave;
+    }
+
+    @Transactional(readOnly = false)
+    public void save(Leave leave) {
+        if (leave.getIsNewRecord()){
+            leave.preInsert();
+            leaveDao.insert(leave);
+        }else{
+            leave.preUpdate();
+            leaveDao.update(leave);
+        }
+    }
+
+    /**
+     * 启动流程
+     * @param
+     */
+    @Transactional(readOnly = false)
+    public void save(Leave leave, Map<String, Object> variables,String type) {
+        // 保存业务数据
+        if (StringUtils.isBlank(leave.getId())){
+            leave.preInsert();
+            leaveDao.insert(leave);
+            logger.debug("save entity: {}", leave);
+
+            // 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+            identityService.setAuthenticatedUserId(leave.getCurrentUser().getId());
+            // 启动流程
+            String businessKey = leave.getId().toString();
+            variables.put("type", "leave");
+            variables.put("busId", businessKey);
+            variables.put("title", leave.getReason());//设置标题;
+            /*String pd_audit_process = "";
+            if (type.equals("1")){
+                pd_audit_process = ActUtils.PD_AUDIT_PROCESS1[0];
+            }else if (type.equals("2")){
+                pd_audit_process = ActUtils.PD_AUDIT_PROCESS2[0];
+            }else if (type.equals("3")){
+                pd_audit_process = ActUtils.PD_AUDIT_PROCESS3[0];
+            }else if (type.equals("4")){
+                pd_audit_process = ActUtils.PD_AUDIT_PROCESS4[0];
+            }else if (type.equals("5")){
+                pd_audit_process = ActUtils.PD_AUDIT_PROCESS5[0];
+            }*/
+            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ActUtils.PD_LEAVE[0], businessKey, variables);
+            leave.setProcessInstance(processInstance);
+            // 更新流程实例ID
+            leave.setProcessInstanceId(processInstance.getId());
+            leaveDao.updateProcessInstanceId(leave);
+        }else{
+            leave.preUpdate();
+            leaveDao.update(leave);
+            leave.getAct().setComment(("yes".equals(leave.getAct().getFlag()) ? "[重申] " : "[销毁] ") + leave.getAct().getComment());
+
+            // 完成流程任务
+            Map<String, Object> vars = Maps.newHashMap();
+            vars.put("pass", "yes".equals(leave.getAct().getFlag())? true : false);
+            actTaskService.complete(leave.getAct().getTaskId(), leave.getAct().getProcInsId(), leave.getAct().getComment(), leave.getComment(), vars);
+        }
+
+
+    }
+
+    @Transactional(readOnly = false)
+    public void saveFile(Leave leave) {
+        if (StringUtils.isBlank(leave.getId())){
+            leave.preInsert();
+            leaveDao.insert(leave);
+        }else{
+            leave.preUpdate();
+            leaveDao.update(leave);
+        }
+    }
+
+    /**
+     * 查询待办任务
+     * @param userId 用户ID
+     * @return
+     */
+    public List<Leave> findTodoTasks(String userId) {
+
+        List<Leave> results = new ArrayList<Leave>();
+        List<Task> tasks = new ArrayList<Task>();
+        // 根据当前人的ID查询
+        List<Task> todoList = taskService.createTaskQuery().processDefinitionKey(ActUtils.PD_LEAVE[0]).taskAssignee(userId).active().orderByTaskPriority().desc().orderByTaskCreateTime().desc().list();
+        // 根据当前人未签收的任务
+        List<Task> unsignedTasks = taskService.createTaskQuery().processDefinitionKey(ActUtils.PD_LEAVE[0]).taskCandidateUser(userId).active().orderByTaskPriority().desc().orderByTaskCreateTime().desc().list();
+        // 合并
+        tasks.addAll(todoList);
+        tasks.addAll(unsignedTasks);
+        System.out.println("---------------------size="+tasks.size());
+        // 根据流程的业务ID查询实体并关联
+        for (Task task : tasks) {
+            String processInstanceId = task.getProcessInstanceId();
+            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
+            String businessKey = processInstance.getBusinessKey();
+            Leave leave = leaveDao.get(businessKey);
+            leave.setTask(task);
+            leave.setProcessInstance(processInstance);
+            leave.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId((processInstance.getProcessDefinitionId())).singleResult());
+            results.add(leave);
+        }
+        return results;
+    }
+
+    public Page<Leave> find(Page<Leave> page, Leave leave) {
+
+        leave.getSqlMap().put("dsf", dataScopeFilter(leave.getCurrentUser(), "o", "u","", MenuStatusEnum.LEAVE.getValue()));
+        leave.setPage(page);
+        page.setList(leaveDao.findList(leave));
+
+        for(Leave item : page.getList()) {
+            String processInstanceId = item.getProcessInstanceId();
+            Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
+            //item.setTask(task);
+            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+            if(historicProcessInstance!=null) {
+                item.setHistoricProcessInstance(historicProcessInstance);
+                item.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult());
+            } else {
+                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
+                if (processInstance != null){
+                    item.setProcessInstance(processInstance);
+                    item.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult());
+                }
+            }
+            ProcessInstance processInstance = actTaskService.getProcIns(item.getProcessInstanceId());
+            if (processInstance!=null) {
+                Task taskInfok = actTaskService.getCurrentTaskInfo(processInstance);
+                if (StringUtils.isNotBlank(taskInfok.getAssignee()) && taskInfok.getAssignee().equals(UserUtils.getUser().getId())) {
+                    item.setTask(taskInfok);
+                }
+            }
+        }
+        return page;
+    }
+
+    @Transactional(readOnly = false)
+    public void delete(Leave Leave) {
+        leaveDao.delete(Leave);
+    }
+
+    @Transactional(readOnly = false)
+    public void update(Leave Leave) {
+        Leave.preUpdate();
+        leaveDao.update(Leave);
+    }
+
+    @Transactional(readOnly = false)
+    public Map getLeaveById(String id,String type) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Leave leave = this.getById(id);
+        Map<String,Object> map = Maps.newHashMap();
+        String officeName = "";
+        String officeId = "";
+        if(leave!=null){
+            User user = userDao.get(leave.getCreateBy());
+            if(user!=null){
+                map.put("userName", user.getName());
+                map.put("photo",user.getPhoto());
+                map.put("users", user.getId());
+                Office office = user.getOffice();
+                if(office!=null && office.getName()!=null){
+                    officeName = office.getName();
+                    officeId = office.getId();
+                }
+            }
+            map.put("createDate",leave.getCreateDate()==null?"":sdf.format(leave.getCreateDate()));
+            map.put("startTime",leave.getStartTime());
+            map.put("endTime",leave.getEndTime());
+            String leaveType = leave.getLeaveType();
+            if (leaveType.equals("1")){
+                leaveType = "事假";
+            }else if(leaveType.equals("2")){
+                leaveType = "病假";
+            }else if(leaveType.equals("3")){
+                leaveType = "调休";
+            }else if(leaveType.equals("4")){
+                leaveType = "年假";
+            }else if(leaveType.equals("5")){
+                leaveType = "婚假";
+            }else if(leaveType.equals("6")){
+                leaveType = "产假";
+            }else if(leaveType.equals("7")){
+                leaveType = "其他";
+            }
+            map.put("leaveType",leaveType);
+            map.put("leaveDays",leave.getLeaveDays());
+            map.put("leaveTime",leave.getLeaveTime());
+            map.put("reason",leave.getReason());
+            map.put("companyId",leave.getCompanyId());
+            map.put("officeName",officeName);
+            map.put("officeId",officeId);
+            map.put("approvalId",id);
+            map.put("status",leave.getStatus());
+            List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(leave.getId(),"71");
+            String files = "";
+            if (workattachmentList!=null && workattachmentList.size()!=0){
+                for (Workattachment workattachment : workattachmentList){
+                    files += workattachment.getUrl()+",";
+                }
+                if (files.length() > 1) {
+                    files = files.substring(0, files.length() - 1);
+                }
+            }
+            map.put("files", files);
+            List<Act> list = actTaskService.histoicFlowList(leave.getProcessInstanceId(), "", "");
+            List<Act> list2 = actTaskService.toMyStartedList(leave.getProcessInstanceId());
+            if (list2!=null && list2.size()!=0){
+                Act act1 = list2.get(list2.size()-1);
+                map.put("taskId", act1.getTaskId());
+                map.put("taskName",act1.getTaskName());
+                map.put("procInsId", act1.getProcInsId());
+                map.put("procDefId", act1.getProcDefId());
+                map.put("actStatus", act1.getStatus()==null?"todo":act1.getStatus());
+                map.put("taskDefKey", act1.getTaskDefKey());
+                map.put("procDefKey", "leave");
+            }
+            List list1 = new ArrayList();
+            String approvalStatus = "0";
+            String assigneeName = "";
+            if (list!=null && list.size()!=0) {
+                if (list.get(0).getHistIns().getActivityName().contains("审批")) {
+                    for (int i = list.size() - 1; i > -1; i--) {
+                        Act act = list.get(i);
+                        Map<String, Object> maps = new HashMap<String, Object>();
+                        String state = "0";
+                        String activityName = "";
+                        if (act.getHistIns().getActivityName().contains("审批")) {
+                            if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+                                activityName = "已审批";
+                                if (UserUtils.getUser().getName().equals(act.getAssigneeName())){
+                                    approvalStatus = "1";
+                                }
+                            } else {
+                                activityName = "待审批";
+                                state = "2";
+                            }
+                        } else {
+                            activityName = act.getHistIns().getActivityName();
+                        }
+                        if (type.equals("1") || type.equals("2")) {
+                            maps.put("activityName", activityName);
+                            maps.put("assigneeName", UserUtils.getUser().getName().equals(act.getAssigneeName()) ? "我" : act.getAssigneeName());
+                        } else if (type.equals("3")) {
+                            maps.put("activityName", activityName);
+                            maps.put("assigneeName", act.getAssigneeName());
+                        }
+                        maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+                        maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+                        maps.put("durationTime", act.getDurationTime());
+                        maps.put("state", state);
+                        maps.put("userId", act.getCurrentUser().getId());
+                        list1.add(maps);
+                    }
+                } else {
+                    if (leave.getStatus().equals("4") || leave.getStatus().equals("3")){
+                        for (int i = 0; i < list.size()-1; i++) {
+                            Act act = list.get(i);
+                            Map<String, Object> maps = new HashMap<String, Object>();
+                            String state = "0";
+                            String activityName = "";
+                            if (act.getHistIns().getActivityName().contains("发起申请")) {
+                                activityName = act.getHistIns().getActivityName();
+                                assigneeName = act.getAssigneeName();
+                            }else if (act.getHistIns().getActivityName().contains("审批")) {
+                                if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                                if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+                                    activityName = "已审批";
+                                    if (UserUtils.getUser().getName().equals(assigneeName)){
+                                        approvalStatus = "1";
+                                    }
+                                    if (i == (list.size()-2) && leave.getStatus().equals("4")){
+                                        activityName = "审核驳回";
+                                        state = "1";
+                                    }else if (i == (list.size()-2) && leave.getStatus().equals("3")){
+                                        activityName = "审核成功";
+                                    }
+                                } else {
+                                    activityName = "待审批";
+                                    state = "2";
+                                }
+                            }
+                            else {
+                                activityName = act.getHistIns().getActivityName();
+                                if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                            }
+                            maps.put("activityName", activityName);
+                            maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+                            maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+                            maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+                            maps.put("durationTime", act.getDurationTime());
+                            maps.put("state", state);
+                            maps.put("userId", act.getCurrentUser().getId());
+                            list1.add(maps);
+                        }
+                    }else {
+                        for (int i = 0; i < list.size(); i++) {
+                            Act act = list.get(i);
+                            Map<String, Object> maps = new HashMap<String, Object>();
+                            String state = "0";
+                            String activityName = "";
+                            if (act.getHistIns().getActivityName().contains("发起申请")) {
+                                activityName = act.getHistIns().getActivityName();
+                                assigneeName = act.getAssigneeName();
+                            }else if (act.getHistIns().getActivityName().contains("审批")) {
+                                if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                                if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+                                    activityName = "已审批";
+                                    if (UserUtils.getUser().getName().equals(assigneeName)){
+                                        approvalStatus = "1";
+                                    }
+                                } else {
+                                    activityName = "待审批";
+                                    state = "2";
+                                }
+                            }
+                            else {
+                                activityName = act.getHistIns().getActivityName();
+                                if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                            }
+                            if (leave.getStatus().equals("5") && i == list.size() - 1) {
+                                activityName = "已撤销";
+                                state = "1";
+                            }
+                            maps.put("activityName", activityName);
+                            maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+                            maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+                            maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+                            maps.put("durationTime", act.getDurationTime());
+                            maps.put("state", state);
+                            maps.put("userId", act.getCurrentUser().getId());
+                            list1.add(maps);
+                        }
+                    }
+                }
+            }
+            map.put("approvalStatus", approvalStatus);
+            ApprovalCopy approvalCopy = new ApprovalCopy();
+            approvalCopy.setApprovalId(id);
+            List<ApprovalCopy> approvalCopyList = approvalCopyService.findList(approvalCopy);
+            String CCName = "";
+            String CCId = "";
+            Boolean readFlag = false;
+            if (approvalCopyList!=null && approvalCopyList.size()!=0) {
+                ApprovalCopy approvalCopy1 = approvalCopyList.get(0);
+                CCId = approvalCopy1.getCCId();
+                String[] CCid = approvalCopy1.getCCId().split(",");
+                readFlag = approvalCopy1.getReadFlag().equals("0");
+                if (type.equals("3") && readFlag){
+                    approvalCopy1.setReadFlag("1");
+                    approvalCopyService.save(approvalCopy1);
+                }
+                for (String userId : CCid) {
+                    User CCUser = UserUtils.get(userId);
+                    if (CCUser != null) {
+                        CCName = CCUser.getName() + ",";
+                    }
+                }
+                if (CCName.length() > 1) {
+                    CCName = CCName.substring(0, CCName.length() - 1);
+                } else {
+                    CCName = "";
+                }
+            }
+
+            map.put("nameCopy",CCName);
+            map.put("CCId",CCId);
+            map.put("process",list1);
+        }
+        return map;
+    }
+
+    /* * 审核审批保存
+     * @param testAudit
+     */
+    @Transactional(readOnly = false)
+    public String auditSave(Leave leave) {
+        try{
+            // 设置意见
+            leave.getAct().setComment(("yes".equals(leave.getAct().getFlag())?"[同意] ":"[驳回] ")+leave.getAct().getComment());
+            System.out.println("comment================="+leave.getAct().getComment());
+
+            // 对不同环节的业务逻辑进行操作
+            String taskDefKey = leave.getAct().getTaskDefKey();
+            System.out.println("taskDefKey====================="+taskDefKey);
+
+            //发送通知
+            WorkProjectNotify notify = new WorkProjectNotify();
+            notify.setNotifyId(leave.getId());
+            notify.setCompanyId(UserUtils.getSelectCompany().getId());
+            notify.setType("24");
+            notify.setStatus("0");
+            notify.setNotifyRole("");
+
+            //业务逻辑对应的条件表达式
+            String exp = "";
+            // 审核环节
+            if ("audit1".equals(taskDefKey)){
+                exp = "pass";
+            } else if ("audit2".equals(taskDefKey)) {
+                exp = "pass";
+            } else if ("audit3".equals(taskDefKey)){
+                exp = "pass";
+            }else if ("audit4".equals(taskDefKey)){
+                exp = "pass";
+            }else if ("audit5".equals(taskDefKey)){
+                exp = "pass";
+            }else if("apply_end".equals(taskDefKey)){
+                exp = "pass";
+            }
+            // 未知环节,直接返回
+            else{
+                return "保存审核意见失败!!";
+            }
+            // 提交流程任务
+            Map<String, Object> vars = Maps.newHashMap();
+            vars.put(exp, "yes".equals(leave.getAct().getFlag()) ? false : true);
+            System.out.println("vars============"+vars.toString());
+            // 提交流程任务
+            actTaskService.complete(leave.getAct().getTaskId(), leave.getAct().getProcInsId(), leave.getAct().getComment(), vars);
+            boolean state = actTaskService.isProcessEnd(leave.getAct().getProcInsId());
+            leave.setStatus("2");
+            if (!state){
+                if ("yes".equals(leave.getAct().getFlag())){
+                    leave.setStatus("3");
+                }else {
+                    leave.setStatus("4");
+                }
+            }
+            leave.preUpdate();
+            this.update(leave);
+
+            //需在leave更新后 操作:
+            //1待审核  2审核中 3通过 4驳回 5已撤销 6催办中
+            if("2".equals(leave.getStatus())){
+                leave = this.get(leave.getId());
+                String userId = leave.getVariables().get("assignee").toString();
+                if(StringUtils.isNotBlank(userId)){
+                    notify.setUser(UserUtils.get(userId));
+                }
+                notify.setTitle("您有新的请假申请待审批");
+                notify.setRemarks("待审批");
+                notify.setContent("请假申请--待审批");
+
+            }else if("3".equals(leave.getStatus())){
+                notify.setUser(leave.getCreateBy());
+                notify.setTitle("您的请假申请已通过");
+                notify.setRemarks("待通知");
+                notify.setContent(leave.getAct().getComment());
+            }else if("4".equals(leave.getStatus())){
+                notify.setUser(leave.getCreateBy());
+                notify.setTitle("您的请假申请被驳回");
+                notify.setRemarks("待通知");
+                notify.setContent(leave.getAct().getComment());
+            }
+            workProjectNotifyService.save(notify);
+
+            //更新审核人的阅读状态
+            WorkProjectNotify notify2 = new WorkProjectNotify();
+            notify2.setUser(UserUtils.getUser());
+            notify2.setNotifyId(leave.getId());
+            workProjectNotifyService.readByNotifyIdAndNotifyUser(notify2);
+
+            //抄送
+            if("3".equals(leave.getStatus()) || "4".equals(leave.getStatus())){
+                ApprovalCopy approvalCopy = approvalCopyService.getByApprovalId(leave.getId());
+                if(approvalCopy!=null && StringUtils.isNotBlank(approvalCopy.getCCId())){
+                    WorkProjectNotify notify1= new WorkProjectNotify();
+                    notify1.setNotifyId(leave.getId());
+                    notify1.setCompanyId(UserUtils.getSelectCompany().getId());
+                    notify1.setType("24");
+                    notify1.setStatus("0");
+                    notify1.setNotifyRole("");
+                    notify1.setContent(leave.getAct().getComment());
+                    String[] ccIds = approvalCopy.getCCId().split(",");
+                    for(String ccId : ccIds){
+                        if(StringUtils.isNotBlank(ccId)){
+                            notify1.setUser(new User(ccId));
+                            if("3".equals(leave.getStatus())){
+                                notify1.setTitle(UserUtils.get(leave.getCreateBy().getId()).getName()+"的请假申请已通过");
+                            }
+                            if("4".equals(leave.getStatus())){
+                                notify1.setTitle(UserUtils.get(leave.getCreateBy().getId()).getName()+"的请假申请被驳回");
+                            }
+                            notify1.setRemarks("待通知");
+                            notify1.setId("");
+                            workProjectNotifyService.save(notify1);
+                        }
+                    }
+                }
+            }
+            return "保存审核意见成功!";
+        }catch (ActivitiObjectNotFoundException e){
+            logger.error("ActivitiObjectNotFoundException e:"+e);
+            return "流程已审批,不能重新审批!";
+        }catch (Exception e){
+            logger.error("Exception e:"+e);
+            return "保存审核意见失败!!";
+        }
+    }
+
+    public List getCreateDateList(String companyId, String date) {
+        Map<String,String> map = new HashMap<>();
+        map.put("companyId",companyId);
+        map.put("date",date);
+        return leaveDao.getCreateDateList(map);
+    }
+
+    public List<Leave> findByCompany2(Leave leave, String date) {
+        Map<String,Object> map = new HashMap<>();
+        map.put("leave",leave);
+        map.put("date",date);
+        return leaveDao.findByCompany2(map);
+    }
+
+    @Transactional(readOnly = false)
+    public void sendNotify(String chaosongIds,String shenpiId,String oaLeaveId) {
+        if(StringUtils.isNotBlank(oaLeaveId)){
+            if(StringUtils.isNotBlank(chaosongIds)){
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setTitle(UserUtils.getUser().getName()+"发起了请假申请");
+                notify.setRemarks("待通知");
+                notify.setContent(UserUtils.getUser().getName()+"的请假申请");
+                notify.setNotifyRole("");
+                notify.setNotifyId(oaLeaveId);
+                notify.setStatus("0");
+                notify.setCompanyId(UserUtils.getSelectCompany().getId());
+                notify.setType("24");
+                String[] arr = chaosongIds.split(",");
+                for (String id : arr){
+                    if(StringUtils.isNotBlank(id)){
+                        notify.setId("");
+                        notify.setUser(new User(id));
+                        workProjectNotifyService.save(notify);
+                    }
+                }
+            }
+            if(StringUtils.isNotBlank(shenpiId)){
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setTitle("您有新的请假申请待审批");
+                notify.setRemarks("待审批");
+                notify.setContent("请假申请--待审批");
+                notify.setNotifyRole("");
+                notify.setUser(new User(shenpiId));
+                notify.setNotifyId(oaLeaveId);
+                notify.setStatus("0");
+                notify.setCompanyId(UserUtils.getSelectCompany().getId());
+                notify.setType("24");
+                workProjectNotifyService.save(notify);
+            }
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public String uploadFile(OSSClientUtil ossClientUtil, MultipartFile file, Leave leave, String flag) {
+        String fileName = file.getOriginalFilename();
+        String fileType = fileName.substring(fileName.lastIndexOf("."));
+        String url = ossClientUtil.uploadFile2OSS(file,"leave");
+        Workattachment workattachment = new Workattachment();
+        workattachment.setUrl(url);
+        workattachment.setType(fileType);
+        workattachment.setAttachmentName(fileName);
+        workattachment.setAttachmentUser(UserUtils.getUser().getId());
+        workattachment.setAttachmentId(leave.getId());
+        workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+        workattachment.setAttachmentFlag(flag);
+        workattachmentService.save(workattachment);
+        return url;
+    }
+
+    public List getCreateDateList1(String time) {
+        Map<String,String> map = new HashMap<String,String>();
+        map.put("userId",UserUtils.getUser().getId());
+        map.put("time",time);
+        return leaveDao.getCreateDateList1(map);
+    }
+    public List<Leave> findByCompany1(String time){
+        Map<String,String> map = new HashMap<String,String>();
+        map.put("userId",UserUtils.getUser().getId());
+        map.put("time",time);
+        return leaveDao.findByCompany1(map);
+    }
+
+    public List getCreateDateListAll(String time) {
+        Map<String,String> map = new HashMap<String,String>();
+        Leave w=new Leave();
+        map.put("sqlStr",dataScopeFilter(w.getCurrentUser(), "o", "u", "s", MenuStatusEnum.LEAVE.getValue()));
+        map.put("time",time);
+        return leaveDao.getCreateDateListAll(map);
+    }
+    public List<Leave> findByCompanyAll(String time){
+        Map<String,String> map = new HashMap<String,String>();
+        Leave w=new Leave();
+        map.put("sqlStr",dataScopeFilter(w.getCurrentUser(), "o", "u", "s", MenuStatusEnum.LEAVE.getValue()));
+        map.put("time",time);
+        return leaveDao.findByCompanyAll(map);
+    }
+
+    public List<Leave> findByManage(Map<String,Object> map) {
+        return leaveDao.findByManage(map);
+    }
+    public List<Leave> findByCompanySelf(Map<String,Object> map) {
+        return leaveDao.findByCompanySelf(map);
+    }
+}

+ 719 - 0
src/main/java/com/jeeplus/modules/oa/service/ManageCalendarService.java

@@ -0,0 +1,719 @@
+package com.jeeplus.modules.oa.service;
+
+import com.jeeplus.common.service.BaseService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.TimeUtils;
+import com.jeeplus.modules.oa.dao.LeaveDao;
+import com.jeeplus.modules.oa.entity.Leave;
+import com.jeeplus.modules.oa.entity.OaAttendance;
+import com.jeeplus.modules.oa_evection.entity.oa_evection.OaEvection;
+import com.jeeplus.modules.oa_evection.service.oa_evection.OaEvectionService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.work.entity.report.WorkReport;
+import com.jeeplus.modules.work.service.report.WorkReportService;
+import com.jeeplus.modules.workgoout.entity.GoOut;
+import com.jeeplus.modules.workgoout.service.GoOutService;
+import com.jeeplus.modules.workoutsignin.entity.WorkOutSignIn;
+import com.jeeplus.modules.workoutsignin.service.WorkOutSignInService;
+import com.jeeplus.modules.workovertimeform.entity.WorkOvertimeForm;
+import com.jeeplus.modules.workovertimeform.service.WorkOvertimeFormService;
+import com.jeeplus.modules.worksealform.entity.WorkSealForm;
+import com.jeeplus.modules.worksealform.service.WorkSealFormService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Created by Meng on 2017/6/20.
+ */
+@Service
+public class ManageCalendarService extends BaseService{
+
+    @Autowired
+    private WorkReportService workReportService;
+    @Autowired
+    private WorkOutSignInService workOutSignInService;
+    @Autowired
+    private OaAttendanceService oaAttendanceService;
+    @Autowired
+    private LeaveDao LeaveDao;
+    @Autowired
+    private LeaveService leaveService;
+    @Autowired
+    private WorkSealFormService workSealFormService;
+    @Autowired
+    private OaEvectionService oaEvectionService;
+    @Autowired
+    private WorkOvertimeFormService workOvertimeFormService;
+    @Autowired
+    private GoOutService goOutService;
+
+    //优化版,供PC端使用
+    public List<Map<String,Object>> getManageCalendarByMonth2(String companyId ,String date){
+
+        WorkReport workReport = new WorkReport();
+        WorkOutSignIn workOutSignIn = new WorkOutSignIn();
+        OaAttendance oaAttendance = new OaAttendance();
+        WorkSealForm workSealForm = new WorkSealForm();
+        Leave leave = new Leave();
+        OaEvection oaEvection = new OaEvection();
+        WorkOvertimeForm workOvertimeForm = new WorkOvertimeForm();
+        GoOut goOut = new GoOut();
+        if (!UserUtils.getUser().isAdmin()){
+            workReport.setCompanyId(companyId);
+            workOutSignIn.setCompanyId(companyId);
+            oaAttendance.setCompany(UserUtils.getSelectCompany());
+            workSealForm.setCompanyId(companyId);
+            leave.setCompanyId(companyId);
+            oaEvection.setCompanyId(companyId);
+            workOvertimeForm.setCompanyId(companyId);
+            goOut.setCompanyId(companyId);
+        }
+        workReport.setDelFlag("0");
+        workOutSignIn.setDelFlag("0");
+        oaAttendance.setDelFlag("0");
+        workSealForm.setDelFlag("0");
+        leave.setDelFlag("0");
+        oaEvection.setDelFlag("0");
+        workOvertimeForm.setDelFlag("0");
+        goOut.setDelFlag("0");
+        List workReportDateList = workReportService.getCreateDateList(companyId,date);
+        List workOutSignInDateList = workOutSignInService.getCreateDateList(companyId,date);
+        List oaAttendanceDateList = oaAttendanceService.getCreateDateList(companyId,date);
+        List workSealFormDateList = workSealFormService.getCreateDateList(companyId,date);
+        List leaveDateList = leaveService.getCreateDateList(companyId,date);
+        List oaEvectionDateList = oaEvectionService.getCreateDateList(companyId,date);
+        List workOvertimeDateList = workOvertimeFormService.getCreateDateList(companyId,date);
+        List goOutDateList = goOutService.getCreateDateList(companyId,date);
+
+        Set<String> set = new TreeSet<String>();
+        for(int i=0;i<workOutSignInDateList.size();i++){
+            String str = workOutSignInDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<workReportDateList.size();i++){
+            String str = workReportDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<oaAttendanceDateList.size();i++){
+            String str = oaAttendanceDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<workSealFormDateList.size();i++){
+            String str = workSealFormDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<leaveDateList.size();i++){
+            String str = leaveDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<oaEvectionDateList.size();i++){
+            String str = oaEvectionDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<workOvertimeDateList.size();i++){
+            String str = workOvertimeDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        for(int i=0;i<goOutDateList.size();i++){
+            String str = goOutDateList.get(i).toString().substring(0,10);
+            set.add(str);
+        }
+        //有效日期
+        List<String> dateList = new ArrayList<String>(set);
+        Collections.sort(dateList, Collections.reverseOrder());
+
+        List thisMonthRecordList = new ArrayList();
+
+        List<WorkOutSignIn> workOutSignInList = workOutSignInService.findByCompany2(workOutSignIn,date);
+        List<WorkReport> workReportList = workReportService.findByCompany2(workReport,date);
+        List<OaAttendance> oaAttendanceList = oaAttendanceService.findByCompany2(oaAttendance,date);
+        List<WorkSealForm> workSealFormList = workSealFormService.findByCompany2(workSealForm,date);
+        List<Leave> leaveList = leaveService.findByCompany2(leave,date);
+        List<OaEvection> oaEvectionList = oaEvectionService.findByCompany2(oaEvection,date);
+        List<WorkOvertimeForm> workOvertimeFormList = workOvertimeFormService.findByCompany2(workOvertimeForm,date);
+        List<GoOut> goOutList = goOutService.findByCompany2(goOut,date);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        for(int i=0;i<dateList.size();i++){
+            Map<String,Object> map = new HashMap<String,Object>();
+            int num = 0 ;
+            for(WorkOutSignIn sign : workOutSignInList){
+                String createDate = sdf.format(sign.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            for(WorkReport report : workReportList){
+                String createDate = sdf.format(report.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            for(OaAttendance attendance : oaAttendanceList){
+                String createDate = sdf.format(attendance.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    if(attendance.getStartTime()!=null && !"".equals(attendance.getStartTime())){
+                        num ++ ;
+                    }
+                    if(attendance.getEndTime() != null && !"".equals(attendance.getEndTime())){
+                        num ++;
+                    }
+                }
+            }
+            for(WorkSealForm seal : workSealFormList){
+                String createDate = sdf.format(seal.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            for(Leave lev : leaveList){
+                String createDate = sdf.format(lev.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            for(OaEvection evection : oaEvectionList){
+                String createDate = sdf.format(evection.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            for(WorkOvertimeForm workOvertime : workOvertimeFormList){
+                String createDate = sdf.format(workOvertime.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            for(GoOut out : goOutList){
+                String createDate = sdf.format(out.getCreateDate()).substring(0,10);
+                if(createDate.equals(dateList.get(i))){
+                    num ++ ;
+                }
+            }
+            map.put("date",dateList.get(i));  //指定月的某一天
+            map.put("reportNum",String.valueOf(num));//当天的记录数
+
+            thisMonthRecordList.add(map);
+        }
+        return  thisMonthRecordList;
+    }
+    //手机端使用
+    public List getManageCalendarByMonth(String dateStr) {
+        dateStr = dateStr + "-01";
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date date =null;
+        try {
+            date =sdf.parse(dateStr);
+        }catch (ParseException e){
+
+        }
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);//month 为指定月份任意日期
+        int year = cal.get(Calendar.YEAR);
+        int m = cal.get(Calendar.MONTH) + 1;
+        int dayNumOfMonth = TimeUtils.getDaysByYearMonth(year, m);
+        cal.set(Calendar.DAY_OF_MONTH, 1);// 从一号开始
+        List reportList =new ArrayList();
+        for (int i = 0; i < dayNumOfMonth; i++, cal.add(Calendar.DATE, 1)) {
+            Map calMap = new HashMap();
+            Date d = cal.getTime();
+            String dd = sdf.format(d);
+            WorkReport workReport =new WorkReport();
+            workReport.setCompanyId(UserUtils.getSelectCompany().getId());
+            workReport.setCreateDate(d);
+            List<WorkReport> workReportList = workReportService.findByCompany(workReport);
+            calMap.put("date",dd);
+            calMap.put("reportNum",workReportList.size());
+            reportList.add(calMap);
+        }
+        return  reportList;
+    }
+
+
+    public Map<String,Object> getManageCalendarByDate(String dateStr) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date date =null;
+        try {
+            date =sdf.parse(dateStr);
+        }catch (ParseException e){
+
+        }
+        WorkReport workReport =new WorkReport();
+        WorkOutSignIn workOutSignIn =new WorkOutSignIn();
+        OaAttendance oaAttendance = new OaAttendance();
+        Leave leave = new Leave();
+        WorkSealForm workSealForm = new WorkSealForm();
+        WorkOvertimeForm workOvertimeForm = new WorkOvertimeForm();
+        OaEvection oaEvection = new OaEvection();
+        GoOut goOut = new GoOut();
+        if(! UserUtils.getUser().isAdmin()){
+            workReport.setCompanyId(UserUtils.getSelectCompany().getId());
+            workOutSignIn.setCompanyId(UserUtils.getSelectCompany().getId());
+            leave.setCompanyId(UserUtils.getSelectCompany().getId());
+            workSealForm.setCompanyId(UserUtils.getSelectCompany().getId());
+            oaEvection.setCompanyId(UserUtils.getSelectCompany().getId());
+            workOvertimeForm.setCompanyId(UserUtils.getSelectCompany().getId());
+            goOut.setCompanyId(UserUtils.getSelectCompany().getId());
+            oaAttendance.setCompany(UserUtils.getSelectCompany());
+        }
+        workReport.setCreateDate(date);
+        workReport.setDelFlag("0");
+        workOutSignIn.setCreateDate(date);
+        workOutSignIn.setDelFlag("0");
+        oaAttendance.setCreateDate(date);
+        oaAttendance.setDelFlag("0");
+        leave.setCreateDate(date);
+        leave.setDelFlag("0");
+        workSealForm.setCreateDate(date);
+        workSealForm.setDelFlag("0");
+        oaEvection.setCreateDate(date);
+        oaEvection.setDelFlag("0");
+        workOvertimeForm.setCreateDate(date);
+        workOvertimeForm.setDelFlag("0");
+        goOut.setCreateDate(date);
+        goOut.setDelFlag("0");
+        List<WorkReport> workReportList = workReportService.findByCompany(workReport);
+        List<WorkOutSignIn> workOutList = workOutSignInService.findByCompany(workOutSignIn);
+        List<OaAttendance> oaAttenList = oaAttendanceService.findByCompany(oaAttendance);
+        List<WorkSealForm> workSealList = workSealFormService.findList(workSealForm);
+        List<Leave> leaveList = LeaveDao.findByCompany(leave);
+        List<OaEvection> oaEvectionList = oaEvectionService.findList(oaEvection);
+        List<WorkOvertimeForm> workOvertimeFormList = workOvertimeFormService.findList(workOvertimeForm);
+        List<GoOut> goOutList = goOutService.findList(goOut);
+
+        Map<String,Object> map = new HashMap<String,Object>();
+        map.put("workReportList",workReportList);
+        map.put("workOutList",workOutList);
+        map.put("oaAttenList",oaAttenList);
+        map.put("workSealList",workSealList);
+        map.put("leaveList",leaveList);
+        map.put("oaEvectionList",oaEvectionList);
+        map.put("workOvertimeFormList",workOvertimeFormList);
+        map.put("goOutList",goOutList);
+        return  map;
+    }
+
+    public List getReportUserList(String dateStr){
+        Map<String,Object> maps = getManageCalendarByDate(dateStr);
+        List reportList =new ArrayList();
+
+        List<WorkReport> workReportList = (List<WorkReport>)maps.get("workReportList");
+        List<WorkOutSignIn> workOutList = (List<WorkOutSignIn>)maps.get("workOutList");
+        List<OaAttendance> oaAttenList = (List<OaAttendance>)maps.get("oaAttenList");
+        List<WorkSealForm> workSealList = (List<WorkSealForm>)maps.get("workSealList");
+        List<Leave> leaveList = (List<Leave>)maps.get("leaveList");
+        List<OaEvection> oaEvectionList = (List<OaEvection>)maps.get("oaEvectionList");
+        List<WorkOvertimeForm> workOvertimeFormList = (List<WorkOvertimeForm>)maps.get("workOvertimeFormList");
+        List<GoOut> goOutList = (List<GoOut>)maps.get("goOutList");
+
+        List<Map> mapList1 = new ArrayList<>();
+        List<Map> mapList2 = new ArrayList<>();
+        List<Map> mapList3 = new ArrayList<>();
+        List<Map> mapList4 = new ArrayList<>();
+        List<Map> mapList5 = new ArrayList<>();
+        List<Map> mapList6 = new ArrayList<>();
+        List<Map> mapList7 = new ArrayList<>();
+        List<Map> mapList8 = new ArrayList<>();
+        List<Map> mapList9 = new ArrayList<>();
+        List<Map> mapList10 = new ArrayList<>();
+        List<Map> mapList11 = new ArrayList<>();
+        Map<String,Object> totalMap1 = new HashMap<String,Object>();
+        Map<String,Object> totalMap2 = new HashMap<String,Object>();
+        Map<String,Object> totalMap3 = new HashMap<String,Object>();
+        Map<String,Object> totalMap4 = new HashMap<String,Object>();
+
+        Map<String,Object> map3 = new HashMap<String,Object>();
+        Map<String,Object> map4 = new HashMap<String,Object>();
+        if(workReportList!=null && workReportList.size()!=0) {
+            for (WorkReport w : workReportList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",w.getCreateDate());
+                    map.put("updateDate",w.getUpdateDate());
+                    map.put("workReportBean",w);
+                    mapList1.add(map);
+                }
+            }
+            map3.put("workReport",mapList1);
+        }
+        totalMap1.put("workReports",map3);
+        if(workOutList!=null && workOutList.size()!=0) {
+            for (WorkOutSignIn w : workOutList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",w.getCreateDate());
+                    map.put("updateDate",w.getUpdateDate());
+                    map.put("workOutSignInBean",w);
+                    mapList2.add(map);
+                }
+            }
+            map4.put("workOutSignIn", mapList2);
+        }
+        totalMap2.put("workOutSignIns",map4);
+
+        Map<String,Object> map1 = new HashMap<String,Object>();
+        if(oaAttenList!=null && oaAttenList.size()!=0) {
+            SimpleDateFormat sdf3 = new SimpleDateFormat("HHmmss");
+            for (OaAttendance o : oaAttenList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(o.getCreateBy().getId());
+                if (u!=null){
+                    if (o.getStartTime() != null && !"".equals(o.getStartTime())) {
+                        String ruleStart = o.getRule().getStartTime().replaceAll(":","")+"00";
+                        Integer start = Integer.parseInt(sdf3.format(o.getStartTime()));
+                        int morning = Integer.parseInt(ruleStart);
+                        if (start > morning) {
+                            map.put("userId", u.getId());
+                            map.put("photo", u.getPhoto());
+                            map.put("userName", u.getName());
+                            map.put("createDate",o.getCreateDate());
+                            map.put("updateDate",o.getUpdateDate());
+                            map.put("oaAttendanceBean",o);
+                            mapList3.add(map);
+                        } else {
+                                map.put("userId", u.getId());
+                                map.put("photo", u.getPhoto());
+                                map.put("userName", u.getName());
+                                map.put("createDate",o.getCreateDate());
+                                map.put("updateDate",o.getUpdateDate());
+                                map.put("oaAttendanceBean",o);
+                                mapList4.add(map);
+                        }
+                    }
+                    if (o.getEndTime() != null && !"".equals(o.getEndTime())) {
+                        String ruleEnd = o.getRule().getEndTime().replaceAll(":","")+"00";
+                        Integer end = Integer.parseInt(sdf3.format(o.getEndTime()));
+                        int night = Integer.parseInt(ruleEnd);
+                        if (end >= night) {
+                            map.put("userId", u.getId());
+                            map.put("photo", u.getPhoto());
+                            map.put("userName", u.getName());
+                            map.put("createDate",o.getCreateDate());
+                            map.put("updateDate",o.getUpdateDate());
+                            map.put("oaAttendanceBean",o);
+                            mapList5.add(map);
+                        } else {
+                                map.put("userId", u.getId());
+                                map.put("photo", u.getPhoto());
+                                map.put("userName", u.getName());
+                                map.put("createDate",o.getCreateDate());
+                                map.put("updateDate",o.getUpdateDate());
+                                map.put("oaAttendanceBean",o);
+                                mapList6.add(map);
+                        }
+                    }
+                }
+            }
+            if(mapList3!=null && mapList3.size()!=0){ map1.put("late",mapList3); }
+
+            if(mapList4!=null && mapList4.size()!=0){ map1.put("onDuty",mapList4);}
+            if(mapList5!=null && mapList5.size()!=0){  map1.put("offDut",mapList5);}
+            if(mapList6!=null && mapList6.size()!=0){ map1.put("leaveEarly",mapList6);}
+
+        }
+        totalMap3.put("attendances",map1);
+
+
+        Map<String,Object> map2 = new HashMap<String,Object>();
+        if(workSealList!=null && workSealList.size()!=0) {
+            for (WorkSealForm w : workSealList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",w.getCreateDate());
+                    map.put("updateDate",w.getUpdateDate());
+                    map.put("workSealFormBean",w);
+                    mapList7.add(map);
+                }
+            }
+            map2.put("workSealFrom",mapList7);
+        }
+        if(leaveList!=null && leaveList.size()!=0) {
+            for (Leave w : leaveList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",w.getCreateDate());
+                    map.put("updateDate",w.getUpdateDate());
+                    map.put("leaveBean",w);
+                    mapList8.add(map);
+                }
+            }
+            map2.put("leave",mapList8);
+        }
+        if(oaEvectionList!=null && oaEvectionList.size()!=0) {
+            for (OaEvection w : oaEvectionList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",w.getCreateDate());
+                    map.put("updateDate",w.getUpdateDate());
+                    map.put("oaEvectionBean",w);
+                    mapList9.add(map);
+                }
+            }
+            map2.put("oaEvection",mapList9);
+        }
+        if(workOvertimeFormList!=null && workOvertimeFormList.size()!=0) {
+            for (WorkOvertimeForm w : workOvertimeFormList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",w.getCreateDate());
+                    map.put("updateDate",w.getUpdateDate());
+                    map.put("workOvertimeFormBean",w);
+                    mapList10.add(map);
+                }
+            }
+            map2.put("workOvertimeForm",mapList10);
+        }
+        if(goOutList!=null && goOutList.size()!=0) {
+            for (GoOut goOut : goOutList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(goOut.getCreateBy().getId());
+                if (u!=null) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    map.put("createDate",goOut.getCreateDate());
+                    map.put("updateDate",goOut.getUpdateDate());
+                    map.put("goOutBean",goOut);
+                    mapList11.add(map);
+                }
+            }
+            map2.put("workGoOut",mapList11);
+        }
+        totalMap4.put("audits",map2);
+        reportList.add(totalMap1);
+        reportList.add(totalMap2);
+        reportList.add(totalMap3);
+        reportList.add(totalMap4);
+        return reportList;
+    }
+
+    public List getReportUserAppList(String dateStr){
+        Map<String,Object> maps = getManageCalendarByDate(dateStr);
+        List reportList =new ArrayList();
+
+        List<WorkReport> workReportList = (List<WorkReport>)maps.get("workReportList");
+        List<WorkOutSignIn> workOutList = (List<WorkOutSignIn>)maps.get("workOutList");
+        List<OaAttendance> oaAttenList = (List<OaAttendance>)maps.get("oaAttenList");
+        List<WorkSealForm> workSealList = (List<WorkSealForm>)maps.get("workSealList");
+        List<Leave> leaveList = (List<Leave>)maps.get("leaveList");
+        List<OaEvection> oaEvectionList = (List<OaEvection>)maps.get("oaEvectionList");
+        List<WorkOvertimeForm> workOvertimeFormList = (List<WorkOvertimeForm>)maps.get("workOvertimeFormList");
+        List<GoOut> goOutList = (List<GoOut>)maps.get("goOutList");
+
+        List<Map> mapList1 = new ArrayList<>();
+        List<Map> mapList2 = new ArrayList<>();
+        List<Map> mapList3 = new ArrayList<>();
+        List<Map> mapList4 = new ArrayList<>();
+        List<Map> mapList5 = new ArrayList<>();
+        List<Map> mapList6 = new ArrayList<>();
+        List<Map> mapList7 = new ArrayList<>();
+        List<Map> mapList8 = new ArrayList<>();
+        List<Map> mapList9 = new ArrayList<>();
+        List<Map> mapList10 = new ArrayList<>();
+        List<Map> mapList11 = new ArrayList<>();
+        Map<String,Object> totalMap1 = new HashMap<String,Object>();
+        Map<String,Object> totalMap2 = new HashMap<String,Object>();
+        Map<String,Object> totalMap3 = new HashMap<String,Object>();
+        Map<String,Object> totalMap4 = new HashMap<String,Object>();
+
+        Map<String,Object> map3 = new HashMap<String,Object>();
+        Map<String,Object> map4 = new HashMap<String,Object>();
+        if(workReportList!=null && workReportList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (WorkReport w : workReportList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList1.add(map);
+                }
+            }
+            map3.put("workReport",mapList1);
+        }
+        totalMap1.put("workReports",map3);
+        if(workOutList!=null && workOutList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (WorkOutSignIn w : workOutList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList2.add(map);
+                }
+            }
+            map4.put("workOutSignIn", mapList2);
+        }
+        totalMap2.put("workOutSignIns",map4);
+        Map<String,Object> map1 = new HashMap<String,Object>();
+        if(oaAttenList!=null && oaAttenList.size()!=0) {
+            SimpleDateFormat sdf3 = new SimpleDateFormat("HHmmss");
+            for (OaAttendance o : oaAttenList) {
+                Map map = new HashMap();
+                Set<User> setmorning = new HashSet<User>();
+                Set<User> setlate = new HashSet<User>();
+                Set<User> setnight = new HashSet<User>();
+                Set<User> setleaveEarly = new HashSet<User>();
+                User u = UserUtils.get(o.getCreateBy().getId());
+                if (u!=null){
+                    if (o.getStartTime() != null && !o.getStartTime().equals("")) {
+                        String arr[] = o.getRule().getStartTime().split(":");
+                        String mornings =arr[0]+(arr[1].length()==1?"0"+arr[1]:arr[1])+"00";
+                        int morning = Integer.parseInt(mornings);
+                        Date startTime = o.getStartTime();
+                        Integer start = Integer.parseInt(sdf3.format(startTime));
+                        if (start > morning && setlate.add(u)) {
+                            map.put("userId", u.getId());
+                            map.put("photo", u.getPhoto());
+                            map.put("userName", u.getName());
+                            mapList3.add(map);
+                        } else {
+                            if(setmorning.add(u)) {
+                                map.put("userId", u.getId());
+                                map.put("photo", u.getPhoto());
+                                map.put("userName", u.getName());
+                                mapList4.add(map);
+                            }
+                        }
+                    }
+                    if (o.getEndTime() != null && !o.getEndTime().equals("")) {
+                        String arr[] = o.getRule().getEndTime().split(":");
+                        String nights =arr[0]+(arr[1].length()==1?"0"+arr[1]:arr[1])+"00";
+                        int night = Integer.parseInt(nights);
+                        Date endTime = o.getEndTime();
+                        Integer end = Integer.parseInt(sdf3.format(endTime));
+                        if (end > night && setnight.add(u)) {
+                            map.put("userId", u.getId());
+                            map.put("photo", u.getPhoto());
+                            map.put("userName", u.getName());
+                            mapList5.add(map);
+                        } else {
+                            if (setleaveEarly.add(u)) {
+                                map.put("userId", u.getId());
+                                map.put("photo", u.getPhoto());
+                                map.put("userName", u.getName());
+                                mapList6.add(map);
+                            }
+                        }
+                    }
+                }
+            }
+            if(mapList3!=null && mapList3.size()!=0){ map1.put("late",mapList3); }
+
+            if(mapList4!=null && mapList4.size()!=0){ map1.put("onDuty",mapList4);}
+            if(mapList5!=null && mapList5.size()!=0){  map1.put("offDut",mapList5);}
+            if(mapList6!=null && mapList6.size()!=0){ map1.put("leaveEarly",mapList6);}
+
+        }
+        totalMap3.put("attendances",map1);
+        Map<String,Object> map2 = new HashMap<String,Object>();
+        if(workSealList!=null && workSealList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (WorkSealForm w : workSealList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList7.add(map);
+                }
+            }
+            map2.put("workSealFrom",mapList7);
+        }
+        if(leaveList!=null && leaveList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (Leave w : leaveList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList8.add(map);
+                }
+            }
+            map2.put("leave",mapList8);
+        }
+        if(oaEvectionList!=null && oaEvectionList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (OaEvection w : oaEvectionList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList9.add(map);
+                }
+            }
+            map2.put("oaEvection",mapList9);
+        }
+        if(workOvertimeFormList!=null && workOvertimeFormList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (WorkOvertimeForm w : workOvertimeFormList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(w.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList10.add(map);
+                }
+            }
+            map2.put("workOvertimeForm",mapList10);
+        }
+        if(goOutList!=null && goOutList.size()!=0) {
+            Set<User> set = new HashSet<User>();
+            for (GoOut goOut : goOutList) {
+                Map map = new HashMap();
+                User u = UserUtils.get(goOut.getCreateBy().getId());
+                if (u!=null && set.add(u)) {
+                    map.put("userId", u.getId());
+                    map.put("photo", u.getPhoto());
+                    map.put("userName", u.getName());
+                    mapList11.add(map);
+                }
+            }
+            map2.put("workGoOut",mapList11);
+        }
+        totalMap4.put("audits",map2);
+        reportList.add(totalMap1);
+        reportList.add(totalMap2);
+        reportList.add(totalMap3);
+        reportList.add(totalMap4);
+        return reportList;
+    }
+}

+ 27 - 0
src/main/java/com/jeeplus/modules/oa/service/OaAttendancePlaceService.java

@@ -0,0 +1,27 @@
+package com.jeeplus.modules.oa.service;
+
+import com.jeeplus.modules.oa.dao.OaAttendancePlaceDao;
+import com.jeeplus.modules.oa.entity.OaAttendancePlace;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * Created by admin on 2017/9/1.
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaAttendancePlaceService {
+    @Autowired
+    private OaAttendancePlaceDao oaAttendancePlaceDao;
+
+    public OaAttendancePlace get(String id){
+        return oaAttendancePlaceDao.get(id);
+    }
+
+    public String getPlaceNameById(String placeId){
+        return oaAttendancePlaceDao.getPlaceNameById(placeId);
+    };
+}

+ 161 - 0
src/main/java/com/jeeplus/modules/oa/service/OaAttendanceRuleService.java

@@ -0,0 +1,161 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import com.google.common.collect.Maps;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.oa.entity.OaAttendancePlace;
+import com.jeeplus.modules.oa.entity.OaAttendanceRule;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.oa.dao.OaAttendancePlaceDao;
+import com.jeeplus.modules.oa.dao.OaAttendanceRuleDao;
+
+/**
+ * 考勤规则Service
+ * @author 孟祥越
+ * @version 2017-05-10
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaAttendanceRuleService extends CrudService<OaAttendanceRuleDao, OaAttendanceRule> {
+
+	@Autowired
+	private OaAttendancePlaceDao oaAttendancePlaceDao;
+
+    @Autowired
+    private OaAttendanceRuleDao oaAttendanceRuleDao;
+
+    public OaAttendanceRule get(String id) {
+		OaAttendanceRule oaAttendanceRule = super.get(id);
+		if(oaAttendanceRule !=null){
+			oaAttendanceRule.setOaAttendancePlaceList(oaAttendancePlaceDao.findList(new OaAttendancePlace(oaAttendanceRule)));
+		}
+		return oaAttendanceRule;
+	}
+	
+	public List<OaAttendancePlace> getOaAttendancePlaceByRule(String ruleId) {
+		OaAttendanceRule oaAttendanceRule = super.get(ruleId);
+		List<OaAttendancePlace> oaAttendancePlaceList= oaAttendancePlaceDao.findList(new OaAttendancePlace(oaAttendanceRule));
+		return oaAttendancePlaceList;
+	}
+	
+	public OaAttendancePlace getOaAttendancePlace(String placeId) {
+		OaAttendancePlace oaAttendancePlace = oaAttendancePlaceDao.get(placeId);
+		return oaAttendancePlace;
+	}
+	
+	public List<OaAttendanceRule> findList(OaAttendanceRule oaAttendanceRule) {
+		return super.findList(oaAttendanceRule);
+	}
+	
+	public Page<OaAttendanceRule> findPage(Page<OaAttendanceRule> page, OaAttendanceRule oaAttendanceRule) {
+		return super.findPage(page, oaAttendanceRule);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(OaAttendanceRule oaAttendanceRule) {
+		super.save(oaAttendanceRule);
+		for (OaAttendancePlace oaAttendancePlace : oaAttendanceRule.getOaAttendancePlaceList()){
+			if (oaAttendancePlace.getId() == null){
+				continue;
+			}
+			if (OaAttendancePlace.DEL_FLAG_NORMAL.equals(oaAttendancePlace.getDelFlag())){
+				if (StringUtils.isBlank(oaAttendancePlace.getId())){
+					oaAttendancePlace.setOaAttendanceRule(oaAttendanceRule);
+					oaAttendancePlace.preInsert();
+					oaAttendancePlaceDao.insert(oaAttendancePlace);
+				}else{
+					oaAttendancePlace.preUpdate();
+					oaAttendancePlaceDao.update(oaAttendancePlace);
+				}
+			}else{
+				oaAttendancePlaceDao.delete(oaAttendancePlace);
+			}
+		}
+	}
+	
+	@Transactional(readOnly = false)
+	public void saveOaAttendancePlace(OaAttendancePlace oaAttendancePlace) {
+		if (OaAttendancePlace.DEL_FLAG_NORMAL.equals(oaAttendancePlace.getDelFlag())){
+			if (StringUtils.isBlank(oaAttendancePlace.getId())){
+				oaAttendancePlace.preInsert();
+				oaAttendancePlaceDao.insert(oaAttendancePlace);
+			}else{
+				oaAttendancePlace.preUpdate();
+				oaAttendancePlaceDao.update(oaAttendancePlace);
+			}
+		}else{
+			oaAttendancePlaceDao.delete(oaAttendancePlace);
+		}
+		List<OaAttendancePlace> oaAttendancePlaceList = new ArrayList<OaAttendancePlace>();
+		if(oaAttendancePlace.getOaAttendanceRule() !=null){
+			oaAttendancePlaceList = this.findAttendancePlaceByCompany(oaAttendancePlace.getCompany().getId());
+			oaAttendancePlace.getOaAttendanceRule().setOaAttendancePlaceList(oaAttendancePlaceList);
+		}
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(OaAttendanceRule oaAttendanceRule) {
+        oaAttendanceRuleDao.deleteByLogic(oaAttendanceRule);
+		oaAttendancePlaceDao.deleteByLogic(new OaAttendancePlace(oaAttendanceRule));
+		List<OaAttendancePlace> oaAttendancePlaceList= findAttendancePlaceByCompany(oaAttendanceRule.getCompany().getId());
+		for (OaAttendancePlace oaAttendancePlace : oaAttendancePlaceList) {
+			oaAttendancePlaceDao.deleteByLogic(oaAttendancePlace);
+		}		
+	}
+	
+	@Transactional(readOnly = false)
+	public void deletePlace(String oaAttendancePlaceId) {
+		oaAttendancePlaceDao.delete(new OaAttendancePlace(oaAttendancePlaceId));
+	}
+	
+	public List<OaAttendanceRule> findListByCompany(String companyId) {
+		OaAttendanceRule or =new OaAttendanceRule();
+		or.setCompany(new Office(companyId));
+		return dao.findListByCompany(or);
+	}
+
+	public OaAttendanceRule findAttendanceRuleByCompany(String companyId) {
+		OaAttendanceRule or =new OaAttendanceRule();
+		OaAttendanceRule rule =new OaAttendanceRule();
+		or.setCompany(new Office(companyId));
+		if(dao.findList(or).size()>0){
+			rule = dao.findList(or).get(0);
+		}else{
+			return null;
+		}
+		if(rule !=null){
+			rule.setOaAttendancePlaceList(oaAttendancePlaceDao.findList(new OaAttendancePlace(rule)));
+		}
+		return rule;
+	}
+	public List<OaAttendancePlace> findAttendancePlaceByCompany(String companyId) {
+		OaAttendancePlace op =new OaAttendancePlace();
+		op.setCompany(new Office(companyId));
+		return oaAttendancePlaceDao.findList(op);
+
+	}
+
+	/**
+	 *	查询规则
+	 * @param ruleId
+	 * @param companyId
+	 */
+	public OaAttendanceRule queryRuleByCompanyIdAndRuleId(String ruleId,String companyId){
+		HashMap<Object, Object> map = Maps.newHashMap();
+		map.put("ruleId",ruleId);
+		map.put("companyId",companyId);
+		return oaAttendanceRuleDao.queryRuleByCompanyIdAndRuleId(map);
+	}
+}

+ 305 - 0
src/main/java/com/jeeplus/modules/oa/service/OaAttendanceService.java

@@ -0,0 +1,305 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.service;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.modules.oa.dao.OaAttendanceDao;
+import com.jeeplus.modules.oa.entity.OaAttendance;
+import com.jeeplus.modules.oa.entity.OaAttendanceRule;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.work.entity.report.WorkReport;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 考勤表Service
+ * @author 孟祥越
+ * @version 2017-05-11
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaAttendanceService extends CrudService<OaAttendanceDao, OaAttendance> {
+
+	@Autowired
+	private OaAttendanceDao oaAttendanceDao;
+	@Autowired
+	private OaAttendanceRuleService oaAttendanceRuleService;
+	
+	public OaAttendance get(String id) {
+		return super.get(id);
+	}
+	
+	public List<OaAttendance> findList(OaAttendance oaAttendance) {
+		List<OaAttendance> list = oaAttendanceDao.findList(oaAttendance);
+		return list;
+	}
+	
+	public Page<OaAttendance> findPage(Page<OaAttendance> page, OaAttendance oaAttendance) {
+		oaAttendance.setPage(page);
+		page.setList(this.findList(oaAttendance));
+		return page;
+	}
+	public Page<OaAttendance> findPageByUser(Page<OaAttendance>page , OaAttendance oaAttendance){
+		oaAttendance.setPage(page);
+		page.setList(oaAttendanceDao.findListByUser(oaAttendance));
+		return page ;
+	}
+	public Page<OaAttendance> findPageByCompany(Page<OaAttendance> page,OaAttendance oaAttendance){
+		oaAttendance.setPage(page);
+		page.setList(dao.findByCompany(oaAttendance));
+		return page;
+	}
+	public List<OaAttendance> findByCompany(OaAttendance oaAttendance) {
+		return dao.findByCompany(oaAttendance);
+	}
+	
+	@Transactional(readOnly = false)
+	public String save(OaAttendance oaAttendance,String type) {
+		try {
+			Office company = oaAttendance.getCompany();
+			if (company == null) {
+				return "打卡失败";
+			}
+			OaAttendance oaAtt = new OaAttendance();
+			oaAtt.setOffice(UserUtils.getSelectOffice());
+			OaAttendanceRule oaAttendanceRule = oaAttendanceRuleService.get(oaAttendance.getRule().getId());
+			if (type.equals("1")) {
+				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+				String endTime = oaAttendanceRule.getEndTime();
+				Calendar c1 = new GregorianCalendar();
+				Calendar c2 = Calendar.getInstance();
+				Date end = null;
+				try {
+					end = sdf.parse(endTime);
+				} catch (ParseException e) {
+					e.printStackTrace();
+				}
+				oaAtt = this.getOaAttendanceByDate(oaAttendance, 0);
+				if (oaAtt != null) {
+					return "上班已打卡";
+				}
+				c1.setTime(end);
+				c1.set(Calendar.YEAR, c2.get(Calendar.YEAR));
+				c1.set(Calendar.MONTH, c2.get(Calendar.MONTH));
+				c1.set(Calendar.DAY_OF_MONTH, c2.get(Calendar.DAY_OF_MONTH));
+				System.out.println(c2.getTime());
+				System.out.println(c1.getTime());
+				if (c2.getTime().compareTo(c1.getTime()) > 0) {
+					System.out.println("已超过上班打卡时间");
+					return "已超过上班打卡时间";
+				} else {
+					oaAttendance.setStartTime(new Date());
+					oaAttendance.setSignDate(new Date());
+					oaAtt = oaAttendance;
+				}
+			}
+			if (type.equals("2")) {
+				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+				String startTime = oaAttendanceRule.getStartTime();
+				Calendar c1 = new GregorianCalendar();//规定次日上班时间
+				Calendar c2 = Calendar.getInstance();//当前时间
+				Date start = null;
+				try {
+					start = sdf.parse(startTime);
+				} catch (ParseException e) {
+					e.printStackTrace();
+				}
+				c1.setTime(start);
+				c1.set(Calendar.YEAR, c2.get(Calendar.YEAR));
+				c1.set(Calendar.MONTH, c2.get(Calendar.MONTH));
+				c1.set(Calendar.DAY_OF_MONTH, c2.get(Calendar.DAY_OF_MONTH));
+				oaAtt = this.getOaAttendanceByDate(oaAttendance, 0);
+				if (oaAtt != null) {
+					if (oaAtt.getEndTime() != null && !oaAtt.getEndTime().equals("")) {
+						return "下班已打卡";
+					}
+					c1.add(Calendar.DATE, +1);
+				/*if(c2.compareTo(c1)>0){
+					System.out.println("已超过下班打卡时间");
+					return "已超过下班打卡时间";
+				}else{
+					oaAtt.setEndTime(new Date());
+				}*/
+					oaAtt.setEndTime(new Date());
+				} else {
+					oaAttendance.setEndTime(new Date());
+					oaAttendance.setSignDate(new Date());
+					oaAtt = oaAttendance;
+				/*oaAtt = this.getOaAttendanceByDate(oaAttendance, -1);
+				if(oaAtt!=null){
+                    if(c2.compareTo(c1)<0){
+                        if(oaAtt.getEndTime()!=null||oaAtt.getEndTime().equals("")){
+                            return "下班已打卡";
+                        }else{
+                            oaAtt.setEndTime(new Date());
+                        }
+                    }
+					*//*if(c2.compareTo(c1)>0){
+						System.out.println("已超过下班打卡时间");
+						return "已超过下班打卡时间";
+					}*//*
+					oaAtt.setEndTime(new Date());
+				}else{
+					c1.setTime(start);
+					c1.set(Calendar.YEAR, c2.get(Calendar.YEAR));
+					c1.set(Calendar.MONTH, c2.get(Calendar.MONTH));
+					c1.set(Calendar.DAY_OF_MONTH, c2.get(Calendar.DAY_OF_MONTH)+1);
+					*//*if(c2.compareTo(c1)>0){
+						System.out.println("已超过下班打卡时间");
+						return "已超过下班打卡时间";
+					}else{
+						oaAttendance.setEndTime(new Date());
+						oaAttendance.setSignDate(new Date());
+						oaAtt = oaAttendance;
+					}*//*
+					oaAttendance.setEndTime(new Date());
+					oaAttendance.setSignDate(new Date());
+					oaAtt = oaAttendance;
+				}*/
+				}
+
+			}
+			oaAtt.setOffice(UserUtils.getSelectOffice());
+
+
+			super.save(oaAtt);
+			return "ok";
+		}catch (Exception e){
+			return "";
+		}
+	}
+
+	public OaAttendance getOaAttendanceByDate(OaAttendance oaAttendance,int days) {
+		List<OaAttendance> oaAttList = new ArrayList<OaAttendance>();
+		Date date=new Date();//取时间
+		Calendar calendar = new GregorianCalendar();
+		calendar.setTime(date);
+		calendar.add(Calendar.DATE,days);//把日期往前减少一天,若想把日期向后推一天则将负数改为正数
+		date=calendar.getTime();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String str=sdf.format(date);
+        Date date1 = null;
+        try {
+            date1=sdf.parse(str);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        oaAttendance.setSignDate(date1);
+		oaAttList = this.findList(oaAttendance);		
+		if(oaAttList != null && oaAttList.size()>0){
+			return oaAttList.get(0);
+		}else{
+			return null;
+		}
+	}
+	
+	
+	@Transactional(readOnly = false)
+	public void delete(OaAttendance oaAttendance) {
+		super.delete(oaAttendance);
+	}
+	
+	public Page<OaAttendanceRule> findPageByrule(Page<OaAttendanceRule> page, OaAttendanceRule rule) {
+		rule.setPage(page);
+		page.setList(dao.findListByrule(rule));
+		return page;
+	}
+	
+	public Page<Office> findPageByCompany(Page<Office> page, Office company) {
+		company.setPage(page);
+		page.setList(dao.findListByCompany(company));
+		return page;
+	}
+
+    public List getCreateDateList(String companyId, String date) {
+		Map<String,String> map = new HashMap<String, String>();
+		map.put("companyId",companyId);
+		map.put("date",date);
+		return oaAttendanceDao.getCreateDateList(map);
+    }
+
+    public List<OaAttendance> findByCompany2(OaAttendance oaAttendance, String date) {
+		Map<String,Object> map = new HashMap<>();
+		map.put("attendance",oaAttendance);
+		map.put("date",date);
+		return oaAttendanceDao.findByCompany2(map);
+    }
+
+
+	public List<String> getCompanyList() {
+		return oaAttendanceDao.getCompanyList();
+	}
+
+	public List<OaAttendance> getOaAttendanceList(String companyId,Date signDate) {
+		return oaAttendanceDao.getOaAttendanceList(companyId,signDate);
+	}
+
+	public Date parseDate(){
+		Date date=new Date();//取时间
+		Calendar calendar = new GregorianCalendar();
+		calendar.setTime(date);
+		calendar.add(Calendar.DATE,-1);//把日期往前减少一天,若想把日期向后推一天则将负数改为正数
+		date=calendar.getTime();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		String str=sdf.format(date);
+		Date signDate = null;
+		try {
+			signDate = sdf.parse(str);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return signDate;
+	}
+
+	public OaAttendance getOaAttendanceByCompanyIdAndUserIdAndSignDate(String companyId, String userId) {
+		Date signDate = parseDate();
+		Map<String , Object> map = new HashMap<>();
+		map.put("companyId",companyId);
+		map.put("userId",userId);
+		map.put("signDate",signDate);
+		return oaAttendanceDao.getOaAttendanceByCompanyIdAndUserIdAndSignDate(map);
+	}
+
+	public List getCreateDateList1(String time) {
+		Map<String,String> map = new HashMap<String,String>();
+		map.put("userId",UserUtils.getUser().getId());
+		map.put("time",time);
+		return oaAttendanceDao.getCreateDateList1(map);
+	}
+	public List<OaAttendance> findByCompany1(String time){
+		Map<String,String> map = new HashMap<String,String>();
+		map.put("userId",UserUtils.getUser().getId());
+		map.put("time",time);
+		return oaAttendanceDao.findByCompany1(map);
+	}
+	public List getCreateDateListAll(String time) {
+		Map<String,String> map = new HashMap<String,String>();
+		OaAttendance w =new OaAttendance();
+		map.put("sqlStr",dataScopeFilter(w.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OA_ATTENDANCE.getValue()));
+		map.put("time",time);
+		return oaAttendanceDao.getCreateDateListAll(map);
+	}
+	public List<OaAttendance> findByCompanyAll(String time){
+		Map<String,String> map = new HashMap<String,String>();
+		OaAttendance w =new OaAttendance();
+		map.put("sqlStr",dataScopeFilter(w.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OA_ATTENDANCE.getValue()));
+		map.put("time",time);
+		return oaAttendanceDao.findByCompanyAll(map);
+	}
+
+	public List<OaAttendance> findByManage(Map<String,Object> map) {
+		return oaAttendanceDao.findByManage(map);
+	}
+	public List<OaAttendance> findByCompanySelf(Map<String,Object> map) {
+		return oaAttendanceDao.findByCompanySelf(map);
+	}
+}

+ 971 - 0
src/main/java/com/jeeplus/modules/oa/service/OaNotifyService.java

@@ -0,0 +1,971 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.service;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.BaseEntity;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.websocket.onchat.ChatServerPool;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.oa.dao.OaNotifyDao;
+import com.jeeplus.modules.oa.dao.OaNotifyDetailDao;
+import com.jeeplus.modules.oa.dao.OaNotifyRecordDao;
+import com.jeeplus.modules.oa.entity.OaNotify;
+import com.jeeplus.modules.oa.entity.OaNotifyRecord;
+import com.jeeplus.modules.projectrecord.enums.ProjectStatusEnum;
+import com.jeeplus.modules.pushinfo.entity.Pushinfo;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.serialnum.service.SerialNumTplService;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.SystemService;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.DictUtils;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workactivity.dao.WorkActivityProcessDao;
+import com.jeeplus.modules.workactivity.entity.Activity;
+import com.jeeplus.modules.workactivity.entity.WorkActivityProcess;
+import com.jeeplus.modules.workactivity.service.ActivityService;
+import com.jeeplus.modules.workactivity.service.WorkActivityProcessService;
+import com.jeeplus.modules.workactivitymenu.entity.WorkActivityMenu;
+import com.jeeplus.modules.workactivitymenu.service.WorkActivityMenuService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import com.jeeplus.modules.workprojectnotify.util.UtilNotify;
+import org.activiti.engine.ActivitiObjectNotFoundException;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 通知通告Service
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaNotifyService extends CrudService<OaNotifyDao, OaNotify> {
+    @Autowired
+    private OaNotifyRecordDao oaNotifyRecordDao;
+    @Autowired
+    private SystemService systemService;
+
+    @Autowired
+    UserDao userDao;
+    @Autowired
+    private PushinfoService pushinfoService;
+    @Autowired
+    private WorkattachmentService workattachmentService;
+    @Autowired
+    private SerialNumTplService serialNumTplService;
+    @Autowired
+    private OaNotifyDetailDao oaNotifyDetailDao;
+    @Autowired
+    private IdentityService identityService;
+    @Autowired
+    private ActTaskService actTaskService;
+    @Autowired
+    private WorkActivityMenuService workActivityMenuService;
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    private WorkActivityProcessService workActivityProcessService;
+    @Autowired
+    private ActivityService activityService;
+    @Autowired
+    protected HistoryService historyService;
+    @Autowired
+    private WorkActivityProcessDao workActivityProcessDao;
+    @Autowired
+    private WorkProjectNotifyService workProjectNotifyService;
+
+    public OaNotify get(String id) {
+        OaNotify oaNotify = dao.get(id);
+        List<Workattachment> attachmentList = workattachmentService.getListByAttachmentIdAndFlag(id, "79");
+        oaNotify.setWorkAttachments(attachmentList);
+        return oaNotify;
+    }
+
+    /**
+     * 获取通知发送记录
+     * @param oaNotify
+     * @return
+     */
+    public OaNotify getRecordList(OaNotify oaNotify) {
+        oaNotify.setOaNotifyRecordList(oaNotifyRecordDao.findList(new OaNotifyRecord(oaNotify)));
+        return oaNotify;
+    }
+    public OaNotify getUsers(OaNotify oaNotify) {
+        List<OaNotifyRecord> list = oaNotifyRecordDao.findUsers(new OaNotifyRecord(oaNotify));
+        List<User> users = new ArrayList<>();
+        if (list!=null &&list.size()!=0){
+            for(OaNotifyRecord oaNotifyRecord:list){
+                users.add(oaNotifyRecord.getUser());
+            }
+        }
+        oaNotify.setUserList(users);
+        return oaNotify;
+    }
+    public OaNotify getOffices(OaNotify oaNotify) {
+        List<OaNotifyRecord> list = oaNotifyRecordDao.findOffices(new OaNotifyRecord(oaNotify));
+        List<Office> offices = new ArrayList<>();
+        if (list!=null &&list.size()!=0){
+            for(OaNotifyRecord oaNotifyRecord:list){
+                Office office = new Office(oaNotifyRecord.getOfficeId());
+                office.setName(oaNotifyRecord.getOfficeName());
+                offices.add(office);
+            }
+        }
+        oaNotify.setOfficeList(offices);
+        return oaNotify;
+    }
+    public OaNotify getRecordOfficeList(OaNotify oaNotify) {
+        oaNotify.setOaNotifyRecordList(oaNotifyRecordDao.findOffices(new OaNotifyRecord(oaNotify)));
+        return oaNotify;
+    }
+
+    //获取通知发送的记录,包含已读和未读--PC端使用
+    public OaNotify getRecordList2(OaNotify oaNotify){
+        oaNotify.setOaNotifyRecordList(oaNotifyRecordDao.findList2(new OaNotifyRecord(oaNotify)));
+        return oaNotify;
+    }
+
+    //我的通告(个人)
+    public Page<OaNotify> findMyself(Page<OaNotify> page, OaNotify oaNotify) {
+        User user = UserUtils.getUser();
+        oaNotify.setCurrentUser(user);
+
+        if(!user.isAdmin()){
+            oaNotify.setCompany(user.getCompany());
+        }
+        oaNotify.setPage(page);
+        List<OaNotify> oaNotifyList = dao.findList(oaNotify);
+        for (OaNotify notify:oaNotifyList){
+            if (StringUtils.isBlank(notify.getRemarks())) {
+                Long endDate = notify.getEndDate().getTime();
+                Long startDate = notify.getStartDate().getTime();
+                Long now = new Date().getTime();
+                if (startDate < now && endDate > now) {
+                    notify.setCandel("yes");
+                }
+            }
+        }
+        //只查询当前公司下发送给自己的通告
+        page.setList(oaNotifyList);
+        return page;
+    }
+    //通告管理(管理员)
+    public Page<OaNotify> find(Page<OaNotify> page, OaNotify oaNotify) {
+        oaNotify.setPage(page);
+        if(!UserUtils.getUser().isAdmin()){
+            oaNotify.setCompany(UserUtils.getSelectCompany());
+
+            if(!UserUtils.isManager()){
+                List<OaNotify> list = new ArrayList<>();
+                page.setList(list);
+                return page;
+            }
+        }
+        //查询出当前公司下所有管理员创建的通告
+        List<OaNotify> oaNotifyList = dao.findList(oaNotify);
+        page.setList(oaNotifyList);
+
+        return page;
+    }
+    //通告管理
+    public Page<OaNotify> findByPc(Page<OaNotify> page, OaNotify oaNotify) {
+        oaNotify.setPage(page);
+        oaNotify.getSqlMap().put("dsf", dataScopeFilter(oaNotify.getCurrentUser(), "o", "u","s", MenuStatusEnum.OA_NOTIFY.getValue()));
+        //查询出当前公司下所有管理员创建的通告
+        List<OaNotify> oaNotifyList = dao.findListByPc(oaNotify);
+        for (OaNotify notify:oaNotifyList){
+            if (StringUtils.isBlank(notify.getRemarks())) {
+                Long startDate = notify.getStartDate().getTime();
+                Long endDate = notify.getEndDate().getTime();
+                Long now = new Date().getTime();
+                if ("5".equals(notify.getStatus()) && startDate<now && endDate>now){
+                    notify.setCandel("yes");
+                }
+            }
+            if (StringUtils.isNotBlank(notify.getContent())){
+                Pattern p = Pattern.compile("\t|\r|\n");
+                Matcher m = p.matcher(notify.getContent());
+                notify.setContent(m.replaceAll(""));
+            }
+        }
+        page.setList(oaNotifyList);
+
+        return page;
+    }
+
+    /**
+     * 获取通知数目
+     * @param oaNotify
+     * @return
+     */
+    public Long findCount(OaNotify oaNotify) {
+        return dao.findCount(oaNotify);
+    }
+
+    @Transactional(readOnly = false)
+    public void save(OaNotify oaNotify) {
+        if(oaNotify.getCompany()==null || StringUtils.isBlank(oaNotify.getCompany().getId())){
+            oaNotify.setCompany(UserUtils.getSelectCompany());
+        }
+        if (oaNotify.getOffice()==null || StringUtils.isBlank(oaNotify.getOffice().getId())){
+            oaNotify.setOffice(UserUtils.getSelectOffice());
+        }
+        String title = StringEscapeUtils.unescapeHtml4(oaNotify.getTitle());
+        String content = StringEscapeUtils.unescapeHtml4(oaNotify.getContent());
+        oaNotify.setTitle(title);
+        oaNotify.setContent(content);
+        String contents = "";
+        if (oaNotify!=null && oaNotify.getContents()!=null){
+            contents = StringEscapeUtils.unescapeHtml4(oaNotify.getContents());
+            oaNotify.setContents(contents);
+        }
+
+        if (StringUtils.isBlank(oaNotify.getNumber())){
+            oaNotify.setNumber(serialNumTplService.genSerialNum(UserUtils.getSelectCompany(), "17"));
+        }
+        super.save(oaNotify);
+        //保存附件
+        this.saveAttachments(oaNotify);
+        // 更新通知人
+        saveDetailList(oaNotify,0);
+        // 更新通知部门
+        saveDetailList(oaNotify,1);
+
+    }
+
+    @Transactional(readOnly = false)
+    public String saveNotify(OaNotify oaNotify) {
+        this.save(oaNotify);
+        return this.startAudit(oaNotify,oaNotify.getProcessInstanceId());
+    }
+
+    private String startAudit(OaNotify oaNotify, String processInstanceId) {
+        Map<String, Object> variables = new HashMap<String, Object>();
+        identityService.setAuthenticatedUserId(oaNotify.getCurrentUser().getId());
+        String contentStr = "公告编号:"+oaNotify.getNumber()+",公告类型:"+ DictUtils.getMainDictLabel(oaNotify.getType(),"oa_notify_type","")+",公告日期:"+ DateUtils.formatDate(oaNotify.getCreateDate());
+        String titleStr = "公告标题:"+ oaNotify.getTitle();
+
+        String businessKey = oaNotify.getId();
+        Office office = UserUtils.getSelectOffice();
+        WorkActivityMenu workActivityMenu = workActivityMenuService.findByParentAndOffice("gg3125f1f194582bdda9abcew750904", office);
+        // 启动流程
+        String processType = workActivityMenu.getProcessType();
+        StringBuffer buffer = new StringBuffer();
+        Activity activity = new Activity();
+        WorkProjectNotify workProjectNotify = UtilNotify
+                .saveNotify(oaNotify.getId(),
+                        null,
+                        oaNotify.getCompany().getId(),
+                        titleStr,
+                        contentStr,
+                        "89",
+                        "0",
+                        "待审批",
+                        ""
+                );
+
+        List<User> users = new ArrayList<>();
+        List<User> zjlList = UserUtils.getByRoleActivityEnname("zjl",3,oaNotify.getOffice().getId(),"11",oaNotify.getCreateBy());
+        if (StringUtils.isNotBlank(workActivityMenu.getId())) {
+            workProjectNotify.setNotifyRole("");
+            workActivityMenu = workActivityMenuService.get(workActivityMenu.getId());
+            List<Activity> activities = workActivityMenu.getActivities();
+            for (Activity a : activities) {
+                String encount = a.getEncount();
+                String enlist = a.getEnlist();
+                if (a.getRole()!=null && StringUtils.isNotBlank(a.getRole().getEnname())){
+                    List enusers = UserUtils.getByRoleActivityEnnames(a.getRole().getEnname(),office.getId(),"11",oaNotify.getCreateBy());
+                    if (enusers.size()==0){
+                        oaNotify.setStatus(String.valueOf(ProjectStatusEnum.TSTORE.getValue()));
+                        dao.updateStatusById(oaNotify);
+                        return "流程审批人不能为空,角色"+a.getRole().getName()+"下无用户,请联系管理员!";
+                    }
+                    variables.put(enlist, enusers);
+                    variables.put(encount, enusers.size());
+                }
+                if (a.getDelFlag().equals("0") && a.getCount() == 1) {
+                    activity = a;
+                }
+            }
+            buffer.append(activity.getRole().getEnname());
+            if (activity != null && StringUtils.isNotBlank(activity.getId())) {
+                //角色审批
+                if (StringUtils.isNotBlank(activity.getRole().getEnname())) {
+                    users = UserUtils.getByRoleActivityEnnames(activity.getRole().getEnname(),office.getId(),"11",oaNotify.getCreateBy());
+                }
+                //人员审批
+                if (StringUtils.isNotBlank(activity.getUser().getId())) {
+                    users.add(activity.getUser());
+                }
+            }
+            workProjectNotify.setId("");
+        } else {
+            variables.put("zjlList", zjlList);
+            if (zjlList.size()==0 ){
+                oaNotify.setStatus(String.valueOf(ProjectStatusEnum.TSTORE.getValue()));
+                dao.updateStatusById(oaNotify);
+            }
+            if (zjlList.size()==0){
+                return "流程审批人不能为空,总经理岗位下无用户,请联系管理员!";
+            }
+            variables.put("zjlCount",zjlList.size());
+            processType = "oaNotify";
+            users.addAll(zjlList);
+        }
+        List<String> userIds = new ArrayList<>(users.size());
+        for (User u : users){
+            userIds.add(u.getId());
+            workProjectNotify.setUser(u);
+            workProjectNotify.setId("");
+            workProjectNotify.setNotifyRole("总经理审批");
+            workProjectNotifyService.save(workProjectNotify);
+            Map<String,Object> extras = new HashMap<>();
+            extras.put("type","7002");
+            extras.put("procDefKey","89");
+            extras.put("id",workProjectNotify.getId());
+            UserUtils.pushInfoToApp(titleStr, contentStr,extras,u.getId());
+        }
+        UserUtils.pushIm(userIds,contentStr);
+
+        variables.put("busId", businessKey);
+        variables.put("type", processType);
+        variables.put("title", "审批单:" + oaNotify.getNumber());//设置标题;
+
+        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processType, businessKey, variables);
+        //        workReceiptsSettle.setProcessInstance(processInstance);
+        if (org.apache.commons.lang3.StringUtils.isNotBlank(processInstanceId)) {
+            workActivityProcessService.updateProcessInstanceId(processInstance.getId(),processInstanceId);
+            workActivityProcessService.deleteProcessInstanceId(processInstanceId);
+            workActivityProcessService.deleteProcessIdAuditUsers(processInstanceId);
+        }
+        List<Activity> list = workActivityMenu.getActivities();
+        if (list != null && list.size() != 0) {
+            workActivityProcessService.saveList(list, processInstance.getId());
+        } else {
+            WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+            workActivityProcess.setProcessKey(processType);
+            workActivityProcess.setCount(1);
+            workActivityProcess.setIsApproval("0");
+            workActivityProcess.setProcessInstanceId(processInstance.getId());
+            workActivityProcessService.save(workActivityProcess);
+            workActivityProcessService.insertAuditsByType(zjlList,processInstance.getId(),1,1);
+        }
+        oaNotify.setProcessInstanceId(processInstance.getId());
+        oaNotify.setStatus(String.valueOf(ProjectStatusEnum.IN_APRL.getValue()));
+        dao.updateProcessIdAndStatus(oaNotify);
+        return "";
+    }
+
+    /**
+     *
+     * @param oaNotify
+     * @param isOffice 0:用户 1:部门
+     */
+    private void saveDetailList(OaNotify oaNotify,int isOffice) {
+        List userList = null;
+        if(isOffice==0){
+            userList = oaNotify.getUserList();
+        }else {
+            userList = oaNotify.getOfficeList();
+        }
+        if(userList ==null|| userList.size()<=0){
+            return;
+        }
+        oaNotifyDetailDao.deleteHandlers(oaNotify.getId(),isOffice);
+        Iterator iterator = userList.iterator();
+        while (iterator.hasNext()){
+            BaseEntity next = (BaseEntity) iterator.next();
+            if (next==null||StringUtils.isBlank(next.getId())){
+                iterator.remove();
+            }
+        }
+        if(userList ==null|| userList.size()<=0){
+            return;
+        }
+        HashMap<String, Object> map = new HashMap<>(5);
+        map.put("notifyId", oaNotify.getId());
+        map.put("handlerList", userList);
+        map.put("flag", isOffice);
+        oaNotifyDetailDao.batchInsert(map);
+    }
+
+    @Transactional(readOnly = false)
+    public void saveAttachments(OaNotify oaNotify) {
+        List<Workattachment> workattachments = oaNotify.getWorkAttachments();
+        if (workattachments!=null && workattachments.size()!=0) {
+            for (Workattachment workattachment : workattachments) {
+                if (workattachment.getId() == null) {
+                    continue;
+                }
+                if (workattachment.DEL_FLAG_NORMAL.equals(workattachment.getDelFlag())) {
+                    workattachment.setAttachmentId(oaNotify.getId());
+                    workattachment.setAttachmentFlag("79");
+                    workattachment.setAttachmentUser(UserUtils.getUser().getId());
+                    if (StringUtils.isBlank(workattachment.getId()) || "null".equals(workattachment.getId())) {
+                        workattachment.preInsert();
+                        workattachmentService.insert(workattachment);
+                    } else {
+                        workattachment.preUpdate();
+                        workattachmentService.save(workattachment);
+                    }
+                } else {
+                    workattachmentService.delete(workattachment);
+                }
+            }
+        }
+    }
+
+    public void pushNotify(OaNotify oaNotify,String state) {
+        this.queryDetails(oaNotify);
+        String ids = this.selectRecords(oaNotify);
+        Map extras = new HashMap();
+        extras.put("type", "2001");
+        extras.put("id", oaNotify.getId());
+        extras.put("state", state);
+        List aliases = new ArrayList();
+        if (ids!=null && ids.length()!=0){
+            String[] aliase = ids.split(",");
+            for (String a:aliase){
+                UserUtils.pushIm(a,"公告消息 "+oaNotify.getTitle());
+                aliases.add(a);
+            }
+        }
+        Pushinfo pushinfo = new Pushinfo();
+        pushinfo.setCompanyId(UserUtils.getSelectCompany().getId());
+        pushinfo.setMobile("ios,android");
+        pushinfo.setCurrentUser(UserUtils.getUser());
+        pushinfo.setRemarks(oaNotify.getContent());
+        pushinfo.setUserId(UserUtils.getUser().getId());
+        pushinfo.setType("2001");
+        pushinfo.setPushId(oaNotify.getId());
+        pushinfo.setTitle("公告");
+        String status = oaNotify.getUpdateBy().getName() +"  "+ DateUtils.formatDate(new Date());
+        pushinfo.setStatus(status);
+        pushinfo.setContent(oaNotify.getTitle());
+        pushinfo.setPushUserId(ids);
+        pushinfo.setParentType("singleCompanyNews");
+        pushinfo.setAddcontent(oaNotify.getContents());
+        if (oaNotify.getFiles()!=null &&oaNotify.getFiles().length()>0){
+            pushinfo.setStatus(oaNotify.getFiles());
+        }
+        pushinfoService.save(pushinfo);
+
+        boolean b = JPushClientUtil.sendNotificationToAliases(oaNotify.getTitle(), oaNotify.getContent(), extras, aliases);
+    }
+
+    private String selectRecords(OaNotify oaNotify) {
+        String recordIds = "";
+        Set<String> set = new HashSet<String>();
+        List<User> users = oaNotify.getUserList();
+        if (users !=null && users.size()!=0){
+            for (int i = 0; i < users.size(); i++) {
+                set.add(users.get(i).getId());
+            }
+        }
+        List<Office> offices = oaNotify.getOfficeList();
+        if (offices!=null && offices.size()!=0){
+            oaNotify.setOaNotifyRecordOffices(offices);
+            for (int i = 0; i < offices.size(); i++) {
+                List<User> userList = systemService.findUserByOfficeId(offices.get(i).getId());
+                for (User user:userList){
+                    set.add(user.getId());
+                }
+            }
+        }
+        if (set!=null && set.size()!=0) {
+            List aliases = new ArrayList();
+            for (String id : set) {
+                recordIds += id + ",";
+                aliases.add(id);
+            }
+            if (StringUtils.isNotBlank(recordIds)) {
+                recordIds = recordIds.substring(0, recordIds.length() - 1);
+            }
+        }
+        if (StringUtils.isNotBlank(recordIds)){
+            oaNotify.setOaNotifyRecordIds(recordIds);
+            if (oaNotify.getOaNotifyRecordList().size() > 0){
+                oaNotifyRecordDao.insertAll(oaNotify.getOaNotifyRecordList());
+            }
+        }
+        return recordIds;
+    }
+
+    @Transactional(readOnly = false)
+    public void saveNotifyFile(OaNotify oaNotify) {
+        super.save(oaNotify);
+        if (oaNotify.getId()!=null && oaNotify.getFiles()!=null){
+            Pushinfo pushinfo = new Pushinfo();
+            pushinfo.setPushId(oaNotify.getId());
+            pushinfo.setType("2001");
+            List<Pushinfo> list =pushinfoService.getByPushId(pushinfo);
+            if (list!=null && list.size()!=0){
+                for (Pushinfo pushinfo1:list){
+                    pushinfo1.setAddcontent(oaNotify.getFiles());
+                    pushinfoService.save(pushinfo1);
+                }
+            }
+        }
+    }
+
+    /**
+     * 更新阅读状态
+     */
+    @Transactional(readOnly = false)
+    public void updateReadFlag(OaNotify oaNotify) {
+        OaNotifyRecord oaNotifyRecord = new OaNotifyRecord(oaNotify);
+        oaNotifyRecord.setUser(oaNotifyRecord.getCurrentUser());
+
+        oaNotifyRecord.setReadDate(new Date());
+        oaNotifyRecord.setReadFlag("1");
+        oaNotifyRecordDao.update(oaNotifyRecord);
+    }
+    /**
+     * 更新阅读状态
+     */
+    @Transactional(readOnly = false)
+    public void deleteByOaNotifyId(String oaNotifyId) {
+        oaNotifyRecordDao.deleteByOaNotifyId(oaNotifyId);
+    }
+    /**
+     * 更新阅读状态
+     */
+    @Transactional(readOnly = false)
+    public void saveRemarks(OaNotify oaNotify) {
+        dao.saveRemarks(oaNotify);
+    }
+
+    @Transactional(readOnly = false)
+    public String uploadFile(OSSClientUtil ossClientUtil, MultipartFile file, OaNotify oaNotify, String flag) {
+        String fileName = file.getOriginalFilename();
+        String fileType = fileName.substring(fileName.lastIndexOf("."));
+        String url = ossClientUtil.uploadFile2OSS(file,"notify");
+        Workattachment workattachment = new Workattachment();
+        workattachment.setUrl(url);
+        workattachment.setType(fileType);
+        workattachment.setAttachmentName(fileName);
+        workattachment.setAttachmentUser(UserUtils.getUser().getId());
+        workattachment.setAttachmentId(oaNotify.getId());
+        workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+        workattachment.setAttachmentFlag(flag);
+        workattachmentService.save(workattachment);
+        return url;
+    }
+
+    @Transactional(readOnly = false)
+    public void delFile(String attaId, String attachmentUrl) {
+        try {
+            Workattachment workattachment = new Workattachment();
+            if(StringUtils.isNotBlank(attaId)){
+                workattachment.setId(attaId);
+                workattachmentService.delete(workattachment);
+            }
+            if(StringUtils.isNotBlank(attachmentUrl)){
+                workattachment.setUrl(attachmentUrl);
+                workattachmentService.deleteFileFromAliyun(workattachment,workattachment==null?attachmentUrl:workattachment.getUrl());
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public String auditSave(OaNotify oaNotify,List<User> auditUsers) {
+        try {
+            String str = "公告编号:"+oaNotify.getNumber()+",公告类型:"+ DictUtils.getMainDictLabel(oaNotify.getType(),"oa_notify_type","")+",公告日期:"+ DateUtils.formatDate(oaNotify.getCreateDate());
+            String title = "公告标题:"+ oaNotify.getTitle();
+            // 对不同环节的业务逻辑进行操作
+            String taskDefKey = oaNotify.getAct().getTaskDefKey();
+            if (!"modifyApply".equals(taskDefKey) && !taskDefKey.contains("audit")) {
+                actTaskService.claim(oaNotify.getAct().getTaskId(), UserUtils.getUser().getId());
+            }else {
+                oaNotify.getAct().setFlag("yes");
+                this.save(oaNotify);
+            }
+            String comment = "";
+            if (String.valueOf(ProjectStatusEnum.REJECTED.getValue()).equals(oaNotify.getStatus()) ){
+                comment = ("yes".equals(oaNotify.getAct().getFlag())?"[重新申请] ":"[已撤销] ");
+            }else {
+                comment = ("yes".equals(oaNotify.getAct().getFlag())?"[同意] ":"[驳回] ")+ oaNotify.getAct().getComment();
+            }
+            //yes 的时候状态为审核通过 否则为未通过
+            //1 审核中 2 未通过
+            oaNotify.setStatus(String.valueOf(("yes".equals(oaNotify.getAct().getFlag()) ? ProjectStatusEnum.IN_APRL.getValue() : ProjectStatusEnum.REJECTED.getValue())));
+            Map<String, Object> vars = Maps.newHashMap();
+            //业务逻辑对应的条件表达式
+            String exp = "";
+            String taskCount = "";
+            String notifyRole = "";
+            int key = 0;
+            String enname = "";
+            List<Activity> activitieList = activityService.getByProcessInstanceId(oaNotify.getProcessInstanceId());
+            WorkActivityMenu workActivityMenu = new WorkActivityMenu();
+            if (activitieList != null && activitieList.size() != 0) {
+                workActivityMenu.setProcessType(activitieList.get(0).getProcessKey());
+                workActivityMenu.setActivities(activitieList);
+            }
+
+            WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+            WorkActivityProcess selectProcess = new WorkActivityProcess();
+            selectProcess.setProcessInstanceId(oaNotify.getProcessInstanceId());
+            List<WorkActivityProcess> workActivityProcesses = workActivityProcessService.findList(selectProcess);
+            List<Activity> activities = workActivityMenu.getActivities();
+            if (StringUtils.isNotBlank(workActivityMenu.getProcessType()) && !workActivityMenu.getProcessType().equals("oaNotify")) {
+                key = 1;
+                for (int i = 0; i < workActivityProcesses.size(); i++) {
+                    WorkActivityProcess activityProcess = workActivityProcesses.get(i);
+                    if (taskDefKey.equals(activityProcess.getActivityTask()) && !taskDefKey.equals("modifyApply")) {
+                        taskCount = activityProcess.getCount()+"";
+                        workActivityProcess = activityProcess;
+                        if (!workActivityProcess.getIsApproval().equals("0")) {
+                            workActivityProcess.setId("");
+                        }
+                        exp = "pass";
+                        if (!"yes".equals(oaNotify.getAct().getFlag())) {
+                            notifyRole = "调整公告";
+                            oaNotify.setStatus(String.valueOf(ProjectStatusEnum.REJECTED.getValue()));
+                            workActivityProcess.setIsApproval("2");
+                            String returnBack = "-1";
+                            for (Activity activity : activities) {
+                                if (activity.getCount() == activityProcess.getCount()) {
+                                    notifyRole = activity.getName();
+                                    returnBack = activity.getReturnBack();
+                                    break;
+                                }
+                            }
+                            if (returnBack.equals("0")) {
+                                workActivityProcess.setId("");
+                            }
+
+                        } else {
+                            workActivityProcess.setIsApproval("1");
+                        }
+                    }else if(taskDefKey.equals("modifyApply")){
+                        taskCount = "0";
+                        exp = "pass";
+                        workActivityProcess.setId("");
+                        workActivityProcess.setCount(0);
+                        if (!"yes".equals(oaNotify.getAct().getFlag())) {
+                            oaNotify.setStatus(String.valueOf(ProjectStatusEnum.RECALL.getValue()));
+                            workActivityProcess.setIsApproval("2");
+                        } else {
+                            workActivityProcess.setIsApproval("1");
+                        }
+                        break;
+                    }
+                }
+            } else {
+                workActivityMenu.setProcessType("oaNotify");
+                for (int i = 0; i < workActivityProcesses.size(); i++) {
+                    WorkActivityProcess activityProcess = workActivityProcesses.get(i);
+                    String count = activityProcess.getCount() + "";
+                    workActivityProcess = activityProcess;
+                    if (!workActivityProcess.getIsApproval().equals("0")) {
+                        workActivityProcess.setId("");
+                    }
+                    // 审核环节
+                    if ("zjl".equals(taskDefKey) && count.contains("1")) {
+                        taskCount = "1";
+                        exp = "pass";
+                        if ("yes".equals(oaNotify.getAct().getFlag())) {
+                            notifyRole = "审批通过";
+                            workActivityProcess.setIsApproval("1");
+                        } else {
+                            notifyRole = "调整公告";
+                            workActivityProcess.setIsApproval("2");
+                        }
+                        break;
+                    } else if ("modifyApply".equals(taskDefKey)&& count.contains("0")) {
+                        notifyRole = "总经理审批";
+                        taskCount = "0";
+                        exp = "pass";
+                        workActivityProcess.setCount(0);
+                        enname = "zjl";
+                        if (!"yes".equals(oaNotify.getAct().getFlag())) {
+                            oaNotify.setStatus(String.valueOf(ProjectStatusEnum.RECALL.getValue()));
+                        }
+                        break;
+                    } else if ("apply_end".equals(taskDefKey)) {
+                    }
+
+                }
+            }
+            // 设置意见
+            oaNotify.getAct().setComment(("yes".equals(oaNotify.getAct().getFlag()) ? "[同意] " : "[驳回] ") + oaNotify.getAct().getComment());
+            oaNotify.preUpdate();
+            // 提交流程任务
+            vars.put(exp, "yes".equals(oaNotify.getAct().getFlag()) ? true : false);
+            vars.put("passs", true);
+            workActivityProcessService.updateProcess(workActivityProcess,workActivityMenu,key,taskCount, oaNotify.getProcessInstanceId(),taskDefKey,"modifyApply", oaNotify.getAct().getFlag(),comment, activities);
+            // 提交流程任务
+            actTaskService.complete(oaNotify.getAct().getTaskId(), oaNotify.getAct().getProcInsId(), oaNotify.getAct().getComment(), vars);
+            boolean state = actTaskService.isProcessEnd(oaNotify.getAct().getProcInsId());
+            List<User> users = new ArrayList<>();
+            List<User> userList = new ArrayList<>();
+            if (!state) {
+                users.add(oaNotify.getCreateBy());
+                if ("yes".equals(oaNotify.getAct().getFlag())) {
+                    oaNotify.setStatus(String.valueOf(ProjectStatusEnum.SIGNED.getValue()));
+                    WorkProjectNotify notify = new WorkProjectNotify();
+                    notify.setNotifyId(oaNotify.getId());
+                    userList = workProjectNotifyService.readByNotifyId(notify);
+                    workProjectNotifyService
+                            .save(UtilNotify
+                                    .saveNotify(oaNotify.getId(),
+                                            oaNotify.getCreateBy(),
+                                            oaNotify.getCompany().getId(),
+                                            title,
+                                            str,
+                                            "89",
+                                            "0",
+                                            "待通知",
+                                            notifyRole));
+
+                } else {
+                    WorkProjectNotify notify = new WorkProjectNotify();
+                    notify.setNotifyId(oaNotify.getId());
+                    userList = workProjectNotifyService.readByNotifyId(notify);
+                    if (!String.valueOf(ProjectStatusEnum.RECALL.getValue()).equals(oaNotify.getStatus())){
+                        oaNotify.setStatus(String.valueOf(ProjectStatusEnum.REJECTED.getValue()));
+                        workProjectNotifyService
+                                .save(UtilNotify
+                                        .saveNotify(oaNotify.getId(),
+                                                oaNotify.getCreateBy(),
+                                                oaNotify.getCompany().getId(),
+                                                title,
+                                                str,
+                                                "89",
+                                                "0",
+                                                "待通知",
+                                                notifyRole));
+                    }
+                }
+                workActivityProcessService.deleteProcessIdAuditUsers(oaNotify.getProcessInstanceId());
+            } else {
+                if (StringUtils.isNotBlank(workActivityMenu.getProcessType()) && !workActivityMenu.getProcessType().equals("oaNotify")) {
+                    WorkProjectNotify notify = new WorkProjectNotify();
+                    notify.setNotifyId(oaNotify.getId());
+                    userList = workProjectNotifyService.readByNotifyId(notify);
+                    //users.addAll(userList);
+                    WorkProjectNotify workProjectNotify = UtilNotify
+                            .saveNotify(oaNotify.getId(),
+                                    new User(),
+                                    oaNotify.getCompany().getId(),
+                                    title,
+                                    str,
+                                    "89",
+                                    "0",
+                                    "待审批",
+                                    notifyRole);
+                    List<WorkProjectNotify> workProjectNotifys = activityService.getByFlagAndTaskDefKeyList(
+                            activities,
+                            workProjectNotify,
+                            taskDefKey,
+                            oaNotify.getAct().getFlag(),
+                            taskCount,
+                            oaNotify.getCreateBy(),
+                            oaNotify.getOffice().getId(),
+                            "89");
+                    for (WorkProjectNotify workProjectNotify1:workProjectNotifys){
+                        users.add(workProjectNotify1.getUser());
+                        workProjectNotify1.setId("");
+                        workProjectNotify1.setIsNewRecord(false);
+                        workProjectNotifyService
+                                .save(workProjectNotify1);
+                    }
+
+                } else {
+                    if (!"yes".equals(oaNotify.getAct().getFlag())) {
+                        WorkProjectNotify notify = new WorkProjectNotify();
+                        notify.setNotifyId(oaNotify.getId());
+                        userList = workProjectNotifyService.readByNotifyId(notify);
+                        //users.addAll(userList);
+                        workProjectNotifyService
+                                .save(UtilNotify
+                                        .saveNotify(oaNotify.getId(),
+                                                oaNotify.getCreateBy(),
+                                                oaNotify.getCompany().getId(),
+                                                title,
+                                                str,
+                                                "89",
+                                                "0",
+                                                "重新申请",
+                                                notifyRole));
+                        users.add( oaNotify.getCreateBy());
+                    } else {
+                        if (StringUtils.isNotBlank(enname)) {
+                            WorkProjectNotify notify = new WorkProjectNotify();
+                            notify.setNotifyId(oaNotify.getId());
+                            userList = workProjectNotifyService.readByNotifyId(notify);
+                            //users.addAll(userList1);
+                            WorkProjectNotify workProjectNotify = UtilNotify
+                                    .saveNotify(oaNotify.getId(),
+                                            new User(),
+                                            oaNotify.getCompany().getId(),
+                                            title,
+                                            str,
+                                            "89",
+                                            "0",
+                                            "待审批",
+                                            notifyRole);
+                            users.addAll(auditUsers);
+                            for (User user1:auditUsers){
+                                workProjectNotify.setUser(user1);
+                                workProjectNotify.setId("");
+                                workProjectNotify.setIsNewRecord(false);
+                                workProjectNotifyService.save(workProjectNotify);
+                                Map<String,Object> extras = new HashMap<>();
+                                extras.put("type","7002");
+                                extras.put("procDefKey","89");
+                                extras.put("id",workProjectNotify.getId());
+                                UserUtils.pushInfoToApp(title, str,extras,user1.getId());
+                            }
+                        }else {
+                            WorkProjectNotify notify = new WorkProjectNotify();
+                            notify.setNotifyId(oaNotify.getId());
+                            userList = workProjectNotifyService.readByNotifyId(notify);
+                            users.add(oaNotify.getCreateBy());
+                            workProjectNotifyService
+                                    .save(UtilNotify
+                                            .saveNotify(oaNotify.getId(),
+                                                    oaNotify.getCreateBy(),
+                                                    oaNotify.getCompany().getId(),
+                                                    title,
+                                                    str,
+                                                    "89",
+                                                    "0",
+                                                    "重新申请",
+                                                    notifyRole));
+                        }
+                    }
+                }
+            }
+            if (StringUtils.isNotBlank(title) && users!=null && users.size()!=0) {
+                for (User u : users) {
+                    UserUtils.pushIm(u.getId(),title);
+                }
+            }
+            if (StringUtils.isNotBlank(title) && userList!=null && userList.size()!=0) {
+                for (User u : userList) {
+                    UserUtils.pushMeIm(u.getId());
+                }
+            }
+            dao.update(oaNotify);
+            if(String.valueOf(ProjectStatusEnum.SIGNED.getValue()).equals(oaNotify.getStatus())){
+                if (oaNotify!=null && oaNotify.getContents()!=null){
+                    oaNotify.setContents(StringEscapeUtils.unescapeHtml4(oaNotify.getContents()));
+                    this.pushNotify(oaNotify,"1");
+                }else {
+                    this.pushNotify(oaNotify,"2");
+                }
+            }
+            return "保存审核意见成功!";
+        }catch (ActivitiObjectNotFoundException e){
+            logger.error("ActivitiObjectNotFoundException e:",e);
+            return "流程已审批,不能重新审批!";
+        }catch (Exception e){
+            logger.error("Exception e:",e);
+            return "保存审核意见失败!!";
+        }
+    }
+
+    public void queryDetails(OaNotify oaNotify) {
+        if(oaNotify==null)return;
+        oaNotify.setOfficeList(this.queryOfficeList(oaNotify));
+        oaNotify.setUserList(this.queryUserList(oaNotify));
+    }
+
+    private List<Office> queryOfficeList(OaNotify oaNotify) {
+        return oaNotifyDetailDao.queryOfficeList(oaNotify);
+    }
+
+    private List<User> queryUserList(OaNotify oaNotify) {
+        return oaNotifyDetailDao.queryUserList(oaNotify);
+    }
+
+    @Transactional(readOnly = false)
+    public void cancelProcess(OaNotify oaNotify) throws Exception {
+        WorkActivityProcess process = new WorkActivityProcess();
+        process.setProcessInstanceId(oaNotify.getProcessInstanceId());
+        process.setIsApproval("0");
+        WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+        workActivityProcess.setProcessInstanceId(oaNotify.getProcessInstanceId());
+        List<WorkActivityProcess> processList = workActivityProcessService.findList(workActivityProcess);
+        WorkProjectNotify notify = new WorkProjectNotify();
+        notify.setNotifyId(oaNotify.getId());
+        List<User> userList = workProjectNotifyService.readByNotifyId(notify);
+        if (userList!=null && userList.size()!=0) {
+            for (User u : userList) {
+                User user = UserUtils.get(u.getId());
+                UserUtils.pushIm(u.getId(),"申请人:"+ user.getName()+",公告审批编号:"+oaNotify.getNumber() +" 强制撤销!");
+            }
+        }
+        if(processList!=null && processList.size()>0){
+            for (int i =0;i<processList.size();i++) {
+                WorkActivityProcess p = processList.get(i);
+                if(StringUtils.isNotBlank(p.getIsApproval()) && "0".equals(p.getIsApproval())){
+                    p.setIsApproval("-1");
+                    p.setDelFlag("1");
+                    workActivityProcessDao.updateDelFlagAndIsApproval(p);
+                }
+            }
+            WorkActivityProcess pro = new WorkActivityProcess();
+            pro.setId("");
+            pro.setDelFlag("0");
+            pro.preInsert();
+            pro.setRemarks("[强制撤销]");
+            pro.setProcessKey(processList.get(0).getProcessKey());
+            pro.setIsApproval("1");
+            pro.setProcessInstanceId(processList.get(0).getProcessInstanceId());
+            pro.setCount(0);
+            workActivityProcessDao.insert(pro);
+
+            //结束该流程,设为"撤销"状态月
+            OaNotify sendMessage = new OaNotify();
+            sendMessage.setId(oaNotify.getId());
+            sendMessage.setStatus(String.valueOf(ProjectStatusEnum.RECALL.getValue()));
+            sendMessage.setProcessInstanceId(oaNotify.getProcessInstanceId());
+            sendMessage.preUpdate();
+            dao.updateProcessIdAndStatus(sendMessage);
+            actTaskService.endProcessInstance(oaNotify.getProcessInstanceId(), "公告申请-撤回");
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public void logicDelete(OaNotify oaNotify) {
+        dao.deleteByLogic(oaNotify);
+        WorkProjectNotify notify = new WorkProjectNotify();
+        notify.setNotifyId(oaNotify.getId());
+        List<User> users = workProjectNotifyService.readByNotifyId(notify);
+        if (users!=null && users.size()!=0){
+            for (User user:users){
+                UserUtils.pushMeIm(user.getId());
+            }
+        }
+    }
+}

+ 128 - 0
src/main/java/com/jeeplus/modules/oa/service/TestAuditService.java

@@ -0,0 +1,128 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.service;
+
+import java.util.Map;
+
+import org.activiti.engine.IdentityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oa.dao.TestAuditDao;
+import com.jeeplus.modules.oa.entity.TestAudit;
+
+/**
+ * 审批Service
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@Service
+@Transactional(readOnly = true)
+public class TestAuditService extends CrudService<TestAuditDao, TestAudit> {
+
+	@Autowired
+	private ActTaskService actTaskService;
+	
+	@Autowired
+	private IdentityService identityService;
+	
+	public TestAudit getByProcInsId(String procInsId) {
+		return dao.getByProcInsId(procInsId);
+	}
+	
+	public Page<TestAudit> findPage(Page<TestAudit> page, TestAudit testAudit) {
+		testAudit.setPage(page);
+		page.setList(dao.findList(testAudit));
+		return page;
+	}
+	
+	/**
+	 * 审核新增或编辑
+	 * @param testAudit
+	 */
+	@Transactional(readOnly = false)
+	public void save(TestAudit testAudit) {
+		
+		// 申请发起
+		if (StringUtils.isBlank(testAudit.getId())){
+			testAudit.preInsert();
+			dao.insert(testAudit);
+			
+			
+			// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+			identityService.setAuthenticatedUserId(testAudit.getCurrentUser().getLoginName());
+			// 启动流程
+			actTaskService.startProcess(ActUtils.PD_TEST_AUDIT[0], ActUtils.PD_TEST_AUDIT[1], testAudit.getId(), testAudit.getContent());
+			
+		}
+		
+		// 重新编辑申请		
+		else{
+			testAudit.preUpdate();
+			dao.update(testAudit);
+
+			testAudit.getAct().setComment(("yes".equals(testAudit.getAct().getFlag())?"[重申] ":"[销毁] ")+testAudit.getAct().getComment());
+			
+			// 完成流程任务
+			Map<String, Object> vars = Maps.newHashMap();
+			vars.put("pass", "yes".equals(testAudit.getAct().getFlag())? "1" : "0");
+			actTaskService.complete(testAudit.getAct().getTaskId(), testAudit.getAct().getProcInsId(), testAudit.getAct().getComment(), testAudit.getContent(), vars);
+		}
+	}
+
+	/**
+	 * 审核审批保存
+	 * @param testAudit
+	 */
+	@Transactional(readOnly = false)
+	public void auditSave(TestAudit testAudit) {
+		
+		// 设置意见
+		testAudit.getAct().setComment(("yes".equals(testAudit.getAct().getFlag())?"[同意] ":"[驳回] ")+testAudit.getAct().getComment());
+		
+		testAudit.preUpdate();
+		
+		// 对不同环节的业务逻辑进行操作
+		String taskDefKey = testAudit.getAct().getTaskDefKey();
+
+		// 审核环节
+		if ("audit".equals(taskDefKey)){
+			
+		}
+		else if ("audit2".equals(taskDefKey)){
+			testAudit.setHrText(testAudit.getAct().getComment());
+			dao.updateHrText(testAudit);
+		}
+		else if ("audit3".equals(taskDefKey)){
+			testAudit.setLeadText(testAudit.getAct().getComment());
+			dao.updateLeadText(testAudit);
+		}
+		else if ("audit4".equals(taskDefKey)){
+			testAudit.setMainLeadText(testAudit.getAct().getComment());
+			dao.updateMainLeadText(testAudit);
+		}
+		else if ("apply_end".equals(taskDefKey)){
+			
+		}
+		
+		// 未知环节,直接返回
+		else{
+			return;
+		}
+		
+		// 提交流程任务
+		Map<String, Object> vars = Maps.newHashMap();
+		vars.put("pass", "yes".equals(testAudit.getAct().getFlag())? "1" : "0");
+		actTaskService.complete(testAudit.getAct().getTaskId(), testAudit.getAct().getProcInsId(), testAudit.getAct().getComment(), vars);
+		
+	}
+	
+}

+ 535 - 0
src/main/java/com/jeeplus/modules/oa/web/LeaveController.java

@@ -0,0 +1,535 @@
+/**
+ * There are <a href="http://www.jeeplus.org/">jeeplus</a> code generation
+ */
+package com.jeeplus.modules.oa.web;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.mapper.JsonMapper;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.websocket.onchat.ChatServerPool;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActAuditService;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oa.entity.Leave;
+import com.jeeplus.modules.oa.service.LeaveService;
+import com.jeeplus.modules.pushinfo.entity.Pushinfo;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.java_websocket.WebSocket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 请假Controller
+ * @author liuj
+ * @version 2013-04-05
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oa/leave")
+public class LeaveController extends BaseController {
+
+	private Logger logger = LoggerFactory.getLogger(getClass());
+
+	@Autowired
+	protected LeaveService leaveService;
+
+	@Autowired
+	protected RuntimeService runtimeService;
+
+	@Autowired
+	protected TaskService taskService;
+
+	@Autowired
+	private ActTaskService actTaskService;
+
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+
+	@Autowired
+	private PushinfoService pushinfoService;
+
+	@Autowired
+	private OfficeService officeService;
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private ActAuditService actAuditService;
+
+	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+	@ModelAttribute
+	public Leave get(@RequestParam(required=false) String id){//,
+//			@RequestParam(value="act.procInsId", required=false) String procInsId) {
+		Leave leave = null;
+		if (StringUtils.isNotBlank(id)){
+			leave = leaveService.get(id);
+//		}else if (StringUtils.isNotBlank(procInsId)){
+//			testAudit = testAuditService.getByProcInsId(procInsId);
+		}
+		if (leave == null){
+			leave = new Leave();
+		}
+		return leave;
+	}
+
+
+	@RequiresPermissions(value={"oa:leave:view","oa:leave:add","oa:leave:edit"},logical= Logical.OR)
+	@RequestMapping(value = {"form"})
+	public String form(Leave leave, Model model) {
+		String view = "leaveForm";
+		// 查看审批申请单
+		if (StringUtils.isNotBlank(leave.getId())){//.getAct().getProcInsId())){
+
+			// 环节编号
+			String taskDefKey = leave.getAct().getTaskDefKey();
+			if (taskDefKey!=null){
+				// 查看工单
+				if(leave.getAct().isFinishTask()){
+					view = "leaveView";
+				}
+				// 修改环节
+				else if ("apply_end".equals(taskDefKey)){
+					view = "leaveAudit";
+				}
+				// 审核环节
+				else if ("audit1".equals(taskDefKey)){
+					if (StringUtils.isBlank(leave.getAct().getStatus())){
+						model.addAttribute("disabled","true");
+						leave.getAct().setProcInsId(leave.getProcessInstanceId());
+					}else {
+						model.addAttribute("disabled","false");
+					}
+					view = "leaveAudit";
+				}
+				//
+				else if ("modifyApply".equals(taskDefKey)){
+					view = "leaveForm";
+				}
+			}
+			if (StringUtils.isNotBlank(leave.getName())){
+				if (leave.getName().equals("view")){
+					model.addAttribute("disabled","true");
+					leave.getAct().setProcInsId(leave.getProcessInstanceId());
+					view = "leaveAudit";
+				}
+			}
+		}
+
+		model.addAttribute("leave", leave);
+		return "modules/oa/"+view;
+	}
+
+	/**
+	 * 启动请假流程
+	 * @param leave
+	 */
+	@RequestMapping(value = "save", method = RequestMethod.POST)
+	public String save(Leave leave, @RequestParam(value = "this_upload_files",required = false)MultipartFile[] this_upload_files, RedirectAttributes redirectAttributes) throws Exception{
+		if (StringUtils.isNotBlank(leave.getId())) {
+			Leave t = leaveService.get(leave.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(leave, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			if (t.getStatus().equals("3") || t.getStatus().equals("4")){
+				addMessage(redirectAttributes, "已结束流程不能修改!");
+			}else {
+				leaveService.save(t);
+			}
+		} else {
+			try {
+				leave.setStatus("1");
+				String approverId = "";
+				List<String> adds = leave.getAdds();
+				for(int i = 0;i<adds.size();i++){
+					if(i + 1 == adds.size()){
+						approverId += adds.get(i);
+					}else{
+						approverId += adds.get(i) + ",";
+					}
+				}
+				leave.setIds(approverId);
+
+				String type = "1";
+				Map<String, Object> variables = Maps.newHashMap();
+				String alias = "1";
+				List<String> assigneeList = new ArrayList<String>(); //分配任务的人员
+				if (approverId != null && !approverId.equals("")) {
+					if (!UserUtils.getUser().isAdmin() && approverId.contains(UserUtils.getUser().getId())) {
+						logger.error("启动请假流程失败:");
+						addMessage(redirectAttributes, "请假申请失败,审批人不能为本人!");
+						return "redirect:" + adminPath + "/oa/leave";
+					}
+					String[] approverIds = approverId.split(",");
+					for (int i = 0; i < approverIds.length; i++) {
+						assigneeList.add(approverIds[i]);
+					}
+					type = approverIds.length + "";
+					alias = approverIds[0];
+				}
+				variables.put("assigneeList", assigneeList);
+				variables.put("count", assigneeList.size());
+				User CC = new User();
+				CC.setId(leave.getCCId());
+				User user = UserUtils.getUser();
+				leave.setUser(user);
+				leave.setCreateBy(user);
+				leave.setUpdateBy(user);
+				leave.setStatus("1");
+				leave.setDelFlag("0");
+				leave.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				leave.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+				leaveService.save(leave, variables, type);
+
+				if(this_upload_files!=null&&this_upload_files.length>0){
+					OSSClientUtil ossClientUtil = new OSSClientUtil();
+					for (int i = 0; i < this_upload_files.length; i++) {
+						MultipartFile file = this_upload_files[i];
+						if(file!=null && !file.isEmpty()&& file.getSize()>0){
+							leaveService.uploadFile(ossClientUtil,file,leave,"71");
+						}
+					}
+				}
+
+
+
+				ApprovalCopy approvalCopy = new ApprovalCopy();
+				approvalCopy.setCCId(leave.getCCId());
+				approvalCopy.setUserId(user.getId());
+				approvalCopy.setType("leave");
+				approvalCopy.setApprovalId(leave.getId());
+				approvalCopy.setRemarks(leave.getReason());
+				approvalCopy.setApproverId(approverId);
+				approvalCopy.setReadFlag("0");
+				approvalCopyService.save(approvalCopy);
+
+				//给抄送人、审批人发送通知
+				if(approvalCopy!=null && StringUtils.isNotBlank(approvalCopy.getId())){
+					String chaosongIds = approvalCopy.getCCId();//给所有抄送人发送通知
+					String shenpiIds = alias;//给审批流程的第一个人发送通知
+					UserUtils.pushIm(alias,"申请人 "+user.getName() + ",请假申请 待审批!");
+					/*List<WebSocket> toUserConns = ChatServerPool.getWebSocketByUser(alias);
+					for (WebSocket toUserConn:toUserConns) {
+						String message = "{\"to\":\""+alias+"\"," +
+								"\"msg\":\"审批信息 申请人:" + user.getName() + ",请假申请 待审批!\"," +
+								"\"useType\":\"sys\"}";
+						ChatServerPool.sendMessageToUser(toUserConn, message);//同时向本人发送消息
+					}*/
+					leaveService.sendNotify(chaosongIds,shenpiIds,approvalCopy.getApprovalId());
+				}
+
+
+				//推送
+				String title = "审批";
+				String content = UserUtils.getUser().getName() + "的请假申请需要你审批";
+				String status = "待审批";
+				String leaveType = leave.getLeaveType();
+				if (leaveType.equals("1")) {
+					//1:事假、2:病假、3:调休、4:年假、5:婚假、6:产假、7:其他
+					leaveType = "事假";
+				} else if (leaveType.equals("2")) {
+					leaveType = "病假";
+				} else if (leaveType.equals("3")) {
+					leaveType = "调休";
+				} else if (leaveType.equals("4")) {
+					leaveType = "年假";
+				} else if (leaveType.equals("5")) {
+					leaveType = "婚假";
+				} else if (leaveType.equals("6")) {
+					leaveType = "产假";
+				} else if (leaveType.equals("7")) {
+					leaveType = "其他";
+				}
+				String remarks = "请假类型:" + leaveType + "\n"
+						+ "开始时间:" + leave.getStartTime() + "\n"
+						+ "结束时间:" + leave.getEndTime();
+				Map extras = new HashMap();
+				extras.put("type", "4001");
+				extras.put("id", leave.getId());
+				extras.put("procDefKey", "leave");
+
+				boolean b = JPushClientUtil.sendNotificationToAlias(title, content, extras, alias);
+				Pushinfo pushinfo = new Pushinfo();
+				pushinfo.setCurrentUser(UserUtils.getUser());
+				pushinfo.setRemarks(remarks);
+				pushinfo.setUserId(UserUtils.getUser().getId());
+				pushinfo.setType("4001");
+				pushinfo.setPushId(leave.getId());
+				pushinfo.setTitle(title);
+				pushinfo.setContent(content);
+				pushinfo.setStatus(status);
+				pushinfo.setAddcontent("leave");
+				pushinfo.setPushUserId(alias);
+				pushinfo.setParentType("singleApproval");
+				pushinfo.setMobile("ios,android");
+				pushinfo.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				pushinfoService.save(pushinfo);
+				if (b) {
+					addMessage(redirectAttributes, "请假申请已经提交");
+				} else {
+					logger.error("请假申请已提交:推送失败!");
+					addMessage(redirectAttributes, "请假申请已提交,推送失败!");
+					return "redirect:" + adminPath + "/oa/leave";
+				}
+			} catch (Exception e) {
+				logger.error("启动请假流程失败:", e);
+				addMessage(redirectAttributes, "系统内部错误!");
+			}
+		}
+		return "redirect:" + adminPath + "/oa/leave";
+	}
+
+
+	/**
+	 * 工单执行(完成任务)
+	 * @param
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "saveAudit")
+	public String saveAudit(Leave leave,Map<String, Object> vars, Model model, RedirectAttributes redirectAttributes) {
+		/*if (StringUtils.isBlank(leave.getAct().getComment())){
+			addMessage(model, "请填写审核意见。");
+			return form(leave, model);
+		}*/
+		//leaveService.auditSave(leave);
+		Act act = leave.getAct();
+		AjaxJson json = actAuditService.saveAudit(act, act.getProcInsId(), "leave", leave.getAct().getComment(), leave.getId(), "2");
+		addMessage(redirectAttributes, json.getMsg());
+		if (leave!=null && StringUtils.isNotBlank(leave.getHome()) && leave.getHome().equals("home")){
+			return "redirect:" + adminPath + "/home";
+		}
+		return "redirect:" + adminPath + "/oa/leave";
+	}
+
+	/**
+	 * 任务列表
+	 * @param leave
+	 */
+	/*@RequestMapping(value = {"list/task",""})
+	public String taskList(HttpSession session, Model model) {
+		String userId = UserUtils.getUser().getLoginName();//ObjectUtils.toString(UserUtils.getUser().getId());
+		List<Leave> results = leaveService.findTodoTasks(userId);
+		model.addAttribute("leaves", results);
+		return "modules/oa/leaveTask";
+	}*/
+
+	/**
+	 * 读取所有流程
+	 * @return
+	 */
+	@RequiresPermissions("oa:leave:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(Leave leave, HttpServletRequest request, HttpServletResponse response, Model model) {
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()){
+			leave.setCompanyId(user.getComId());
+			if (!UserUtils.isManager()){
+				leave.setCreateBy(user);
+			}
+		}
+		Page<Leave> page = leaveService.find(new Page<Leave>(request, response), leave);
+		model.addAttribute("page", page);
+		return "modules/oa/leaveList";
+	}
+
+	/**
+	 * 待办任务列表页面
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"leaveTodoList"})
+	public String leaveTodoList(Act act, HttpServletRequest request, HttpServletResponse response, Model model) {
+		act.setProcDefKey("leave");
+		List<Act> list = actTaskService.todoList(act);
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<Leave> lists = new ArrayList<Leave>();
+		for (Act a : list) {
+			Leave leave = leaveService.getByProcessInstanceId(a.getProcInsId());
+			if (leave != null && leave.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					User user = UserUtils.get(a.getVars().getMap().get("applyUserId").toString());
+					if (user!=null) {
+						a.getVars().getMap().put("applyUserId", UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+					}
+				}
+				leave.setAct(a);
+				if (com.jeeplus.common.utils.StringUtils.isNotBlank(leave.getId())){
+					leave.setName(officeService.get(leave.getCompanyId()).getName());
+				}
+				lists.add(leave);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oa/leaveTodoList";
+	}
+
+	/**
+	 * 已办任务
+	 * @param act
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"leaveHistoricList"})
+	public String leaveHistoricList (Act act, HttpServletRequest request, HttpServletResponse response, Model model){
+		act.setProcDefKey("leave");
+		Page<Act> page = actTaskService.historicList(new Page<Act>(request, response), act);
+		List<Act> list = page.getList();
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<Leave> lists = new ArrayList<Leave>();
+		for (Act a : list) {
+			Leave leave = leaveService.getByProcessInstanceId(a.getHistTask().getProcessInstanceId());
+			if (leave != null && leave.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					a.getVars().getMap().put("applyUserId",UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+				}
+				leave.setAct(a);
+				if (com.jeeplus.common.utils.StringUtils.isNotBlank(a.getId())){
+					leave.setName(officeService.get(leave.getCompanyId()).getName());
+				}
+				if (leave.getCreateDate()!=null){
+					leave.setTime(sdf.format(leave.getCreateDate()));
+				}
+				lists.add(leave);
+			}
+		}
+		model.addAttribute("list", lists);
+		/*List<Act> list = page.getList();
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<Act> lists = new ArrayList<Act>();
+		for (Act a : list) {
+			Leave leave = leaveService.getByProcessInstanceId(a.getHistTask().getProcessInstanceId());
+			if (leave != null && leave.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					a.getVars().getMap().put("applyUserId",UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+				}
+				lists.add(a);
+			}
+		}
+		model.addAttribute("list", lists);*/
+
+		return "modules/oa/leaveHistoricList";
+	}
+
+	/**
+	 * 审核企业信息
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "applyOnLeave")
+	public String applyOnCompany(Act act, HttpServletResponse response, Model model) {
+		// 获取流程XML上的表单KEY
+		//String formKey = "/oa/leave/applyOnLeave";
+		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
+		//logger.info("------formKeys:"+formKeys);
+		// 获取流程实例对象
+		if (act.getProcInsId() != null){
+			if(actTaskService.getProcIns(act.getProcInsId())!=null){
+				act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+			}else{
+				act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+			}
+		}
+		return "redirect:" + ActUtils.getFormUrl(formKey, act);
+	}
+
+	/**
+	 * 读取详细数据
+	 * @param id
+	 * @return
+	 */
+	@RequestMapping(value = "detail/{id}")
+	@ResponseBody
+	public String getLeave(@PathVariable("id") String id) {
+		Leave leave = leaveService.get(id);
+		return JsonMapper.getInstance().toJson(leave);
+	}
+
+	/**
+	 * 读取详细数据
+	 * @param id
+	 * @return
+	 */
+	@RequestMapping(value = "detail-with-vars/{id}/{taskId}")
+	@ResponseBody
+	public String getLeaveWithVars(@PathVariable("id") String id, @PathVariable("taskId") String taskId) {
+		Leave leave = leaveService.get(id);
+		Map<String, Object> variables = taskService.getVariables(taskId);
+		leave.setVariables(variables);
+		return JsonMapper.getInstance().toJson(leave);
+	}
+
+	/**
+	 * 请假申请撤销
+	 * @param
+	 * @return
+	 */
+	@RequestMapping(value = "revoke")
+	public String revoke(HttpServletRequest request, HttpServletResponse response) {
+
+		HashMap<String, String> requestMap = findRequestMap(request);
+		String processInstanceId = requestMap.get("processInstanceId");
+		String id = requestMap.get("id");
+		String deleteReason = requestMap.get("reason");
+
+		AjaxJson j = new AjaxJson();
+		try {
+			Leave leave = leaveService.getById(id);
+			leave.setStatus("5");
+			leave.preUpdate();
+			leaveService.update(leave);
+			Map map = leaveService.getLeaveById(id,"1");
+			j.put("data",map);
+			actTaskService.endProcessInstance(processInstanceId, deleteReason);
+			j.setMsg("撤销申请成功");
+
+			//撤销后,更改所有发送过的通知的阅读状态
+			WorkProjectNotify notify = new WorkProjectNotify();
+			notify.setNotifyId(leave.getId());
+			workProjectNotifyService.readByNotifyId(notify);
+		}catch (Exception e){
+			j.setErrorCode("101");
+			logger.info(e.getMessage());
+			j.setMsg("撤销申请失败");
+			j.setSuccess(false);
+		}
+		return "redirect:" + adminPath + "/oa/leave";
+	}
+}

+ 379 - 0
src/main/java/com/jeeplus/modules/oa/web/OaAttendanceController.java

@@ -0,0 +1,379 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.web;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.oa.entity.OaAttendance;
+import com.jeeplus.modules.oa.entity.OaAttendanceRule;
+import com.jeeplus.modules.oa.service.OaAttendanceRuleService;
+import com.jeeplus.modules.oa.service.OaAttendanceService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * 考勤表Controller
+ * @author 孟祥越
+ * @version 2017-05-11
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oa/oaAttendance")
+public class OaAttendanceController extends BaseController {
+
+	@Autowired
+	private OaAttendanceService oaAttendanceService;
+
+	@Autowired
+	private OaAttendanceRuleService oaAttendanceRuleService;
+
+	@ModelAttribute
+	public OaAttendance get(@RequestParam(required=false) String id) {
+		OaAttendance entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = oaAttendanceService.get(id);
+		}
+		if (entity == null){
+			entity = new OaAttendance();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 考勤信息列表页面
+	 */
+	@RequiresPermissions("oa:oaAttendance:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OaAttendance oaAttendance, HttpServletRequest request, HttpServletResponse response, Model model) {
+		User user = UserUtils.getUser();
+		String username = request.getParameter("user.name");
+		String fromDate = request.getParameter("fromThisDay");
+		String toDate = request.getParameter("toThisDay");
+		if(! user.isAdmin()){
+			oaAttendance.setCompany(UserUtils.getSelectCompany());
+			if(! UserUtils.isManager()){
+				oaAttendance.setUser(user);
+			}
+		}else{
+
+		}
+		Page<OaAttendance> page = oaAttendanceService.findPage(new Page<OaAttendance>(request,response),oaAttendance);
+
+		String userId = user.getId();
+		AjaxJson j=new AjaxJson();
+		if(userId!=null &&!userId.equals("")) {
+			oaAttendance.setUser(new User(userId));
+		}else{
+			oaAttendance.setUser(UserUtils.getUser());
+		}
+		oaAttendance.setCompany(UserUtils.getSelectCompany());
+		SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm");
+		SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
+
+		for(OaAttendance attendance : page.getList()) {
+			List<OaAttendance> oaAttList = oaAttendanceService.findList(attendance);
+			if(oaAttList==null ){
+				j.setSuccess(false);
+				j.setErrorCode("1");
+				j.setMsg("获取考勤信息失败");
+				j.put("data",oaAttList);
+			}else if(oaAttList.size()>0){
+				OaAttendance o = oaAttList.get(0);
+				OaAttendanceRule r = oaAttendanceRuleService.get(o.getRule());
+				Date startRule = null;
+				Date endRule = null;
+				String start = null;
+				String end = null;
+				Date startDate=o.getStartTime();
+				Date endDate = o.getEndTime();
+				Date startTime=null;
+				Date endTime = null;
+				try {
+					startRule =sdf1.parse(r.getStartTime());
+					endRule =sdf1.parse(r.getEndTime());
+
+					if(o.getStartTime()!=null && !o.getStartTime().equals("")){
+						start=sdf2.format(o.getStartTime());
+						startTime=sdf2.parse(start);
+					}
+					if(o.getEndTime()!=null && !o.getEndTime().equals("")){
+						end=sdf2.format(o.getEndTime());
+						endTime=sdf2.parse(end);
+					}
+				} catch (ParseException e) {
+					j.setSuccess(false);
+					j.setErrorCode("1");
+					j.setMsg("获取考勤信息失败");
+					//e.printStackTrace();
+				}
+				Calendar c1 =  new GregorianCalendar();//次日规定上班时间
+				Calendar c2 =  new GregorianCalendar();//上班时间
+				Calendar c3 =  new GregorianCalendar();//下班时间
+				Calendar c4 =  new GregorianCalendar();//规定上班时间
+				Calendar c5 =  new GregorianCalendar();//规定上班时间
+
+				c1.setTime(startRule);
+				if(startDate !=null) {
+					c2.setTime(startDate);
+				}
+				if(endDate !=null) {
+					c3.setTime(endDate);
+				}
+				c4.setTime(startRule);
+				c5.setTime(endRule);
+				c1.set(Calendar.YEAR, c2.get(Calendar.YEAR));
+				c1.set(Calendar.MONTH, c2.get(Calendar.MONTH));
+				c1.set(Calendar.DAY_OF_MONTH, c2.get(Calendar.DAY_OF_MONTH));
+				c1.add(Calendar.DATE,+1);
+				//1 正常打卡 、 2迟到、  3早退 、 5待打卡
+
+				if(startTime!=null && endTime!=null){
+					if(startTime.getTime()<=startRule.getTime()){
+						attendance.setMorning("1");
+					}else{
+						attendance.setMorning("2");
+					}
+					if(endTime.getTime()>=endRule.getTime() && c3.compareTo(c1)<0){
+						attendance.setAfternoon("1");
+					}else if(endTime.getTime()<endRule.getTime()){
+						attendance.setAfternoon("3");
+					}else{
+						attendance.setAfternoon("3");
+					}
+				}else if(startTime==null && endTime!=null){
+					if(endTime.getTime()>=endRule.getTime() && c3.compareTo(c1)<0){
+						attendance.setAfternoon("1");
+						attendance.setMorning("5");
+					}else if(endTime.getTime()<endRule.getTime()){
+						attendance.setAfternoon("3");
+						attendance.setMorning("5");
+					}else{
+						attendance.setAfternoon("3");
+						attendance.setMorning("5");
+					}
+				}else if(startTime!=null && endTime==null){
+					if(startTime.getTime()<=startRule.getTime()){
+						attendance.setMorning("1");
+						attendance.setAfternoon("5");
+					}else{
+						attendance.setMorning("2");
+						attendance.setAfternoon("5");
+					}
+				}
+			}else {
+				attendance.setMorning("5");
+				attendance.setAfternoon("5");
+				j.setMsg("获取当日考勤成功");
+			}
+		}
+		try {
+			if(StringUtils.isNotBlank(fromDate)){
+				Date fromThisDay =  new SimpleDateFormat("yyyy-MM-dd").parse(fromDate);
+				model.addAttribute("fromThisDay",fromThisDay);
+			}
+			if(StringUtils.isNotBlank(toDate)){
+				Date toThisDay = new SimpleDateFormat("yyyy-MM-dd").parse(toDate);
+				model.addAttribute("toThisDay",toThisDay);
+			}
+		}catch (ParseException e){
+			e.printStackTrace();
+		}
+		model.addAttribute("username",username);
+		model.addAttribute("page", page);
+		return "modules/oa/oaAttendanceList";
+	}
+
+	/**
+	 * 查看,增加,编辑考勤信息表单页面
+	 */
+	@RequiresPermissions(value={"oa:oaAttendance:view","oa:oaAttendance:add","oa:oaAttendance:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(@RequestParam(value = "readAttr",required = false)String readAttr,OaAttendance oaAttendance, Model model) {
+		model.addAttribute("oaAttendance", oaAttendance);
+		model.addAttribute("disabled",(readAttr==null||"".equals(readAttr))?"false":"true");
+		return "modules/oa/oaAttendanceForm";
+	}
+
+	/**
+	 * 保存考勤信息
+	 */
+	@RequiresPermissions(value={"oa:oaAttendance:add","oa:oaAttendance:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OaAttendance oaAttendance, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, oaAttendance)){
+			return form("",oaAttendance, model);
+		}
+		if(!oaAttendance.getIsNewRecord()){//编辑表单保存
+			OaAttendance t = oaAttendanceService.get(oaAttendance.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(oaAttendance, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			oaAttendanceService.save(t);//保存
+		}else{//新增表单保存
+			oaAttendance.setOfficeId(UserUtils.getSelectOffice().getId());
+			oaAttendanceService.save(oaAttendance);//保存
+		}
+		addMessage(redirectAttributes, "保存考勤信息成功");
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendance/?repage";
+	}
+	
+	/**
+	 * 删除考勤信息
+	 */
+	@RequiresPermissions("oa:oaAttendance:del")
+	@RequestMapping(value = "delete")
+	public String delete(OaAttendance oaAttendance, RedirectAttributes redirectAttributes) {
+		oaAttendanceService.delete(oaAttendance);
+		addMessage(redirectAttributes, "删除考勤信息成功");
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendance/?repage";
+	}
+	
+	/**
+	 * 批量删除考勤信息
+	 */
+	@RequiresPermissions("oa:oaAttendance:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			oaAttendanceService.delete(oaAttendanceService.get(id));
+		}
+		addMessage(redirectAttributes, "删除考勤信息成功");
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendance/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("oa:oaAttendance:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(OaAttendance oaAttendance, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+			User user = UserUtils.getUser();
+			if(! user.isAdmin()){
+				oaAttendance.setCompany(UserUtils.getSelectCompany());
+				if(! UserUtils.isManager()){
+					oaAttendance.setUser(user);
+				}
+			}else{
+
+			}
+
+            String fileName = "考勤信息"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<OaAttendance> page = oaAttendanceService.findPage(new Page<OaAttendance>(request, response, -1), oaAttendance);
+    		new ExportExcel("考勤信息", OaAttendance.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出考勤信息记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendance/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("oa:oaAttendance:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<OaAttendance> list = ei.getDataList(OaAttendance.class);
+			for (OaAttendance oaAttendance : list){
+				try{
+					oaAttendanceService.save(oaAttendance);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条考勤信息记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条考勤信息记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入考勤信息失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendance/?repage";
+    }
+	
+	/**
+	 * 下载导入考勤信息数据模板
+	 */
+	@RequiresPermissions("oa:oaAttendance:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "考勤信息数据导入模板.xlsx";
+    		List<OaAttendance> list = Lists.newArrayList(); 
+    		new ExportExcel("考勤信息数据", OaAttendance.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendance/?repage";
+    }
+	
+	
+	/**
+	 * 选择考勤规则
+	 */
+	@RequestMapping(value = "selectrule")
+	public String selectrule(OaAttendanceRule rule, String url, String fieldLabels, String fieldKeys, String searchLabel, String searchKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<OaAttendanceRule> page = oaAttendanceService.findPageByrule(new Page<OaAttendanceRule>(request, response),  rule);
+		try {
+			fieldLabels = URLDecoder.decode(fieldLabels, "UTF-8");
+			fieldKeys = URLDecoder.decode(fieldKeys, "UTF-8");
+			searchLabel = URLDecoder.decode(searchLabel, "UTF-8");
+			searchKey = URLDecoder.decode(searchKey, "UTF-8");
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		model.addAttribute("labelNames", fieldLabels.split("\\|"));
+		model.addAttribute("labelValues", fieldKeys.split("\\|"));
+		model.addAttribute("fieldLabels", fieldLabels);
+		model.addAttribute("fieldKeys", fieldKeys);
+		model.addAttribute("url", url);
+		model.addAttribute("searchLabel", searchLabel);
+		model.addAttribute("searchKey", searchKey);
+		model.addAttribute("obj", rule);
+		model.addAttribute("page", page);
+		return "modules/sys/gridselect";
+	}
+	
+
+}

+ 262 - 0
src/main/java/com/jeeplus/modules/oa/web/OaAttendanceRuleController.java

@@ -0,0 +1,262 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.web;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.modules.oa.dao.OaAttendancePlaceDao;
+import com.jeeplus.modules.oa.entity.OaAttendancePlace;
+import com.jeeplus.modules.oa.service.OaAttendancePlaceService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.oa.entity.OaAttendanceRule;
+import com.jeeplus.modules.oa.service.OaAttendanceRuleService;
+import com.jeeplus.modules.sys.entity.Office;
+
+/**
+ * 考勤规则Controller
+ * @author 孟祥越
+ * @version 2017-05-10
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oa/oaAttendanceRule")
+public class OaAttendanceRuleController extends BaseController {
+
+	@Autowired
+	private OaAttendanceRuleService oaAttendanceRuleService;
+	@Autowired
+	private OaAttendancePlaceService oaAttendancePlaceService;
+	@ModelAttribute
+	public OaAttendanceRule get(@RequestParam(required=false) String id) {
+		OaAttendanceRule entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = oaAttendanceRuleService.get(id);
+		}
+		if (entity == null){
+			entity = new OaAttendanceRule();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 考勤规则列表页面
+	 */
+	@RequiresPermissions("oa:oaAttendanceRule:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OaAttendanceRule oaAttendanceRule, HttpServletRequest request, HttpServletResponse response, Model model) {
+		User user = UserUtils.getUser();
+		oaAttendanceRule.setCompany(user.getCompany());
+		Page<OaAttendanceRule> page = oaAttendanceRuleService.findPage(new Page<OaAttendanceRule>(request, response), oaAttendanceRule);
+		List<OaAttendanceRule> ruleList= page.getList();
+		List outterList = Lists.newArrayList();
+		for(OaAttendanceRule rule : ruleList){
+			String[] placeIds = rule.getPlaceId().split(",");
+			String[] placeNames = new String[5];
+			for(int i=0;i<placeIds.length;i++){
+				String placeName = oaAttendancePlaceService.getPlaceNameById(placeIds[i]);
+				if(placeName ==null || placeName.length()==0){
+					placeName = "-1";
+				}
+				placeNames[i] = placeName ;
+			}
+			String[] wifiCodes = rule.getWifi().split(",");
+			String[] wifiNames = rule.getWifiName().split(",");
+
+			for(int i=0;i<placeNames.length;i++){
+				String placeName = placeNames[i];
+				String wifiCode  = wifiCodes[i];
+				String wifiName  = wifiNames[i];
+/*				if(!(placeName.equals("-1") && wifiCode.equals("-1"))){
+					String str = placeName+"+"+wifiCode+"+"+wifiName;
+					outterList.add(str);
+				}*/
+				placeName=(placeName.equals("-1")||placeName==null)?"-":placeName;
+				wifiCode = (wifiCode.equals("-1")||wifiCode==null)?"-":wifiCode;
+				wifiName = (wifiName.equals("-1")||wifiName==null)?"-":wifiName;
+				if(!(placeName.equals("-")&&wifiCode.equals("-")&&wifiName.equals("-"))){
+					String str = placeName+"+"+wifiCode+"+"+wifiName;
+					outterList.add(str);
+				}
+			}
+		}
+		model.addAttribute("outterList",outterList);
+		model.addAttribute("page", page);
+		return "modules/oa/oaAttendanceRuleList";
+	}
+
+	/**
+	 * 查看,增加,编辑考勤规则表单页面
+	 */
+	@RequiresPermissions(value={"oa:oaAttendanceRule:view","oa:oaAttendanceRule:add","oa:oaAttendanceRule:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(@RequestParam(value = "readAttr",required = false)String readAttr,OaAttendanceRule oaAttendanceRule, Model model,HttpServletRequest request) {
+
+		String place_wifi_name = request.getParameter("place_wifi_name");
+		if(!StringUtils.isBlank(place_wifi_name)){
+			String[] arr = place_wifi_name.split(" ");
+			model.addAttribute("rule_place",arr[0]);
+			model.addAttribute("rule_wifi",arr[1]);
+			model.addAttribute("rule_wifi_name",arr[2]);
+		}
+		model.addAttribute("oaAttendanceRule", oaAttendanceRule);
+		model.addAttribute("disabled",(readAttr==null||"".equals(readAttr))?"false":"true");
+
+		return "modules/oa/oaAttendanceRuleForm";
+	}
+
+	/**
+	 * 查看,增加,编辑考勤规则表单页面
+	 */
+	@RequiresPermissions(value={"oa:oaAttendanceRule:view","oa:oaAttendanceRule:add","oa:oaAttendanceRule:edit"},logical=Logical.OR)
+	@RequestMapping(value = "companyRuleForm")
+	public String companyRuleForm(String companyId, Model model) {
+		model.addAttribute("oaAttendanceRule", oaAttendanceRuleService.findAttendanceRuleByCompany(companyId));
+		return "modules/oa/oaAttendanceRuleForm";
+	}
+	
+	/**
+	 * 保存考勤规则
+	 */
+	@RequiresPermissions(value={"oa:oaAttendanceRule:add","oa:oaAttendanceRule:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OaAttendanceRule oaAttendanceRule, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, oaAttendanceRule)){
+			return form("",oaAttendanceRule, model,null);
+		}
+		if(!oaAttendanceRule.getIsNewRecord()){//编辑表单保存
+			OaAttendanceRule t = oaAttendanceRuleService.get(oaAttendanceRule.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(oaAttendanceRule, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			oaAttendanceRuleService.save(t);//保存
+		}else{//新增表单保存
+			oaAttendanceRuleService.save(oaAttendanceRule);//保存
+		}
+		addMessage(redirectAttributes, "保存考勤规则成功");
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendanceRule/?repage";
+	}
+	
+	/**
+	 * 删除考勤规则
+	 */
+	@RequiresPermissions("oa:oaAttendanceRule:del")
+	@RequestMapping(value = "delete")
+	public String delete(OaAttendanceRule oaAttendanceRule, RedirectAttributes redirectAttributes) {
+		oaAttendanceRuleService.delete(oaAttendanceRule);
+		addMessage(redirectAttributes, "删除考勤规则成功");
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendanceRule/?repage";
+	}
+	
+	/**
+	 * 批量删除考勤规则
+	 */
+	@RequiresPermissions("oa:oaAttendanceRule:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			oaAttendanceRuleService.delete(oaAttendanceRuleService.get(id));
+		}
+		addMessage(redirectAttributes, "删除考勤规则成功");
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendanceRule/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("oa:oaAttendanceRule:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(OaAttendanceRule oaAttendanceRule, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "考勤规则"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<OaAttendanceRule> page = oaAttendanceRuleService.findPage(new Page<OaAttendanceRule>(request, response, -1), oaAttendanceRule);
+    		new ExportExcel("考勤规则", OaAttendanceRule.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出考勤规则记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendanceRule/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("oa:oaAttendanceRule:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<OaAttendanceRule> list = ei.getDataList(OaAttendanceRule.class);
+			for (OaAttendanceRule oaAttendanceRule : list){
+				try{
+					oaAttendanceRuleService.save(oaAttendanceRule);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条考勤规则记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条考勤规则记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入考勤规则失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendanceRule/?repage";
+    }
+	
+	/**
+	 * 下载导入考勤规则数据模板
+	 */
+	@RequiresPermissions("oa:oaAttendanceRule:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "考勤规则数据导入模板.xlsx";
+    		List<OaAttendanceRule> list = Lists.newArrayList(); 
+    		new ExportExcel("考勤规则数据", OaAttendanceRule.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oa/oaAttendanceRule/?repage";
+    }
+	
+	
+	
+
+}

+ 128 - 0
src/main/java/com/jeeplus/modules/oa/web/OaManageCalendarController.java

@@ -0,0 +1,128 @@
+package com.jeeplus.modules.oa.web;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.modules.oa.entity.Leave;
+import com.jeeplus.modules.oa.service.LeaveService;
+import com.jeeplus.modules.oa.service.ManageCalendarService;
+import com.jeeplus.modules.oa_evection.entity.oa_evection.OaEvection;
+import com.jeeplus.modules.oa_evection.service.oa_evection.OaEvectionService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.work.entity.report.WorkReport;
+import com.jeeplus.modules.workborrowmangement.entity.WorkBorrowMangement;
+import com.jeeplus.modules.workgoout.entity.GoOut;
+import com.jeeplus.modules.workgoout.service.GoOutService;
+import com.jeeplus.modules.workovertimeform.entity.WorkOvertimeForm;
+import com.jeeplus.modules.workovertimeform.service.WorkOvertimeFormService;
+import com.jeeplus.modules.worksealform.entity.WorkSealForm;
+import com.jeeplus.modules.worksealform.service.WorkSealFormService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by admin on 2017/8/24.
+ */
+@Controller
+@RequestMapping("${adminPath}/oa/manageCalendar")
+public class OaManageCalendarController {
+
+    @Autowired
+    private ManageCalendarService manageCalendarService;
+    @Autowired
+    private WorkSealFormService workSealFormService ;
+    @Autowired
+    private LeaveService leaveService;
+    @Autowired
+    private OaEvectionService evectionService;
+    @Autowired
+    private WorkOvertimeFormService workOvertimeFormService;
+    @Autowired
+    private GoOutService goOutService;
+
+    @RequestMapping(value={"","getManageCalendarInfoByMonth"})
+    public ModelAndView manageCalendarInfo(@RequestParam(value = "date",required = false) String date ,HttpServletRequest request, @RequestParam(value="userId",required = false) String userId){
+        ModelAndView mv = new ModelAndView("modules/oa/manageCalendar");
+        if(!UserUtils.isManager()){
+            request.setAttribute("message","您在本公司非管理员,无权查看管理日志");
+            return mv;
+        }
+        if(date==null||"".equals(date)){
+            date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+        }
+        User user;
+        if(UserUtils.getUser()!=null){
+            user =UserUtils.getUser();
+        }else {
+            user =UserUtils.get(userId);
+        }
+        String companyId = null ;
+        if(!user.isAdmin()){
+            companyId = user.getComId();
+        }
+        mv.addObject("user",user);
+        String yearmonthStr = date.substring(0,7);
+        //本公司当月的记录   某一天 --- n条记录
+        List thisMonthRecordList =  manageCalendarService.getManageCalendarByMonth2(companyId,yearmonthStr);
+
+        mv.addObject("thisMonthRecordList",thisMonthRecordList);
+        return mv;
+    }
+    @RequestMapping("/getManageCalendarInfoByDate")
+    public ModelAndView getManageCalendarInfoByDate(HttpServletRequest request,@RequestParam(value="userId",required = false)String userId,@RequestParam(value="date",required = false)String date){
+        ModelAndView mv = new ModelAndView("modules/oa/manageCalendarDetails");
+        User login_user = UserUtils.get(userId);
+        List manageCalendarDetailsList =  manageCalendarService.getReportUserList(date);
+
+        mv.addObject("login_user",login_user);
+        mv.addObject("manageCalendarDetailsList",manageCalendarDetailsList);
+
+        return mv;
+    }
+    @RequestMapping("workSealForm")
+    public String showWorkSealForm(@RequestParam("id")String id ,Model model){
+        WorkSealForm workSealForm = workSealFormService.get(id);
+        model.addAttribute("workSealForm",workSealForm);
+        return "modules/oa/audits-workSealForm";
+    }
+
+    @RequestMapping("leaveForm")
+    public String showLeaveForm(@RequestParam("id")String id , Model model){
+        Leave leave = leaveService.get(id);
+        model.addAttribute("leave",leave);
+        return "modules/oa/audits-leaveForm";
+    }
+
+    @RequestMapping("evectionForm")
+    public String showEvectionForm(@RequestParam("id")String id , Model model){
+        OaEvection oaEvection = evectionService.get(id);
+        model.addAttribute("oaEvection",oaEvection);
+        return "modules/oa/audits-evectionForm";
+    }
+
+    @RequestMapping("workOvertimeForm")
+    public String showWorkOvertimeForm(@RequestParam("id")String id,Model model){
+        WorkOvertimeForm workOvertimeForm = workOvertimeFormService.get(id);
+        model.addAttribute("workOvertimeForm",workOvertimeForm);
+        return "modules/oa/audits-workOvertimeForm";
+    }
+
+    @RequestMapping("goOutForm")
+    public String showGoOutForm(@RequestParam("id")String id ,Model model){
+        GoOut goOut = goOutService.get(id);
+        model.addAttribute("goOut",goOut);
+        return "modules/oa/audits-goOutForm";
+    }
+
+
+}

+ 437 - 0
src/main/java/com/jeeplus/modules/oa/web/OaNotifyController.java

@@ -0,0 +1,437 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.web;
+
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.websocket.onchat.ChatServerPool;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.oa.entity.OaNotify;
+import com.jeeplus.modules.oa.entity.OaNotifyRecord;
+import com.jeeplus.modules.oa.service.OaNotifyService;
+import com.jeeplus.modules.projectrecord.enums.ProjectStatusEnum;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.SystemService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.java_websocket.WebSocket;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * 通知通告Controller
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oa/oaNotify")
+public class OaNotifyController extends BaseController {
+
+	@Autowired
+	private OaNotifyService oaNotifyService;
+    @Autowired
+    private ActTaskService actTaskService;
+	@Autowired
+	private PushinfoService pushinfoService;
+	
+	@ModelAttribute
+	public OaNotify get(@RequestParam(required=false) String id) {
+		OaNotify entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = oaNotifyService.get(id);
+		}
+		if (entity == null){
+			entity = new OaNotify();
+		}
+		return entity;
+	}
+	//我的通告
+	@RequestMapping(value = {"self"})
+	public String listMyself(OaNotify oaNotify, HttpServletRequest request, HttpServletResponse response, Model model) {
+		oaNotify.setSelf(true);
+		Page<OaNotify> page = oaNotifyService.findMyself(new Page<OaNotify>(request, response), oaNotify);
+		List<OaNotify> list = page.getList();
+		for (OaNotify notify:list){
+			if (StringUtils.isNotBlank(notify.getContent())){
+				notify.setContent(notify.getContent().replace("\n",""));
+			}
+		}
+		model.addAttribute("page", page);
+		return "modules/oa/oaNotifyListMyself";
+	}
+	//通告管理
+	@RequiresPermissions("oa:oaNotify:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OaNotify oaNotify, HttpServletRequest request, HttpServletResponse response, Model model,RedirectAttributes redirectAttributes) {
+		User user = UserUtils.getUser();
+		/*if(!UserUtils.isManager()){
+			addMessage(redirectAttributes,"您在本公司非管理员,只能查看'我的通告'");
+			String returnView = "redirect:" + adminPath + "/oa/oaNotify/self" ;
+			return returnView;
+		}*/
+		if(!user.isAdmin()){
+			oaNotify.setCompany(user.getCompany());
+		}
+		Page<OaNotify> page = oaNotifyService.findByPc(new Page<OaNotify>(request, response), oaNotify);
+		model.addAttribute("page", page);
+		return "modules/oa/oaNotifyList";
+	}
+
+	/**
+	 * 查看,增加,编辑报告表单页面
+	 */
+	@RequiresPermissions(value={"oa:oaNotify:view","oa:oaNotify:add","oa:oaNotify:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(@RequestParam(value = "view",required = false)String view, OaNotify oaNotify, Model model) {
+		if (StringUtils.isNotBlank(oaNotify.getId())){
+			oaNotify = oaNotifyService.getRecordList2(oaNotify);
+            oaNotifyService.queryDetails(oaNotify);
+		}
+		if (oaNotify.getCreateDate() == null){
+			oaNotify.setCreateDate(new Date());
+		}
+		if (oaNotify.getCreateBy() == null || StringUtils.isBlank(oaNotify.getCreateBy().getId())){
+			oaNotify.setCreateBy(UserUtils.getUser());
+		}
+		if(oaNotify.getOffice() == null || StringUtils.isBlank(oaNotify.getOffice().getId())){
+            oaNotify.setOffice(UserUtils.getSelectOffice());
+        }
+		oaNotify.setContent("");
+		model.addAttribute("oaNotify", oaNotify);
+		if(StringUtils.isNotBlank(view)&& "view".equals(view)){
+			return "modules/oa/oaNotifyView";
+		}
+		return "modules/oa/oaNotifyForm";
+	}
+
+	/**
+	 * 删除附件
+	 * @param request
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping("delFile")
+	@ResponseBody
+	public AjaxJson delFile(OaNotify oaNotify, HttpServletRequest request, Model model){
+		String id = request.getParameter("id");
+		String attaId = request.getParameter("attaId");
+		String attachmentUrl = request.getParameter("attachmentUrl");
+		oaNotifyService.delFile(attaId,attachmentUrl);
+		AjaxJson ajaxJson = new AjaxJson();
+		ajaxJson.put("attachmentUrl",attachmentUrl);
+		return ajaxJson;
+	}
+
+    /**
+     * 暂存
+     * @param oaNotify
+     * @param model
+     * @param redirectAttributes
+     * @return
+     * @throws Exception
+     */
+    @RequiresPermissions(value={"oa:oaNotify:add","oa:oaNotify:edit"},logical=Logical.OR)
+    @RequestMapping(value = "tstore")
+    public String tstore(OaNotify oaNotify, Model model, RedirectAttributes redirectAttributes) throws Exception{
+        if (!beanValidator(model, oaNotify)){
+            return form("",oaNotify, model);
+        }
+        oaNotify.setStatus(String.valueOf(ProjectStatusEnum.TSTORE.getValue()));
+        if(!oaNotify.getIsNewRecord()){//编辑表单保存
+            OaNotify t = oaNotifyService.get(oaNotify.getId());//从数据库取出记录的值
+            MyBeanUtils.copyBeanNotNull2Bean(oaNotify, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+            oaNotifyService.save(t);//保存
+        }else{//新增表单保存
+            oaNotifyService.save(oaNotify);//保存
+        }
+        addMessage(redirectAttributes, "暂存公告成功");
+        return "redirect:"+ Global.getAdminPath()+"/oa/oaNotify/?repage";
+    }
+
+	//添加操作只在"通告管理"页面完成;
+	@RequiresPermissions(value={"oa:oaNotify:add","oa:oaNotify:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OaNotify oaNotify, Model model,RedirectAttributes redirectAttributes) throws Exception {
+        if (!beanValidator(model, oaNotify)){
+            return form("",oaNotify, model);
+        }
+
+        oaNotify.setState(String.valueOf(ProjectStatusEnum.IN_APRL.getValue()));
+        String str = "";
+        if(!oaNotify.getIsNewRecord()){//编辑表单保存
+            OaNotify t = oaNotifyService.get(oaNotify.getId());//从数据库取出记录的值
+            MyBeanUtils.copyBeanNotNull2Bean(oaNotify, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+            str = oaNotifyService.saveNotify(t);//保存
+        }else{//新增表单保存
+            str = oaNotifyService.saveNotify(oaNotify);//保存
+        }
+        if (StringUtils.isNotBlank(str)){
+            addMessage(redirectAttributes, "保存公告失败:"+str);
+        }else {
+            addMessage(redirectAttributes, "保存公告成功");
+        }
+
+		return "redirect:" + adminPath + "/oa/oaNotify/?repage";
+	}
+
+	//删除只在"通告管理"页面操作,管理员完成;"我的通告"页面不提供删除修改操作;
+	@RequiresPermissions("oa:oaNotify:del")
+	@RequestMapping(value = "delete")
+	public String delete(OaNotify oaNotify, RedirectAttributes redirectAttributes) {
+		//oaNotifyService.delete(oaNotify);
+		oaNotifyService.deleteByOaNotifyId(oaNotify.getId());
+		oaNotify.setRemarks("关闭");
+		oaNotifyService.save(oaNotify);
+		pushinfoService.updateDelflagByPushId(oaNotify.getId(),"1");
+		addMessage(redirectAttributes, "关闭通知成功");
+		return "redirect:" + adminPath + "/oa/oaNotify/list?repage";
+	}
+
+    @RequiresPermissions("oa:oaNotify:del")
+    @RequestMapping(value = "logicDelete")
+    public String logicDelete(OaNotify oaNotify, RedirectAttributes redirectAttributes) {
+        String sta = oaNotify.getStatus();
+        if("5".equals(sta)|| "2".equals(sta)){
+            if("5".equals(sta)){
+                addMessage(redirectAttributes, "公告信息已审批通过,无法删除");
+                return "redirect:"+Global.getAdminPath()+"/oa/oaNotify/list?repage";
+            }else{
+                addMessage(redirectAttributes, "公告信息正在审核中,无法删除");
+                return "redirect:"+Global.getAdminPath()+"/oa/oaNotify/list?repage";
+            }
+        }
+        oaNotifyService.logicDelete(oaNotify);
+        addMessage(redirectAttributes, "删除公告成功");
+        return "redirect:"+Global.getAdminPath()+"/oa/oaNotify/list?repage";
+    }
+
+	//删除只在"通告管理"页面操作,管理员完成;"我的通告"页面不提供删除修改操作;
+	@RequiresPermissions("oa:oaNotify:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			oaNotifyService.delete(oaNotifyService.get(id));
+		}
+		addMessage(redirectAttributes, "删除通知成功");
+		return "redirect:" + adminPath + "/oa/oaNotify/list?repage";
+	}
+	
+	/**
+	 * 我的通知列表
+	 */
+//	@RequestMapping(value = "self")
+//	public String selfList(OaNotify oaNotify, HttpServletRequest request, HttpServletResponse response, Model model) {
+//		User user = UserUtils.getUser();
+//		if(!user.isAdmin()){
+//			oaNotify.setSelf(true);
+//			oaNotify.setCompany(user.getCompany());
+//			oaNotify.setCreateBy(user);
+//			oaNotify.setCurrentUser(user);
+//		}
+//		Page<OaNotify> page = oaNotifyService.find(new Page<OaNotify>(request, response), oaNotify);
+//		model.addAttribute("page", page);
+//		return "modules/oa/oaNotifyList";
+//	}
+//
+
+	/**
+	 * 我的通知列表-数据
+	 */
+	@RequiresPermissions("oa:oaNotify:view")
+	@RequestMapping(value = "selfData")
+	@ResponseBody
+	public Page<OaNotify> listData(OaNotify oaNotify, HttpServletRequest request, HttpServletResponse response, Model model) {
+		oaNotify.setSelf(true);
+		Page<OaNotify> page = oaNotifyService.find(new Page<OaNotify>(request, response), oaNotify);
+		return page;
+	}
+	
+	/**
+	 * 查看我的通知,重定向在当前页面打开
+	 * (在查看时打开view方法就是改变阅读状态而不显示;在查看时打开form方法就是可以看到所有已阅未阅情况)
+	 */
+	@RequestMapping(value = "view")
+	public String view(@RequestParam(value = "readAttr",required = false)String readAttr, OaNotify oaNotify, Model model) {
+		if (StringUtils.isNotBlank(oaNotify.getId())){
+			oaNotifyService.updateReadFlag(oaNotify);
+			UserUtils.pushMeIm("");
+			/*List<WebSocket> toUserConns = ChatServerPool.getWebSocketByUser(UserUtils.getUser().getId());
+			for (WebSocket toUserConn : toUserConns) {
+				String message = "{\"useType\":\"sys_me\"}";
+				ChatServerPool.sendMessageToUser(toUserConn, message);//同时向本人发送消息
+			}*/
+			oaNotify = oaNotifyService.getRecordList(oaNotify);
+			oaNotifyService.getUsers(oaNotify);
+			oaNotifyService.getOffices(oaNotify);
+			model.addAttribute("toReadMyNotify",true);
+			model.addAttribute("disabled",(readAttr==null||"".equals(readAttr))?"false":"true");
+			model.addAttribute("oaNotify", oaNotify);
+			return "modules/oa/oaNotifyView";
+		}
+		return "redirect:" + adminPath + "/oa/oaNotify/self?repage";
+
+	}
+
+	/**
+	 * 查看我的通知-数据
+	 */
+	@RequestMapping(value = "viewData")
+	@ResponseBody
+	public OaNotify viewData(OaNotify oaNotify, Model model) {
+		if (StringUtils.isNotBlank(oaNotify.getId())){
+			oaNotifyService.updateReadFlag(oaNotify);
+			return oaNotify;
+		}
+		return null;
+	}
+	
+	/**
+	 * 查看我的通知-发送记录
+	 */
+	@RequestMapping(value = "viewRecordData")
+	@ResponseBody
+	public OaNotify viewRecordData(OaNotify oaNotify, Model model) {
+		if (StringUtils.isNotBlank(oaNotify.getId())){
+			oaNotify = oaNotifyService.getRecordList(oaNotify);
+			return oaNotify;
+		}
+		return null;
+	}
+	
+	/**
+	 * 获取我的通知数目
+	 */
+	@RequestMapping(value = "self/count")
+	@ResponseBody
+	public String selfCount(OaNotify oaNotify, Model model) {
+		oaNotify.setSelf(true);
+		oaNotify.setReadFlag("0");
+		return String.valueOf(oaNotifyService.findCount(oaNotify));
+	}
+
+    //	审批页面
+    @RequestMapping(value = "audit")
+    public String workContractInfoAudit(Act act, OaNotify oaNotify, Model model) {
+        if(StringUtils.isNotBlank(oaNotify.getId())){
+            oaNotifyService.queryDetails(oaNotify);
+        }
+        if (act.getProcInsId() != null) {
+            if (actTaskService.getProcIns(act.getProcInsId()) != null) {
+                act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+            } else {
+                act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+            }
+        }
+        if (act != null && StringUtils.isNotBlank(act.getTaskId())) {
+            oaNotify.setAct(act);
+            model.addAttribute("processInstanceId", oaNotify.getProcessInstanceId());
+        }
+        model.addAttribute("oaNotify", oaNotify);
+        return "modules/oa/oaNotifyAudit";
+    }
+
+    /**
+     * 工单执行(完成任务)
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "saveAudit")
+    public String saveAudit(OaNotify oaNotify, Model model,
+                            RedirectAttributes redirectAttributes) {
+        try {
+            List<User> users = UserUtils.getByProssType(oaNotify.getProcessInstanceId(),1);
+            String flag = oaNotify.getAct().getFlag();
+            if ("yes".equals(flag) && (users==null || users.size()==0)){
+                addMessage(redirectAttributes, "审批失败,审批人为空,请联系管理员!");
+            }else {
+                String str = oaNotifyService.auditSave(oaNotify, users);
+                addMessage(redirectAttributes, str);
+            }
+        }catch (Exception e){
+            addMessage(redirectAttributes, "公告流程审批失败");
+        }
+
+        if (StringUtils.isNotBlank(oaNotify.getHome()) && "home".equals(oaNotify.getHome())){
+            return "redirect:" + Global.getAdminPath() + "/home/?repage";
+        }else {
+            return "redirect:" + Global.getAdminPath() + "/oa/oaNotify/list?repage";
+        }
+    }
+
+    @RequestMapping(value = "getProcess")
+    public String getProcess(OaNotify oaNotify, Model model, HttpServletRequest request){
+        model.addAttribute("processInstanceId", oaNotify.getProcessInstanceId());
+        return "modules/worksendmessage/workSendMessageTask";
+    }
+
+    @RequiresPermissions(value={"oa:oaNotify:edit"},logical=Logical.OR)
+    @RequestMapping(value = "modify")
+    public String modify(OaNotify oaNotify, Model model,RedirectAttributes redirectAttributes) {
+        oaNotify=oaNotifyService.get(oaNotify.getId());
+        if(StringUtils.isNotBlank(oaNotify.getId())){
+            oaNotifyService.queryDetails(oaNotify);
+        }
+        ProcessInstance processInstance = actTaskService.getProcIns(oaNotify.getProcessInstanceId());
+        if (processInstance!=null) {
+            Task taskInfok = actTaskService.getCurrentTaskInfo(processInstance);
+            Act act = new Act();
+            act.setTaskId(taskInfok.getId());
+            act.setTaskName(taskInfok.getName());
+            act.setTaskDefKey(taskInfok.getTaskDefinitionKey());
+            act.setProcDefId(taskInfok.getProcessDefinitionId());
+            act.setProcInsId(taskInfok.getProcessInstanceId());
+            act.setTask(taskInfok);
+            oaNotify.setAct(act);
+        }
+
+        model.addAttribute("oaNotify", oaNotify);
+        return "modules/oa/oaNotifyModifyApply";
+    }
+
+    @RequiresPermissions(value={"oa:oaNotify:edit"},logical=Logical.OR)
+    @RequestMapping(value = "revoke")
+    public String revoke(HttpServletRequest request, RedirectAttributes redirectAttributes) {
+        HashMap<String, String> requestMap = findRequestMap(request);
+        String processInstanceId = requestMap.get("processInstanceId");
+        String id = requestMap.get("id");
+        try {
+            OaNotify oaNotify = oaNotifyService.get(id);
+            if("5".equals(oaNotify.getStatus())){
+                addMessage(redirectAttributes, "公告信息已审批通过,无法撤回");
+                return "redirect:"+Global.getAdminPath()+"/oa/oaNotify/list?repage";
+            }
+            oaNotifyService.cancelProcess(oaNotify);
+            addMessage(redirectAttributes, "撤回该公告审批成功");
+        }catch (Exception e){
+            logger.info(e.getMessage());
+            addMessage(redirectAttributes, "撤回该公告审批失败");
+        }
+        return "redirect:" + Global.getAdminPath() + "/oa/oaNotify/list?repage";
+    }
+}

+ 169 - 0
src/main/java/com/jeeplus/modules/oa/web/TestAuditController.java

@@ -0,0 +1,169 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa.web;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.oa.entity.TestAudit;
+import com.jeeplus.modules.oa.service.TestAuditService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+
+/**
+ * 审批Controller
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oa/testAudit")
+public class TestAuditController extends BaseController {
+
+	@Autowired
+	private TestAuditService testAuditService;
+	
+	@ModelAttribute
+	public TestAudit get(@RequestParam(required=false) String id){//, 
+//			@RequestParam(value="act.procInsId", required=false) String procInsId) {
+		TestAudit testAudit = null;
+		if (StringUtils.isNotBlank(id)){
+			testAudit = testAuditService.get(id);
+//		}else if (StringUtils.isNotBlank(procInsId)){
+//			testAudit = testAuditService.getByProcInsId(procInsId);
+		}
+		if (testAudit == null){
+			testAudit = new TestAudit();
+		}
+		return testAudit;
+	}
+	
+	@RequestMapping(value = {"list", ""})
+	public String list(TestAudit testAudit, HttpServletRequest request, HttpServletResponse response, Model model) {
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()){
+			testAudit.setCreateBy(user);
+		}
+        Page<TestAudit> page = testAuditService.findPage(new Page<TestAudit>(request, response), testAudit); 
+        model.addAttribute("page", page);
+		return "modules/oa/testAuditList";
+	}
+	
+	/**
+	 * 申请单填写
+	 * @param testAudit
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "form")
+	public String form(TestAudit testAudit, Model model) {
+		
+		String view = "testAuditForm";
+		
+		// 查看审批申请单
+		if (StringUtils.isNotBlank(testAudit.getId())){//.getAct().getProcInsId())){
+
+			// 环节编号
+			String taskDefKey = testAudit.getAct().getTaskDefKey();
+			
+			// 查看工单
+			if(testAudit.getAct().isFinishTask()){
+				view = "testAuditView";
+			}
+			// 修改环节
+			else if ("modify".equals(taskDefKey)){
+				view = "testAuditForm";
+			}
+			// 审核环节
+			else if ("audit".equals(taskDefKey)){
+				view = "testAuditAudit";
+//				String formKey = "/oa/testAudit";
+//				return "redirect:" + ActUtils.getFormUrl(formKey, testAudit.getAct());
+			}
+			// 审核环节2
+			else if ("audit2".equals(taskDefKey)){
+				view = "testAuditAudit";
+			}
+			// 审核环节3
+			else if ("audit3".equals(taskDefKey)){
+				view = "testAuditAudit";
+			}
+			// 审核环节4
+			else if ("audit4".equals(taskDefKey)){
+				view = "testAuditAudit";
+			}
+			// 兑现环节
+			else if ("apply_end".equals(taskDefKey)){
+				view = "testAuditAudit";
+			}
+		}
+
+		model.addAttribute("testAudit", testAudit);
+		return "modules/oa/" + view;
+	}
+	
+	/**
+	 * 申请单保存/修改
+	 * @param testAudit
+	 * @param model
+	 * @param redirectAttributes
+	 * @return
+	 */
+	@RequestMapping(value = "save")
+	public String save(TestAudit testAudit, Model model, RedirectAttributes redirectAttributes) {
+		if (!beanValidator(model, testAudit)){
+			return form(testAudit, model);
+		}
+		testAuditService.save(testAudit);
+		addMessage(redirectAttributes, "提交审批'" + testAudit.getUser().getName() + "'成功");
+		if(testAudit.getId()==null || testAudit.getId().equals("")){
+			return "redirect:" + adminPath + "/act/task/process/";
+		}else{
+			return "redirect:" + adminPath + "/act/task/todo/";
+		}
+		
+	}
+
+	/**
+	 * 工单执行(完成任务)
+	 * @param testAudit
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "saveAudit")
+	public String saveAudit(TestAudit testAudit, Model model) {
+		/*if (StringUtils.isBlank(testAudit.getAct().getFlag())
+				|| StringUtils.isBlank(testAudit.getAct().getComment())){
+			addMessage(model, "请填写审核意见。");
+			return form(testAudit, model);
+		}*/
+		testAuditService.auditSave(testAudit);
+		return "redirect:" + adminPath + "/act/task";
+	}
+	
+	/**
+	 * 删除工单
+	 * @param id
+	 * @param redirectAttributes
+	 * @return
+	 */
+	@RequestMapping(value = "delete")
+	public String delete(TestAudit testAudit, RedirectAttributes redirectAttributes) {
+		testAuditService.delete(testAudit);
+		addMessage(redirectAttributes, "删除审批成功");
+		return "redirect:" + adminPath + "/oa/testAudit/?repage";
+	}
+
+}

+ 45 - 0
src/main/java/com/jeeplus/modules/oa_evection/dao/oa_evection/OaEvectionDao.java

@@ -0,0 +1,45 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa_evection.dao.oa_evection;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oa_evection.entity.oa_evection.OaEvection;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 出差流程DAO接口
+ * @author 丁旭
+ * @version 2017-05-22
+ */
+@MyBatisDao
+public interface OaEvectionDao extends CrudDao<OaEvection> {
+	/**
+	 * 更新流程实例ID
+	 * @param oaEvection
+	 * @return
+	 */
+	public int updateProcessInstanceId(OaEvection oaEvection);
+
+    /**
+     * 根据流程实例ID获取Leave
+     * @param processInstanceId
+     * @return
+     */
+    public OaEvection getByProcessInstanceId(String processInstanceId);
+
+    List getCreateDateList(Map<String, String> map);
+
+    List<OaEvection> findByCompany2(Map<String, Object> map);
+
+	public List getCreateDateList1(Map<String,String> map);
+	public List findByCompany1(Map<String,String> map);
+	public List getCreateDateListAll(Map<String,String> map);
+	public List findByCompanyAll(Map<String,String> map);
+	public List<OaEvection> findByManage(Map<String,Object> map);
+	public List<OaEvection> findByCompanySelf(Map<String,Object> map);
+}

+ 418 - 0
src/main/java/com/jeeplus/modules/oa_evection/entity/oa_evection/OaEvection.java

@@ -0,0 +1,418 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa_evection.entity.oa_evection;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 出差流程Entity
+ * @author 丁旭
+ * @version 2017-05-22
+ */
+public class OaEvection extends ActEntity<OaEvection> {
+	
+	private static final long serialVersionUID = 1L;
+	private String startTime;		// 开始时间
+	private String endTime;		// 结束时间
+	private String processInstanceId;		// 流程实例ID
+	private String realityStartTime;		// 实际开始时间
+	private String realityEndTime;		// 实际结束时间
+	private String reason;		// 出差事由
+	private String address;		// 出差地点
+	private String dateCount;		// 出差天数
+    private String companyId; //公司主键
+	private String officeId;
+    private String files; //
+    private String status;		// 申请状态
+    private String comment; //审核意见 目前只保存手机端审核
+	private String ids;
+	private String idNames;
+	private String ida;
+	private String idNamea;
+	private String idb;
+	private String idNameb;
+	private String idc;
+	private String idNamec;
+	private String idd;
+	private String idNamed;
+	private String ide;
+	private String idNamee;
+	private String CCId;
+	private Date createDateStart;
+	private Date createDateEnd;
+	private String name;
+	private String time;
+	private List<String> adds = Lists.newArrayList();
+	private List<Workattachment> workattachmentList;
+	private String home;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getTime() {
+		return time;
+	}
+
+	public void setTime(String time) {
+		this.time = time;
+	}
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getFiles() {
+        return files;
+    }
+
+    public void setFiles(String files) {
+        this.files = files;
+    }
+
+    public String getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(String companyId) {
+        this.companyId = companyId;
+    }
+
+	// 流程任务
+		private Task task;
+		private Map<String, Object> variables;
+		// 运行中的流程实例
+		private ProcessInstance processInstance;
+		// 历史的流程实例
+		private HistoricProcessInstance historicProcessInstance;
+		// 流程定义
+		private ProcessDefinition processDefinition;
+	
+	
+	
+	
+	public Task getTask() {
+			return task;
+		}
+
+		public void setTask(Task task) {
+			this.task = task;
+		}
+
+		public Map<String, Object> getVariables() {
+			return variables;
+		}
+
+		public void setVariables(Map<String, Object> variables) {
+			this.variables = variables;
+		}
+
+		public ProcessInstance getProcessInstance() {
+			return processInstance;
+		}
+
+		public void setProcessInstance(ProcessInstance processInstance) {
+			this.processInstance = processInstance;
+		}
+
+		public HistoricProcessInstance getHistoricProcessInstance() {
+			return historicProcessInstance;
+		}
+
+		public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
+			this.historicProcessInstance = historicProcessInstance;
+		}
+
+		public ProcessDefinition getProcessDefinition() {
+			return processDefinition;
+		}
+
+		public void setProcessDefinition(ProcessDefinition processDefinition) {
+			this.processDefinition = processDefinition;
+		}
+
+	public OaEvection() {
+		super();
+	}
+
+	public OaEvection(String id){
+		super(id);
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="开始时间", align=2, sort=7)
+	public String getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(String startTime) {
+		this.startTime = startTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="结束时间", align=2, sort=8)
+	public String getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(String endTime) {
+		this.endTime = endTime;
+	}
+	
+	@ExcelField(title="流程实例ID", align=2, sort=9)
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="实际开始时间", align=2, sort=10)
+	public String getRealityStartTime() {
+		return realityStartTime;
+	}
+
+	public void setRealityStartTime(String realityStartTime) {
+		this.realityStartTime = realityStartTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="实际结束时间", align=2, sort=11)
+	public String getRealityEndTime() {
+		return realityEndTime;
+	}
+
+	public void setRealityEndTime(String realityEndTime) {
+		this.realityEndTime = realityEndTime;
+	}
+	
+	@ExcelField(title="出差事由", align=2, sort=12)
+	public String getReason() {
+		return reason;
+	}
+
+	public void setReason(String reason) {
+		this.reason = reason;
+	}
+	
+	@ExcelField(title="出差地点", align=2, sort=13)
+	public String getAddress() {
+		return address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+	
+	@ExcelField(title="出差天数", align=2, sort=14)
+	public String getDateCount() {
+		return dateCount;
+	}
+
+	public void setDateCount(String dateCount) {
+		this.dateCount = dateCount;
+	}
+
+	public String getIds() {
+		List<String> idList = Lists.newArrayList();
+		if (StringUtils.isNotBlank(ids)) {
+			String ss = ids.trim().replace(" ", ",").replace(" ", ",").replace(",", ",").replace("'", "");
+			for (String s : ss.split(",")) {
+				// if(s.matches("\\d*")) {
+				idList.add("'" + s + "'");
+				// }
+			}
+		}
+		return StringUtils.join(idList, ",");
+	}
+
+	public void setIds(String ids) {
+		this.ids = ids;
+	}
+
+	public String getIdNames() {
+		List<String> idList = Lists.newArrayList();
+		if (StringUtils.isNotBlank(idNames)) {
+			String ss = idNames.trim().replace(" ", ",").replace(" ", ",").replace(",", ",").replace("'", "");
+			for (String s : ss.split(",")) {
+				// if(s.matches("\\d*")) {
+				idList.add("'" + s + "'");
+				// }
+			}
+		}
+		return StringUtils.join(idList, ",");
+	}
+
+	public void setIdNames(String idNames) {
+		this.idNames = idNames;
+	}
+
+	@ExcelField(title="申请人", align=2, sort=12)
+	public String getIda() {
+		return ida;
+	}
+
+	public void setIda(String ida) {
+		this.ida = ida;
+	}
+
+	public String getIdNamea() {
+		return idNamea;
+	}
+
+	public void setIdNamea(String idNamea) {
+		this.idNamea = idNamea;
+	}
+
+	public String getIdb() {
+		return idb;
+	}
+
+	public void setIdb(String idb) {
+		this.idb = idb;
+	}
+
+	public String getIdNameb() {
+		return idNameb;
+	}
+
+	public void setIdNameb(String idNameb) {
+		this.idNameb = idNameb;
+	}
+
+	public String getIdc() {
+		return idc;
+	}
+
+	public void setIdc(String idc) {
+		this.idc = idc;
+	}
+
+	public String getIdNamec() {
+		return idNamec;
+	}
+
+	public void setIdNamec(String idNamec) {
+		this.idNamec = idNamec;
+	}
+
+	public String getIdd() {
+		return idd;
+	}
+
+	public void setIdd(String idd) {
+		this.idd = idd;
+	}
+
+	public String getIdNamed() {
+		return idNamed;
+	}
+
+	public void setIdNamed(String idNamed) {
+		this.idNamed = idNamed;
+	}
+
+	public String getIde() {
+		return ide;
+	}
+
+	public void setIde(String ide) {
+		this.ide = ide;
+	}
+
+	public String getIdNamee() {
+		return idNamee;
+	}
+
+	public void setIdNamee(String idNamee) {
+		this.idNamee = idNamee;
+	}
+
+	public String getCCId() {
+		return CCId;
+	}
+
+	public void setCCId(String CCId) {
+		this.CCId = CCId;
+	}
+
+	public Date getCreateDateStart() {
+		return createDateStart;
+	}
+
+	public void setCreateDateStart(Date createDateStart) {
+		this.createDateStart = createDateStart;
+	}
+
+	public Date getCreateDateEnd() {
+		return createDateEnd;
+	}
+
+	public void setCreateDateEnd(Date createDateEnd) {
+		this.createDateEnd = createDateEnd;
+	}
+
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+
+	public List<String> getAdds() {
+		return adds;
+	}
+
+	public void setAdds(List<String> adds) {
+		this.adds = adds;
+	}
+
+	public List<Workattachment> getWorkattachmentList() {
+		return workattachmentList;
+	}
+
+	public void setWorkattachmentList(List<Workattachment> workattachmentList) {
+		this.workattachmentList = workattachmentList;
+	}
+
+	public String getHome() {
+		return home;
+	}
+
+	public void setHome(String home) {
+		this.home = home;
+	}
+}

+ 814 - 0
src/main/java/com/jeeplus/modules/oa_evection/service/oa_evection/OaEvectionService.java

@@ -0,0 +1,814 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa_evection.service.oa_evection;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.Collections3;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.websocket.onchat.ChatServerPool;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oa_evection.dao.oa_evection.OaEvectionDao;
+import com.jeeplus.modules.oa_evection.entity.oa_evection.OaEvection;
+import com.jeeplus.modules.pushinfo.entity.Pushinfo;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.java_websocket.WebSocket;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 出差流程Service
+ *
+ * @author 丁旭
+ * @version 2017-05-22
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaEvectionService extends CrudService<OaEvectionDao, OaEvection> {
+    @Autowired
+    private OaEvectionDao oaEvectionDao;
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    protected TaskService taskService;
+    @Autowired
+    protected HistoryService historyService;
+    @Autowired
+    protected RepositoryService repositoryService;
+    @Autowired
+    private IdentityService identityService;
+    @Autowired
+    private UserDao userDao;
+
+    @Autowired
+    private ActTaskService actTaskService;
+    @Autowired
+    private ApprovalCopyService approvalCopyService;
+
+    @Autowired
+    private PushinfoService pushinfoService;
+    @Autowired
+    private WorkProjectNotifyService workProjectNotifyService;
+    @Autowired
+    private WorkattachmentService workattachmentService;
+
+    @SuppressWarnings("unchecked")
+    public OaEvection get(String id) {
+        OaEvection oaEvection = oaEvectionDao.get(id);
+        Map<String, Object> variables = null;
+
+        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(oaEvection.getProcessInstanceId()).singleResult();
+        if (historicProcessInstance != null) {
+            variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
+        } else {
+            variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(oaEvection.getProcessInstanceId()).active().singleResult().getId());
+        }
+        oaEvection.setVariables(variables);
+
+        List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(oaEvection.getId(),"73");
+        oaEvection.setWorkattachmentList(workattachmentList);
+        return oaEvection;
+    }
+
+    @SuppressWarnings("unchecked")
+    public OaEvection getById(String id) {
+        OaEvection oaEvection = oaEvectionDao.get(id);
+        return oaEvection;
+    }
+
+    @Transactional(readOnly = false)
+    public Map getEvectionById(String id, String type) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        OaEvection oaEvection = this.getById(id);
+        Map<String, Object> map = Maps.newHashMap();
+        if (oaEvection != null) {
+            User user = userDao.get(oaEvection.getCreateBy());
+            String officeName = "";
+            if (user != null) {
+                map.put("userName", user.getName());
+                map.put("photo", user.getPhoto());
+                map.put("users", user.getId());
+                Office office = user.getOffice();
+                if (office != null && office.getName() != null) {
+                    officeName = office.getName();
+                }
+            }
+            map.put("officeName", officeName);
+            map.put("createDate", oaEvection.getCreateDate() == null ? "" : sdf.format(oaEvection.getCreateDate()));
+            map.put("startTime", oaEvection.getStartTime());
+            map.put("endTime", oaEvection.getEndTime());
+            map.put("address", oaEvection.getAddress());
+            map.put("dateCount", oaEvection.getDateCount());
+            map.put("reason", oaEvection.getReason());
+            map.put("approvalId", id);
+            map.put("status", oaEvection.getStatus());
+            map.put("companyId", oaEvection.getCompanyId());
+            /*map.put("files", oaEvection.getFiles() == null ? "" : oaEvection.getFiles());*/
+            List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(oaEvection.getId(),"73");
+            String files = "";
+            if (workattachmentList!=null && workattachmentList.size()!=0){
+                for (Workattachment workattachment : workattachmentList){
+                    files += workattachment.getUrl()+",";
+                }
+                if (files.length() > 1) {
+                    files = files.substring(0, files.length() - 1);
+                }
+            }
+            map.put("files", files);
+            List<Act> list = actTaskService.histoicFlowList(oaEvection.getProcessInstanceId(), "", "");
+            List<Act> list2 = actTaskService.toMyStartedList(oaEvection.getProcessInstanceId());
+            if (list2 != null && list2.size() != 0) {
+                Act act1 = list2.get(list2.size() - 1);
+                map.put("taskId", act1.getTaskId());
+                map.put("taskName", act1.getTaskName());
+                map.put("procInsId", act1.getProcInsId());
+                map.put("procDefId", act1.getProcDefId());
+                map.put("actStatus", act1.getStatus() == null ? "todo" : act1.getStatus());
+                map.put("taskDefKey", act1.getTaskDefKey());
+                map.put("procDefKey", "evection");
+            }
+            List list1 = new ArrayList();
+            String approvalStatus = "0";
+            String assigneeName = "";
+            if (list != null && list.size() != 0) {
+                if (list.get(0).getHistIns().getActivityName().contains("审批")) {
+                    for (int i = list.size() - 1; i > -1; i--) {
+                        Act act = list.get(i);
+                        Map<String, Object> maps = new HashMap<String, Object>();
+                        String state = "0";
+                        String activityName = "";
+                        if (act.getHistIns().getActivityName().contains("审批")) {
+                            if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+                                activityName = "已审批";
+                                if (UserUtils.getUser().getName().equals(act.getAssigneeName())) {
+                                    approvalStatus = "1";
+                                }
+                            } else {
+                                activityName = "待审批";
+                                state = "2";
+                            }
+                        } else {
+                            activityName = act.getHistIns().getActivityName();
+                        }
+                        maps.put("activityName", activityName);
+                        maps.put("assigneeName", UserUtils.getUser().getName().equals(act.getAssigneeName()) ? "我" : act.getAssigneeName());
+                        maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+                        maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+                        maps.put("durationTime", act.getDurationTime());
+                        maps.put("state", state);
+                        maps.put("userId", act.getCurrentUser().getId());
+                        list1.add(maps);
+                    }
+                } else {
+                    if (oaEvection.getStatus().equals("4") || oaEvection.getStatus().equals("3")) {
+                        for (int i = 0; i < list.size() - 1; i++) {
+                            Act act = list.get(i);
+                            Map<String, Object> maps = new HashMap<String, Object>();
+                            String state = "0";
+                            String activityName = "";
+                            if (act.getHistIns().getActivityName().contains("发起申请")) {
+                                activityName = act.getHistIns().getActivityName();
+                                assigneeName = act.getAssigneeName();
+                            } else if (act.getHistIns().getActivityName().contains("审批")) {
+                                if (UserUtils.get(act.getHistIns().getAssignee()) != null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                                if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+                                    activityName = "已审批";
+                                    if (UserUtils.getUser().getName().equals(assigneeName)) {
+                                        approvalStatus = "1";
+                                    }
+                                    if (i == (list.size() - 2) && oaEvection.getStatus().equals("4")) {
+                                        activityName = "审核驳回";
+                                        state = "1";
+                                    } else if (i == (list.size() - 2) && oaEvection.getStatus().equals("3")) {
+                                        activityName = "审核成功";
+                                    }
+                                } else {
+                                    activityName = "待审批";
+                                    state = "2";
+                                }
+                            } else {
+                                activityName = act.getHistIns().getActivityName();
+                                if (UserUtils.get(act.getHistIns().getAssignee()) != null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                            }
+
+                            if (type.equals("1") || type.equals("2")) {
+                                maps.put("activityName", activityName);
+                                maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+                            } else if (type.equals("3")) {
+                                maps.put("activityName", activityName);
+                                maps.put("assigneeName", assigneeName);
+                            }
+                            maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+                            maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+                            maps.put("durationTime", act.getDurationTime());
+                            maps.put("state", state);
+                            maps.put("userId", act.getCurrentUser().getId());
+                            list1.add(maps);
+                        }
+                    } else {
+                        for (int i = 0; i < list.size(); i++) {
+                            Act act = list.get(i);
+                            Map<String, Object> maps = new HashMap<String, Object>();
+                            String state = "0";
+                            String activityName = "";
+                            if (act.getHistIns().getActivityName().contains("发起申请")) {
+                                activityName = act.getHistIns().getActivityName();
+                                assigneeName = act.getAssigneeName();
+                            } else if (act.getHistIns().getActivityName().contains("审批")) {
+                                if (UserUtils.get(act.getHistIns().getAssignee()) != null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                                if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+                                    activityName = "已审批";
+                                    if (UserUtils.getUser().getName().equals(assigneeName)) {
+                                        approvalStatus = "1";
+                                    }
+                                } else {
+                                    activityName = "待审批";
+                                    state = "2";
+                                }
+                            } else {
+                                activityName = act.getHistIns().getActivityName();
+                                if (UserUtils.get(act.getHistIns().getAssignee()) != null) {
+                                    assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+                                }
+                            }
+                            if (oaEvection.getStatus().equals("5") && i == list.size() - 1) {
+                                activityName = "已撤销";
+                                state = "1";
+                            }
+                            maps.put("activityName", activityName);
+                            maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+                            maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+                            maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+                            maps.put("durationTime", act.getDurationTime());
+                            maps.put("state", state);
+                            maps.put("userId", act.getCurrentUser().getId());
+                            list1.add(maps);
+                        }
+                    }
+                }
+            }
+            map.put("approvalStatus", approvalStatus);
+            ApprovalCopy approvalCopy = new ApprovalCopy();
+            approvalCopy.setApprovalId(id);
+            List<ApprovalCopy> approvalCopyList = approvalCopyService.findList(approvalCopy);
+            String CCName = "";
+            String CCId = "";
+            Boolean readFlag = false;
+            if (approvalCopyList != null && approvalCopyList.size() != 0) {
+                ApprovalCopy approvalCopy1 = approvalCopyList.get(0);
+                CCId = approvalCopy1.getCCId();
+                String[] CCid = approvalCopy1.getCCId().split(",");
+                readFlag = approvalCopy1.getReadFlag().equals("0");
+                if (type.equals("3") && readFlag) {
+                    approvalCopy1.setReadFlag("1");
+                    approvalCopyService.save(approvalCopy1);
+                }
+                for (String userId : CCid) {
+                    User CCUser = UserUtils.get(userId);
+                    if (CCUser != null) {
+                        CCName = CCUser.getName() + ",";
+                    }
+                }
+                if (CCName.length() > 1) {
+                    CCName = CCName.substring(0, CCName.length() - 1);
+                } else {
+                    CCName = "";
+                }
+            }
+            map.put("nameCopy", CCName);
+            map.put("CCId", CCId);
+            map.put("process", list1);
+        }
+        return map;
+    }
+
+    public List<OaEvection> findList(OaEvection oaEvection) {
+        return super.findList(oaEvection);
+    }
+
+    public Page<OaEvection> findPage(Page<OaEvection> page, OaEvection oaEvection) {
+        return super.findPage(page, oaEvection);
+    }
+
+    //暂存
+    @Transactional(readOnly = false)
+    public void save(OaEvection oaEvection) {
+        super.save(oaEvection);
+    }
+
+    //启动流程
+    @Transactional(readOnly = false)
+    public void submit(OaEvection oaEvection, Map<String, Object> variables, String type) {
+        // 保存业务数据
+        if (StringUtils.isBlank(oaEvection.getId())) {
+            // 保存业务数据
+            super.save(oaEvection);
+
+            logger.debug("save entity: {}", oaEvection);
+
+            // 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+            identityService.setAuthenticatedUserId(oaEvection.getCurrentUser().getId());
+
+            // 启动流程
+            String businessKey = oaEvection.getId().toString();
+            variables.put("type", "evection");
+            variables.put("busId", businessKey);
+            variables.put("title", oaEvection.getReason());//设置标题;
+
+            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ActUtils.PD_OA_EVECTION[0], businessKey, variables);
+            oaEvection.setProcessInstance(processInstance);
+            // 更新流程实例ID
+            oaEvection.setProcessInstanceId(processInstance.getId());
+            oaEvectionDao.updateProcessInstanceId(oaEvection);
+
+        } else {
+            oaEvection.preUpdate();
+            oaEvectionDao.update(oaEvection);
+            oaEvection.getAct().setComment(("yes".equals(oaEvection.getAct().getFlag()) ? "[重申] " : "[销毁] ") + oaEvection.getAct().getComment());
+
+            // 完成流程任务
+            Map<String, Object> vars = Maps.newHashMap();
+            vars.put("reApply", "yes".equals(oaEvection.getAct().getFlag()) ? true : false);
+            actTaskService.complete(oaEvection.getAct().getTaskId(), oaEvection.getAct().getProcInsId(), oaEvection.getAct().getComment(), oaEvection.getComment(), vars);
+        }
+
+    }
+
+    @Transactional(readOnly = false)
+    public void saveFile(OaEvection oaEvection) {
+        if (StringUtils.isBlank(oaEvection.getId())) {
+            oaEvection.preInsert();
+            oaEvectionDao.insert(oaEvection);
+        } else {
+            oaEvection.preUpdate();
+            oaEvectionDao.update(oaEvection);
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public void delete(OaEvection oaEvection) {
+        oaEvectionDao.delete(oaEvection);
+    }
+
+    @Transactional(readOnly = false)
+    public void update(OaEvection oaEvection) {
+        oaEvection.preUpdate();
+        oaEvectionDao.update(oaEvection);
+    }
+
+    /**
+     * 获取流程详细信息
+     *
+     * @param processInstanceId
+     */
+    @SuppressWarnings("unchecked")
+    public OaEvection getByProcessInstanceId(String processInstanceId) {
+        OaEvection oaEvection = oaEvectionDao.getByProcessInstanceId(processInstanceId);
+        return oaEvection;
+    }
+
+    /**
+     * 查询待办任务
+     *
+     * @param userId 用户ID
+     * @return
+     */
+    public List<OaEvection> findTodoTasks(String userId) {
+
+        List<OaEvection> results = new ArrayList<OaEvection>();
+        List<Task> tasks = new ArrayList<Task>();
+        // 根据当前人的ID查询
+        List<Task> todoList = taskService.createTaskQuery().processDefinitionKey(ActUtils.PD_OA_EVECTION[0]).taskAssignee(userId).active().orderByTaskPriority().desc().orderByTaskCreateTime().desc().list();
+
+        // 根据当前人未签收的任务
+        List<Task> unsignedTasks = taskService.createTaskQuery().processDefinitionKey(ActUtils.PD_OA_EVECTION[0]).taskCandidateUser(userId).active().orderByTaskPriority().desc().orderByTaskCreateTime().desc().list();
+        // 合并
+        tasks.addAll(todoList);
+        tasks.addAll(unsignedTasks);
+        // 根据流程的业务ID查询实体并关联
+        for (Task task : tasks) {
+            String processInstanceId = task.getProcessInstanceId();
+            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
+            String businessKey = processInstance.getBusinessKey();
+            OaEvection oaEvection = oaEvectionDao.get(businessKey);
+            oaEvection.setTask(task);
+            oaEvection.setProcessInstance(processInstance);
+            oaEvection.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId((processInstance.getProcessDefinitionId())).singleResult());
+            results.add(oaEvection);
+        }
+        return results;
+    }
+
+
+    /* * 审核审批保存
+     * @param testAudit
+     */
+    @Transactional(readOnly = false)
+    public void auditSave(OaEvection oaEvection) {
+
+        // 设置意见
+        oaEvection.getAct().setComment(("yes".equals(oaEvection.getAct().getFlag()) ? "[同意] " : "[驳回] ") + oaEvection.getAct().getComment());
+
+        // 对不同环节的业务逻辑进行操作
+        String taskDefKey = oaEvection.getAct().getTaskDefKey();
+
+        //发送通知
+        WorkProjectNotify notify = new WorkProjectNotify();
+        notify.setNotifyId(oaEvection.getId());
+        notify.setCompanyId(UserUtils.getSelectCompany().getId());
+        notify.setType("26");
+        notify.setStatus("0");
+        notify.setNotifyRole("");
+
+        //业务逻辑对应的条件表达式
+        String exp = "";
+        // 审核环节
+        if ("audit1".equals(taskDefKey)) {
+            exp = "pass";
+        } else if ("audit2".equals(taskDefKey)) {
+            exp = "pass";
+        } else if ("audit3".equals(taskDefKey)) {
+            exp = "pass";
+        } else if ("audit4".equals(taskDefKey)) {
+            exp = "pass";
+        } else if ("audit5".equals(taskDefKey)) {
+            exp = "pass";
+        } else if ("apply_end".equals(taskDefKey)) {
+            exp = "pass";
+        }
+        // 未知环节,直接返回
+        else {
+            return;
+        }
+
+        // 提交流程任务
+        Map<String, Object> vars = Maps.newHashMap();
+        vars.put(exp, "yes".equals(oaEvection.getAct().getFlag()) ? false : true);
+
+        // 提交流程任务
+        actTaskService.complete(oaEvection.getAct().getTaskId(), oaEvection.getAct().getProcInsId(), oaEvection.getAct().getComment(), vars);
+        boolean state = actTaskService.isProcessEnd(oaEvection.getAct().getProcInsId());
+        oaEvection.setStatus("2");
+        if (!state) {
+            if ("yes".equals(oaEvection.getAct().getFlag())) {
+                oaEvection.setStatus("3");
+            } else {
+                oaEvection.setStatus("4");
+            }
+        }
+        oaEvection.preUpdate();
+        this.update(oaEvection);
+
+        //需在oaEvection更新后 操作:
+        //1待审核  2审核中 3通过 4驳回 5已撤销 6催办中
+        if ("2".equals(oaEvection.getStatus())) {
+            oaEvection = this.get(oaEvection.getId());
+            String userId = oaEvection.getVariables().get("assignee").toString();
+            if (StringUtils.isNotBlank(userId)) {
+                notify.setUser(UserUtils.get(userId));
+            }
+            notify.setTitle("您有新的出差申请待审批");
+            notify.setRemarks("待审批");
+            notify.setContent("出差申请--待审批");
+
+        } else if ("3".equals(oaEvection.getStatus())) {
+            notify.setUser(oaEvection.getCreateBy());
+            notify.setTitle("您的出差申请已通过");
+            notify.setRemarks("待通知");
+            notify.setContent(oaEvection.getAct().getComment());
+        } else if ("4".equals(oaEvection.getStatus())) {
+            notify.setUser(oaEvection.getCreateBy());
+            notify.setTitle("您的出差申请被驳回");
+            notify.setRemarks("待通知");
+            notify.setContent(oaEvection.getAct().getComment());
+        }
+        workProjectNotifyService.save(notify);
+
+        //更新审核人的阅读状态
+        WorkProjectNotify notify2 = new WorkProjectNotify();
+        notify2.setUser(UserUtils.getUser());
+        notify2.setNotifyId(oaEvection.getId());
+        workProjectNotifyService.readByNotifyIdAndNotifyUser(notify2);
+
+        //抄送
+        if ("3".equals(oaEvection.getStatus()) || "4".equals(oaEvection.getStatus())) {
+            ApprovalCopy approvalCopy = approvalCopyService.getByApprovalId(oaEvection.getId());
+            if (approvalCopy != null && StringUtils.isNotBlank(approvalCopy.getCCId())) {
+                WorkProjectNotify notify1 = new WorkProjectNotify();
+                notify1.setNotifyId(oaEvection.getId());
+                notify1.setCompanyId(UserUtils.getSelectCompany().getId());
+                notify1.setType("26");
+                notify1.setStatus("0");
+                notify1.setNotifyRole("");
+                notify1.setContent(oaEvection.getAct().getComment());
+                String[] ccIds = approvalCopy.getCCId().split(",");
+                for (String ccId : ccIds) {
+                    if (StringUtils.isNotBlank(ccId)) {
+                        notify1.setUser(new User(ccId));
+                        if ("3".equals(oaEvection.getStatus())) {
+                            notify1.setTitle(UserUtils.get(oaEvection.getCreateBy().getId()).getName() + "的出差申请已通过");
+                        }
+                        if ("4".equals(oaEvection.getStatus())) {
+                            notify1.setTitle(UserUtils.get(oaEvection.getCreateBy().getId()).getName() + "的出差申请被驳回");
+                        }
+                        notify1.setRemarks("待通知");
+                        notify1.setId("");
+                        workProjectNotifyService.save(notify1);
+                    }
+                }
+            }
+        }
+    }
+
+    public Page<OaEvection> find(Page<OaEvection> page, OaEvection oaEvection) {
+
+        oaEvection.getSqlMap().put("dsf", dataScopeFilter(oaEvection.getCurrentUser(), "o", "u", "", MenuStatusEnum.OA_EVECTION.getValue()));
+
+        oaEvection.setPage(page);
+        page.setList(oaEvectionDao.findList(oaEvection));
+        for (OaEvection item : page.getList()) {
+            String processInstanceId = item.getProcessInstanceId();
+            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+            if (historicProcessInstance != null) {
+                item.setHistoricProcessInstance(historicProcessInstance);
+                item.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult());
+            } else {
+                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
+                if (processInstance != null) {
+                    item.setProcessInstance(processInstance);
+                    item.setProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult());
+                }
+            }
+            ProcessInstance processInstance = actTaskService.getProcIns(item.getProcessInstanceId());
+            if (processInstance != null) {
+                Task taskInfok = actTaskService.getCurrentTaskInfo(processInstance);
+                if (StringUtils.isNotBlank(taskInfok.getAssignee()) && taskInfok.getAssignee().equals(UserUtils.getUser().getId())) {
+                    item.setTask(taskInfok);
+                }
+            }
+        }
+        return page;
+    }
+
+    //启动流程
+    @Transactional(readOnly = false)
+    public boolean saveEvection(OaEvection oaEvection, MultipartFile[] this_upload_files) {
+        oaEvection.setStatus("1");
+        String approverId = "";
+        List<String> adds = oaEvection.getAdds();
+        for(int i = 0;i<adds.size();i++){
+            if(i + 1 == adds.size()){
+                approverId += adds.get(i);
+            }else{
+                approverId += adds.get(i) + ",";
+            }
+        }
+        oaEvection.setIds(approverId);
+        Map<String, Object> variables = Maps.newHashMap();
+        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+               /* String startTime = requestMap.get("startTime");//格式化时间
+                String endTime = requestMap.get("endTime");//格式化时间
+                String userId = requestMap.get("userId");
+
+                String address = requestMap.get("address"); // 出差地点
+                String dateCount = requestMap.get("dateCount"); // 出差天数
+                String reason = requestMap.get("reason"); // 出差原因
+
+                String approverId = requestMap.get("approverId");//审批人
+                String CCId = requestMap.get("CCId");//抄送人7
+                String delFlag="0"; //审核流程状态标记 0 待审核 1 审核完成
+                User user = new User(); //记录请假人的
+                OaEvection oaEvection = new OaEvection();*/
+        String type = "1";
+        String alias = "1";
+        List<String> assigneeList = new ArrayList<String>(); //分配任务的人员
+        if (approverId != null && !approverId.equals("")) {
+            if (!UserUtils.getUser().isAdmin() && approverId.contains(UserUtils.getUser().getId())) {
+                logger.error("启动出差流程失败:");
+                return false;
+            }
+            String[] approverIds = approverId.split(",");
+            for (int i = 0; i < approverIds.length; i++) {
+                assigneeList.add(approverIds[i]);
+            }
+            type = approverIds.length + "";
+            alias = approverIds[0];
+        }
+        variables.put("assigneeList", assigneeList);
+        variables.put("count", assigneeList.size());
+        User CC = new User();
+        CC.setId(oaEvection.getCCId());
+        User user = UserUtils.getUser();
+        oaEvection.setCreateBy(user);
+        oaEvection.setStatus("1");
+        oaEvection.setUpdateBy(user);
+        oaEvection.setDelFlag("0");
+        oaEvection.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+        oaEvection.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+        submit(oaEvection, variables, type);
+
+        if(this_upload_files!=null&&this_upload_files.length>0){
+            OSSClientUtil ossClientUtil = new OSSClientUtil();
+            for (int i = 0; i < this_upload_files.length; i++) {
+                MultipartFile file = this_upload_files[i];
+                if(file!=null && !file.isEmpty()&& file.getSize()>0){
+                    uploadFile(ossClientUtil,file,oaEvection,"73");
+                }
+            }
+        }
+
+        ApprovalCopy approvalCopy = new ApprovalCopy();
+        approvalCopy.setCCId(oaEvection.getCCId() == null ? "" : oaEvection.getCCId());
+        approvalCopy.setUserId(user.getId());
+        approvalCopy.setType("evection");
+        approvalCopy.setRemarks(oaEvection.getReason());
+        approvalCopy.setApprovalId(oaEvection.getId());
+        approvalCopy.setApproverId(approverId);
+        approvalCopy.setReadFlag("0");
+        approvalCopyService.save(approvalCopy);
+
+        //给抄送人、审批人发送通知
+        if (approvalCopy != null && org.apache.commons.lang3.StringUtils.isNotBlank(approvalCopy.getId())) {
+            String chaosongIds = approvalCopy.getCCId();//给所有抄送人发送通知
+            String shenpiIds = alias;//给审批流程的第一个人发送通知
+            this.sendNotify(chaosongIds, shenpiIds, approvalCopy.getApprovalId());
+            UserUtils.pushIm(alias,"申请人:" + user.getName() + ",出差申请 待审批!");
+            /*List<WebSocket> toUserConns = ChatServerPool.getWebSocketByUser(alias);
+            for (WebSocket toUserConn:toUserConns) {
+                String message = "{\"to\":\""+alias+"\"," +
+                        "\"msg\":\"审批信息 申请人:" + user.getName() + ",出差申请 待审批!\"," +
+                        "\"useType\":\"sys\"}";
+                ChatServerPool.sendMessageToUser(toUserConn, message);//同时向本人发送消息
+            }*/
+        }
+
+        String title = "审批";
+        String content = UserUtils.getUser().getName() + "的出差申请需要你审批";
+        String status = "待审批";
+        String remarks = "开始时间:" + oaEvection.getStartTime() + "\n"
+                + "结束时间:" + oaEvection.getEndTime() + "\n"
+                + "出差地点:" + oaEvection.getAddress();
+        Map extras = new HashMap();
+        extras.put("type", "4001");
+        extras.put("id", oaEvection.getId());
+        extras.put("procDefKey", "evection");
+
+        boolean b = JPushClientUtil.sendNotificationToAlias(title, content, extras, alias);
+        Pushinfo pushinfo = new Pushinfo();
+        pushinfo.setCurrentUser(UserUtils.getUser());
+        pushinfo.setRemarks(remarks);
+        pushinfo.setUserId(UserUtils.getUser().getId());
+        pushinfo.setType("4001");
+        pushinfo.setPushId(oaEvection.getId());
+        pushinfo.setTitle(title);
+        pushinfo.setStatus(status);
+        pushinfo.setContent(content);
+        pushinfo.setMobile("ios,android");
+        pushinfo.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+        pushinfo.setAddcontent("evection");
+        pushinfo.setPushUserId(alias);
+        pushinfo.setParentType("singleApproval");
+        pushinfoService.save(pushinfo);
+        return true;
+
+    }
+
+    @Transactional(readOnly = false)
+    public String uploadFile(OSSClientUtil ossClientUtil, MultipartFile file, OaEvection oaEvection, String flag) {
+        String fileName = file.getOriginalFilename();
+        String fileType = fileName.substring(fileName.lastIndexOf("."));
+        String url = ossClientUtil.uploadFile2OSS(file,"evection");
+        Workattachment workattachment = new Workattachment();
+        workattachment.setUrl(url);
+        workattachment.setType(fileType);
+        workattachment.setAttachmentName(fileName);
+        workattachment.setAttachmentUser(UserUtils.getUser().getId());
+        workattachment.setAttachmentId(oaEvection.getId());
+        workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+        workattachment.setAttachmentFlag(flag);
+        workattachmentService.save(workattachment);
+        return url;
+    }
+
+    @Transactional(readOnly = false)
+    public void sendNotify(String chaosongIds, String shenpiId, String goOutId) {
+        if (StringUtils.isNotBlank(goOutId)) {
+            if (StringUtils.isNotBlank(chaosongIds)) {
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setTitle(UserUtils.getUser().getName() + "发起了出差申请");
+                notify.setRemarks("待通知");
+                notify.setContent(UserUtils.getUser().getName() + "的出差申请");
+                notify.setNotifyRole("");
+                notify.setNotifyId(goOutId);
+                notify.setStatus("0");
+                notify.setCompanyId(UserUtils.getSelectCompany().getId());
+                notify.setType("26");
+                String[] arr = chaosongIds.split(",");
+                for (String id : arr) {
+                    if (StringUtils.isNotBlank(id)) {
+                        notify.setId("");
+                        notify.setUser(new User(id));
+                        workProjectNotifyService.save(notify);
+                    }
+                }
+            }
+            if (StringUtils.isNotBlank(shenpiId)) {
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setTitle("您有新的出差申请待审批");
+                notify.setRemarks("待审批");
+                notify.setContent("出差申请--待审批");
+                notify.setNotifyRole("");
+                notify.setUser(new User(shenpiId));
+                notify.setNotifyId(goOutId);
+                notify.setStatus("0");
+                notify.setCompanyId(UserUtils.getSelectCompany().getId());
+                notify.setType("26");
+                workProjectNotifyService.save(notify);
+            }
+        }
+    }
+
+    public List getCreateDateList(String companyId, String date) {
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("companyId", companyId);
+        map.put("date", date);
+        return oaEvectionDao.getCreateDateList(map);
+    }
+
+    public List<OaEvection> findByCompany2(OaEvection oaEvection, String date) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("evection", oaEvection);
+        map.put("date", date);
+        return oaEvectionDao.findByCompany2(map);
+    }
+
+    public List getCreateDateList1(String time) {
+        Map<String,String> map = new HashMap<String,String>();
+        map.put("userId",UserUtils.getUser().getId());
+        map.put("time",time);
+        return oaEvectionDao.getCreateDateList1(map);
+    }
+    public List<OaEvection> findByCompany1(String time){
+        Map<String,String> map = new HashMap<String,String>();
+        map.put("userId",UserUtils.getUser().getId());
+        map.put("time",time);
+        return oaEvectionDao.findByCompany1(map);
+    }
+
+    public List getCreateDateListAll(String time) {
+        Map<String,String> map = new HashMap<String,String>();
+        OaEvection w=new OaEvection();
+        map.put("sqlStr",dataScopeFilter(w.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OA_EVECTION.getValue()));
+        map.put("time",time);
+        return oaEvectionDao.getCreateDateListAll(map);
+    }
+    public List<OaEvection> findByCompanyAll(String time){
+        Map<String,String> map = new HashMap<String,String>();
+        OaEvection w=new OaEvection();
+        map.put("sqlStr",dataScopeFilter(w.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OA_EVECTION.getValue()));
+        map.put("time",time);
+        return oaEvectionDao.findByCompanyAll(map);
+    }
+
+    public List<OaEvection> findByManage(Map<String,Object> map) {
+        return oaEvectionDao.findByManage(map);
+    }
+    public List<OaEvection> findByCompanySelf(Map<String,Object> map) {
+        return oaEvectionDao.findByCompanySelf(map);
+    }
+}

+ 337 - 0
src/main/java/com/jeeplus/modules/oa_evection/web/oa_evection/OaEvectionController.java

@@ -0,0 +1,337 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oa_evection.web.oa_evection;
+
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActAuditService;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oa_evection.entity.oa_evection.OaEvection;
+import com.jeeplus.modules.oa_evection.service.oa_evection.OaEvectionService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 出差流程Controller
+ * @author 杨帆
+ * @version 2017-05-22
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oa_evection/oaEvection")
+public class OaEvectionController extends BaseController {
+
+    @Autowired
+    private OaEvectionService oaEvectionService;
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    protected RuntimeService runtimeService;
+
+    @Autowired
+    protected TaskService taskService;
+
+    @Autowired
+    private ActTaskService actTaskService;
+
+    @Autowired
+    private OfficeService officeService;
+    @Autowired
+    private WorkProjectNotifyService workProjectNotifyService;
+    @Autowired
+    private ActAuditService actAuditService;
+
+    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    @ModelAttribute
+    public OaEvection get(@RequestParam(required=false) String id){//,
+//			@RequestParam(value="act.procInsId", required=false) String procInsId) {
+        OaEvection oaEvection = null;
+        if (StringUtils.isNotBlank(id)){
+            oaEvection = oaEvectionService.get(id);
+//		}else if (StringUtils.isNotBlank(procInsId)){
+//			testAudit = testAuditService.getByProcInsId(procInsId);
+        }
+        if (oaEvection == null){
+            oaEvection = new OaEvection();
+        }
+        return oaEvection;
+    }
+
+
+    @RequiresPermissions(value={"oa:evection:view","oa:evection:add","oa:evection:edit"},logical= Logical.OR)
+    @RequestMapping(value = {"form"})
+    public String form(OaEvection oaEvection, Model model) {
+        String view = "oaEvectionForm";
+        // 查看审批申请单
+        if (StringUtils.isNotBlank(oaEvection.getId())){//.getAct().getProcInsId())){
+            // 环节编号
+            String taskDefKey = oaEvection.getAct().getTaskDefKey();
+            if (taskDefKey!=null) {
+                // 查看工单
+                if (oaEvection.getAct().isFinishTask()) {
+                    view = "oaEvectionView";
+                }
+                // 修改环节
+                else if ("apply_end".equals(taskDefKey)) {
+                    view = "oaEvectionAudit";
+                }
+                // 审核环节
+                else if ("audit1".equals(taskDefKey)) {
+                    if (StringUtils.isBlank(oaEvection.getAct().getStatus())){
+                        model.addAttribute("disabled","true");
+                    }else {
+                        model.addAttribute("disabled","false");
+                    }
+                    view = "oaEvectionAudit";
+                }
+                //
+                else if ("modifyApply".equals(taskDefKey)) {
+                    view = "oaEvectionForm";
+                }
+            }
+            if (org.apache.commons.lang3.StringUtils.isNotBlank(oaEvection.getName())){
+                if (oaEvection.getName().equals("view")){
+                    model.addAttribute("disabled","true");
+                    oaEvection.getAct().setProcInsId(oaEvection.getProcessInstanceId());
+                    view = "oaEvectionAudit";
+                }
+            }
+        }
+
+        model.addAttribute("oaEvection", oaEvection);
+        return "modules/oa_evection/"+view;
+    }
+
+    /**
+     * 启动出差流程
+     * @param oaEvection
+     */
+    @RequestMapping(value = "save", method = RequestMethod.POST)
+    public String save(OaEvection oaEvection, @RequestParam(value = "this_upload_files",required = false)MultipartFile[] this_upload_files, RedirectAttributes redirectAttributes) throws Exception {
+        if (StringUtils.isNotBlank(oaEvection.getId())) {
+            OaEvection t = oaEvectionService.get(oaEvection.getId());//从数据库取出记录的值
+            MyBeanUtils.copyBeanNotNull2Bean(oaEvection, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+            if (t.getStatus().equals("3") || t.getStatus().equals("4")){
+                addMessage(redirectAttributes, "已结束流程不能修改!");
+            }else {
+                oaEvectionService.save(t);
+            }
+        } else {
+            try{
+                boolean b = oaEvectionService.saveEvection(oaEvection,this_upload_files);
+                if (b) {
+                    addMessage(redirectAttributes, "出差申请已经提交");
+                } else {
+                    addMessage(redirectAttributes, "系统内部错误!");
+                }
+            }catch(Exception e){
+                logger.info("save e.getMessage()=" + e.getMessage());
+                addMessage(redirectAttributes, "系统内部错误!");
+            }
+        }
+        return "redirect:" + adminPath + "/oa_evection/oaEvection";
+    }
+
+
+    /**
+     * 工单执行(完成任务)
+     * @param oaEvection
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "saveAudit")
+    public String saveAudit(OaEvection oaEvection,Map<String, Object> vars, Model model, RedirectAttributes redirectAttributes) {
+       /* if (StringUtils.isBlank(oaEvection.getAct().getComment())){
+            addMessage(model, "请填写审核意见。");
+            return form(oaEvection, model);
+        }*/
+        //oaEvectionService.auditSave(oaEvection);
+        Act act = oaEvection.getAct();
+        AjaxJson json = actAuditService.saveAudit(act, act.getProcInsId(), "evection", oaEvection.getAct().getComment(), oaEvection.getId(), "2");
+        addMessage(redirectAttributes, json.getMsg());
+        if (oaEvection!=null && StringUtils.isNotBlank(oaEvection.getHome()) && oaEvection.getHome().equals("home")){
+            return "redirect:" + adminPath + "/home";
+        }
+        return "redirect:" + adminPath + "/oa_evection/oaEvection";
+    }
+
+    /**
+     * 读取所有流程
+     * @return
+     */
+    @RequiresPermissions("oa:evection:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(OaEvection oaEvection, HttpServletRequest request, HttpServletResponse response, Model model) {
+        User user = UserUtils.getUser();
+        if (!user.isAdmin()){
+            oaEvection.setCompanyId(user.getComId());
+            if (!UserUtils.isManager()){
+                oaEvection.setCreateBy(user);
+            }
+        }
+        Page<OaEvection> page = oaEvectionService.find(new Page<OaEvection>(request, response), oaEvection);
+        model.addAttribute("page", page);
+        return "modules/oa_evection/oaEvectionList";
+    }
+
+    /**
+     * 待办任务列表页面
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = {"oaEvectionTodoList"})
+    public String oaEvectionTodoList(Act act, HttpServletRequest request, HttpServletResponse response, Model model) {
+        act.setProcDefKey("evection");
+        List<Act> list = actTaskService.todoList(act);
+        Office office = UserUtils.getSelectCompany();
+        String companyId = office==null?"":office.getId();
+        List<OaEvection> lists = new ArrayList<OaEvection>();
+        for (Act a : list) {
+            OaEvection oaEvection = oaEvectionService.getByProcessInstanceId(a.getProcInsId());
+            if (oaEvection != null && oaEvection.getCompanyId().equals(companyId)) {
+                if (a.getVars().getMap().get("applyUserId")!=null) {
+                    User user = UserUtils.get(a.getVars().getMap().get("applyUserId").toString());
+                    if (user != null) {
+                        a.getVars().getMap().put("applyUserId", UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+                    }
+                }
+                oaEvection.setAct(a);
+                if (com.jeeplus.common.utils.StringUtils.isNotBlank(oaEvection.getId())){
+                    oaEvection.setName(officeService.get(companyId).getName());
+                }
+                lists.add(oaEvection);
+            }
+        }
+        model.addAttribute("list", lists);
+        return "modules/oa_evection/oaEvectionTodoList";
+    }
+
+    /**
+     * 已办任务
+     * @param act
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = {"oaEvectionHistoricList"})
+    public String oaEvectionHistoricList (Act act, HttpServletRequest request, HttpServletResponse response, Model model){
+        act.setProcDefKey("evection");
+        Page<Act> page = actTaskService.historicList(new Page<Act>(request, response), act);
+        List<Act> list = page.getList();
+        Office office = UserUtils.getSelectCompany();
+        String companyId = office==null?"":office.getId();
+        List<OaEvection> lists = new ArrayList<OaEvection>();
+        for (Act a : list) {
+            OaEvection oaEvection = oaEvectionService.getByProcessInstanceId(a.getHistTask().getProcessInstanceId());
+            if (oaEvection != null && oaEvection.getCompanyId().equals(companyId)) {
+                if (a.getVars().getMap().get("applyUserId")!=null){
+                    a.getVars().getMap().put("applyUserId",UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+                }
+                oaEvection.setAct(a);
+                if (com.jeeplus.common.utils.StringUtils.isNotBlank(oaEvection.getId())){
+                    oaEvection.setName(officeService.get(companyId).getName());
+                }
+                lists.add(oaEvection);
+            }
+        }
+        model.addAttribute("list", lists);
+
+        return "modules/oa_evection/oaEvectionHistoricList";
+    }
+
+    /**
+     * 审核信息
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "applyOnEvection")
+    public String applyOnCompany(Act act, HttpServletResponse response, Model model) {
+        // 获取流程XML上的表单KEY
+        String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
+        //logger.info("------formKeys:"+formKeys);
+        // 获取流程实例对象
+        if (act.getProcInsId() != null){
+            if(actTaskService.getProcIns(act.getProcInsId())!=null){
+                act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+            }else{
+                act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+            }
+        }
+        return "redirect:" + ActUtils.getFormUrl(formKey, act);
+    }
+
+    /**
+     * 出差申请撤销
+     * @param
+     * @return
+     */
+    @RequestMapping(value = "revoke")
+    public String revoke(HttpServletRequest request, HttpServletResponse response) {
+
+        HashMap<String, String> requestMap = findRequestMap(request);
+        String processInstanceId = requestMap.get("processInstanceId");
+        String id = requestMap.get("id");
+        String deleteReason = requestMap.get("reason");
+
+        AjaxJson j = new AjaxJson();
+        try {
+            OaEvection oaEvection = oaEvectionService.getById(id);
+            oaEvection.setStatus("5");
+            oaEvection.preUpdate();
+            oaEvectionService.update(oaEvection);
+            Map map = oaEvectionService.getEvectionById(id,"1");
+            j.put("data",map);
+            actTaskService.endProcessInstance(processInstanceId, deleteReason);
+            j.setMsg("撤销申请成功");
+
+            //撤销后,更改所有发送过的通知的阅读状态
+            WorkProjectNotify notify = new WorkProjectNotify();
+            notify.setNotifyId(oaEvection.getId());
+            workProjectNotifyService.readByNotifyId(notify);
+        }catch (Exception e){
+            j.setErrorCode("101");
+            logger.info(e.getMessage());
+            j.setMsg("撤销申请失败");
+            j.setSuccess(false);
+        }
+        return "redirect:" + adminPath + "/oa_evection/oaEvection";
+    }
+}

+ 31 - 0
src/main/java/com/jeeplus/modules/oaall/dao/OaAllDao.java

@@ -0,0 +1,31 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaall.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oaall.entity.OaAll;
+
+/**
+ * 通用审批功能DAO接口
+ * @author mpb
+ * @version 2018-01-11
+ */
+@MyBatisDao
+public interface OaAllDao extends CrudDao<OaAll> {
+
+    /**
+     * 更新流程实例ID
+     * @param oaAll
+     * @return
+     */
+    public int updateProcessInstanceId(OaAll oaAll);
+
+    /**
+     * 根据流程实例ID获取Leave
+     * @param processInstanceId
+     * @return
+     */
+    public OaAll getByProcessInstanceId(String processInstanceId);
+}

+ 232 - 0
src/main/java/com/jeeplus/modules/oaall/entity/OaAll.java

@@ -0,0 +1,232 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaall.entity;
+
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 通用审批功能Entity
+ * @author mpb
+ * @version 2018-01-11
+ */
+public class OaAll extends ActEntity<OaAll> {
+	
+	private static final long serialVersionUID = 1L;
+	private String applyContent;		// 申请内容
+	private String approveDetail;		// 审批详情
+	private String status;
+	private String ids;
+	private String CCId;
+	private String companyId;
+	private String officeId;
+	private String processInstanceId;
+	private String comment; //审核意见 目前只保存手机端审核
+	private List<String> adds = Lists.newArrayList();
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList();
+	private String files;
+	private String home;
+
+	private Date createDateStart;//搜索条件
+	private Date createDateEnd;
+	// 流程任务
+	private Task task;
+	private Map<String, Object> variables;
+	// 运行中的流程实例
+	private ProcessInstance processInstance;
+	// 历史的流程实例
+	private HistoricProcessInstance historicProcessInstance;
+	// 流程定义
+	private ProcessDefinition processDefinition;
+
+	public String getFiles() {
+		return files;
+	}
+
+	public void setFiles(String files) {
+		this.files = files;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public OaAll() {
+		super();
+	}
+
+	public Date getCreateDateStart() {
+		return createDateStart;
+	}
+
+	public void setCreateDateStart(Date createDateStart) {
+		this.createDateStart = createDateStart;
+	}
+
+	public Date getCreateDateEnd() {
+		return createDateEnd;
+	}
+
+	public void setCreateDateEnd(Date createDateEnd) {
+		this.createDateEnd = createDateEnd;
+	}
+
+	public OaAll(String id){
+		super(id);
+	}
+
+	public String getIds() {
+		return ids;
+	}
+
+	public void setIds(String ids) {
+		this.ids = ids;
+	}
+
+	public String getCCId() {
+		return CCId;
+	}
+
+	public void setCCId(String CCId) {
+		this.CCId = CCId;
+	}
+
+	public User getUser() {
+		return createBy;
+	}
+
+	public void setUser(User user) {
+		this.createBy = user;
+	}
+
+	@ExcelField(title="申请内容", align=2, sort=7)
+	public String getApplyContent() {
+		return applyContent;
+	}
+
+	public void setApplyContent(String applyContent) {
+		this.applyContent = applyContent;
+	}
+	
+	@ExcelField(title="审批详情", align=2, sort=8)
+	public String getApproveDetail() {
+		return approveDetail;
+	}
+
+	public void setApproveDetail(String approveDetail) {
+		this.approveDetail = approveDetail;
+	}
+
+	public String getStatus() {
+		return status;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+
+	public List<String> getAdds() {
+		return adds;
+	}
+
+	public void setAdds(List<String> adds) {
+		this.adds = adds;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+
+	public Task getTask() {
+		return task;
+	}
+
+	public void setTask(Task task) {
+		this.task = task;
+	}
+
+	public Map<String, Object> getVariables() {
+		return variables;
+	}
+
+	public void setVariables(Map<String, Object> variables) {
+		this.variables = variables;
+	}
+
+	public ProcessInstance getProcessInstance() {
+		return processInstance;
+	}
+
+	public void setProcessInstance(ProcessInstance processInstance) {
+		this.processInstance = processInstance;
+	}
+
+	public HistoricProcessInstance getHistoricProcessInstance() {
+		return historicProcessInstance;
+	}
+
+	public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
+		this.historicProcessInstance = historicProcessInstance;
+	}
+
+	public ProcessDefinition getProcessDefinition() {
+		return processDefinition;
+	}
+
+	public void setProcessDefinition(ProcessDefinition processDefinition) {
+		this.processDefinition = processDefinition;
+	}
+
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+	public String getHome() {
+		return home;
+	}
+
+	public void setHome(String home) {
+		this.home = home;
+	}
+}

+ 573 - 0
src/main/java/com/jeeplus/modules/oaall/service/OaAllService.java

@@ -0,0 +1,573 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaall.service;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.Collections3;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oaall.dao.OaAllDao;
+import com.jeeplus.modules.oaall.entity.OaAll;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 通用审批功能Service
+ * @author mpb
+ * @version 2018-01-11
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaAllService extends CrudService<OaAllDao, OaAll> {
+
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+
+	@Autowired
+	private RuntimeService runtimeService;
+	@Autowired
+	protected TaskService taskService;
+	@Autowired
+	protected HistoryService historyService;
+	@Autowired
+	protected RepositoryService repositoryService;
+	@Autowired
+	private IdentityService identityService;
+	@Autowired
+	private OaAllDao oaAllDao;
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+	@Autowired
+	private UserDao userDao;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+	@Autowired
+	private WorkattachmentService workattachmentService;
+
+	public OaAll get(String id) {
+		OaAll oaAll = oaAllDao.get(id);
+		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
+		workClientAttachment.setAttachmentId(id);
+		workClientAttachment.setAttachmentFlag("67");
+		List<WorkClientAttachment> list = workClientAttachmentDao.findList(workClientAttachment);
+		if(list.size() > 0){
+			oaAll.setWorkAttachments(list);
+		}
+		Map<String,Object> variables=null;
+		if(oaAll != null){
+			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(oaAll.getProcessInstanceId()).singleResult();
+			if(historicProcessInstance!=null) {
+				variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
+			} else {
+				variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(oaAll.getProcessInstanceId()).active().singleResult().getId());
+			}
+			oaAll.setVariables(variables);
+		}
+		return oaAll;
+	}
+	
+	public List<OaAll> findList(OaAll oaAll) {
+		return super.findList(oaAll);
+	}
+	
+	public Page<OaAll> findPage(Page<OaAll> page, OaAll oaAll) {
+		oaAll.getSqlMap().put("dsf", dataScopeFilter(oaAll.getCurrentUser(), "o", "u","s", MenuStatusEnum.OA_ALL.getValue()));
+		oaAll.setPage(page);
+		page.setList(findList(oaAll));
+		return page;
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(OaAll oaAll,Map<String, Object> variables) {
+		super.save(oaAll);
+
+		for (WorkClientAttachment workClientAttachment : oaAll.getWorkAttachments()){
+			if (workClientAttachment.getId() == null){
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())){
+				workClientAttachment.setAttachmentId(oaAll.getId());
+				workClientAttachment.setAttachmentFlag("67");
+				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())){
+					workClientAttachment.preInsert();
+					workClientAttachmentDao.insert(workClientAttachment);
+				}else{
+					workClientAttachment.preUpdate();
+					workClientAttachmentDao.update(workClientAttachment);
+				}
+			}else{
+				workClientAttachmentDao.delete(workClientAttachment);
+			}
+		}
+		// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+		identityService.setAuthenticatedUserId(oaAll.getCurrentUser().getId());
+		// 启动流程
+		String businessKey = oaAll.getId().toString();
+		variables.put("type", "allApprove");
+		variables.put("busId", businessKey);
+		variables.put("title", "通用审批");//设置标题;
+		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ActUtils.PD_ALLAPPROVE[0], businessKey, variables);
+		oaAll.setProcessInstance(processInstance);
+		// 更新流程实例ID
+		oaAll.setProcessInstanceId(processInstance.getId());
+		oaAllDao.updateProcessInstanceId(oaAll);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(OaAll oaAll) {
+		super.delete(oaAll);
+	}
+
+	@Transactional(readOnly = false)
+	public void sendNotify(String chaosongIds,String shenpiId,String oaLeaveId) {
+		if(StringUtils.isNotBlank(oaLeaveId)){
+			if(StringUtils.isNotBlank(chaosongIds)){
+				WorkProjectNotify notify = new WorkProjectNotify();
+				notify.setTitle(UserUtils.getUser().getName()+"发起了通用审批申请");
+				notify.setRemarks("待通知");
+				notify.setContent(UserUtils.getUser().getName()+"的通用审批申请");
+				notify.setNotifyRole("");
+				notify.setNotifyId(oaLeaveId);
+				notify.setStatus("0");
+				notify.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify.setType("32");
+				String[] arr = chaosongIds.split(",");
+				for (String id : arr){
+					if(StringUtils.isNotBlank(id)){
+						notify.setId("");
+						notify.setUser(new User(id));
+						workProjectNotifyService.save(notify);
+					}
+				}
+			}
+			if(StringUtils.isNotBlank(shenpiId)){
+				WorkProjectNotify notify = new WorkProjectNotify();
+				notify.setTitle("您有新的通用审批申请待审批");
+				notify.setRemarks("待审批");
+				notify.setContent("通用审批申请--待审批");
+				notify.setNotifyRole("");
+				notify.setUser(new User(shenpiId));
+				notify.setNotifyId(oaLeaveId);
+				notify.setStatus("0");
+				notify.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify.setType("32");
+				workProjectNotifyService.save(notify);
+			}
+		}
+	}
+
+
+	@Transactional(readOnly = false)
+	public void auditSave(OaAll oaAll) {
+		// 设置意见
+		oaAll.getAct().setComment(("yes".equals(oaAll.getAct().getFlag())?"[同意] ":"[驳回] ")+oaAll.getAct().getComment());
+		// 对不同环节的业务逻辑进行操作
+		String taskDefKey = oaAll.getAct().getTaskDefKey();
+		//发送通知
+		WorkProjectNotify notify = new WorkProjectNotify();
+		notify.setNotifyId(oaAll.getId());
+		notify.setCompanyId(UserUtils.getSelectCompany().getId());
+		notify.setType("32");
+		notify.setStatus("0");
+		notify.setNotifyRole("");
+
+		//业务逻辑对应的条件表达式
+		String exp = "";
+		// 审核环节
+		if ("audit1".equals(taskDefKey)){
+			exp = "pass";
+		} else if ("audit2".equals(taskDefKey)) {
+			exp = "pass";
+		} else if ("audit3".equals(taskDefKey)){
+			exp = "pass";
+		}else if ("audit4".equals(taskDefKey)){
+			exp = "pass";
+		}else if ("audit5".equals(taskDefKey)){
+			exp = "pass";
+		}else if("apply_end".equals(taskDefKey)){
+			exp = "pass";
+		}
+		// 未知环节,直接返回
+		else{
+			return;
+		}
+		// 提交流程任务
+		Map<String, Object> vars = Maps.newHashMap();
+		vars.put(exp, "yes".equals(oaAll.getAct().getFlag()) ? false : true);
+		// 提交流程任务
+		actTaskService.complete(oaAll.getAct().getTaskId(), oaAll.getAct().getProcInsId(), oaAll.getAct().getComment(), vars);
+		boolean state = actTaskService.isProcessEnd(oaAll.getAct().getProcInsId());
+		oaAll.setStatus("2");
+		if (!state){
+			if ("yes".equals(oaAll.getAct().getFlag())){
+				oaAll.setStatus("3");
+			}else {
+				oaAll.setStatus("4");
+			}
+		}
+		oaAll.preUpdate();
+		oaAllDao.update(oaAll);
+
+		//需在leave更新后 操作:
+		//1待审核  2审核中 3通过 4驳回 5已撤销 6催办中
+		if("2".equals(oaAll.getStatus())){
+			oaAll = this.get(oaAll.getId());
+			String userId = oaAll.getVariables().get("assignee").toString();
+			if(StringUtils.isNotBlank(userId)){
+				notify.setUser(UserUtils.get(userId));
+			}
+			notify.setTitle("您有新的通用审批申请待审批");
+			notify.setRemarks("待审批");
+			notify.setContent("通用审批申请--待审批");
+
+		}else if("3".equals(oaAll.getStatus())){
+			notify.setUser(oaAll.getCreateBy());
+			notify.setTitle("您的通用审批申请已通过");
+			notify.setRemarks("待通知");
+			notify.setContent(oaAll.getAct().getComment());
+		}else if("4".equals(oaAll.getStatus())){
+			notify.setUser(oaAll.getCreateBy());
+			notify.setTitle("您的通用审批申请被驳回");
+			notify.setRemarks("待通知");
+			notify.setContent(oaAll.getAct().getComment());
+		}
+		workProjectNotifyService.save(notify);
+
+		//更新审核人的阅读状态
+		WorkProjectNotify notify2 = new WorkProjectNotify();
+		notify2.setUser(UserUtils.getUser());
+		notify2.setNotifyId(oaAll.getId());
+		workProjectNotifyService.readByNotifyIdAndNotifyUser(notify2);
+
+		//抄送
+		if("3".equals(oaAll.getStatus()) || "4".equals(oaAll.getStatus())){
+			ApprovalCopy approvalCopy = approvalCopyService.getByApprovalId(oaAll.getId());
+			if(approvalCopy!=null && StringUtils.isNotBlank(approvalCopy.getCCId())){
+				WorkProjectNotify notify1= new WorkProjectNotify();
+				notify1.setNotifyId(oaAll.getId());
+				notify1.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify1.setType("32");
+				notify1.setStatus("0");
+				notify1.setNotifyRole("");
+				notify1.setContent(oaAll.getAct().getComment());
+				String[] ccIds = approvalCopy.getCCId().split(",");
+				for(String ccId : ccIds){
+					if(StringUtils.isNotBlank(ccId)){
+						notify1.setUser(new User(ccId));
+						if("3".equals(oaAll.getStatus())){
+							notify1.setTitle(UserUtils.get(oaAll.getCreateBy().getId()).getName()+"的通用审批申请已通过");
+						}
+						if("4".equals(oaAll.getStatus())){
+							notify1.setTitle(UserUtils.get(oaAll.getCreateBy().getId()).getName()+"的通用审批申请被驳回");
+						}
+						notify1.setRemarks("待通知");
+						notify1.setId("");
+						workProjectNotifyService.save(notify1);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * 获取流程详细Leave
+	 * @param processInstanceId
+	 */
+	@SuppressWarnings("unchecked")
+	public OaAll getByProcessInstanceId(String processInstanceId) {
+		OaAll oaAll = oaAllDao.getByProcessInstanceId(processInstanceId);
+		return oaAll;
+	}
+
+	/**
+	 * 获取流程详细及工作流参数
+	 * @param id
+	 */
+	@SuppressWarnings("unchecked")
+	public OaAll getById(String id) {
+		OaAll oaAll = oaAllDao.get(id);
+		return oaAll;
+	}
+
+	@Transactional(readOnly = false)
+	public void update(OaAll oaAll) {
+		oaAll.preUpdate();
+		oaAllDao.update(oaAll);
+	}
+
+	@Transactional(readOnly = false)
+	public Map getLeaveById(String id,String type) {
+
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		OaAll oaAll = this.getById(id);
+		Map<String,Object> map = Maps.newHashMap();
+		String officeName = "";
+		String officeId = "";
+		if(oaAll!=null){
+			User user = userDao.get(oaAll.getCreateBy());
+			if(user!=null){
+				map.put("userName", user.getName());
+				map.put("photo",user.getPhoto());
+				map.put("users", user.getId());
+				Office office = user.getOffice();
+				if(office!=null && office.getName()!=null){
+					officeName = office.getName();
+					officeId = office.getId();
+				}
+			}
+			map.put("createDate",oaAll.getCreateDate()==null?"":sdf.format(oaAll.getCreateDate()));
+			map.put("applyContent",oaAll.getApplyContent());
+			map.put("filePath",oaAll.getFiles());
+			List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(oaAll.getId(),"67");
+			String files = "";
+			if (workattachmentList!=null && workattachmentList.size()!=0){
+				for (Workattachment workattachment : workattachmentList){
+					files += workattachment.getUrl()+",";
+				}
+				if (files.length() > 1) {
+					files = files.substring(0, files.length() - 1);
+				}
+			}
+			map.put("files", files);
+			map.put("approveDetail",oaAll.getApproveDetail());
+			map.put("companyId",oaAll.getCompanyId());
+			map.put("officeName",officeName);
+			map.put("officeId",officeId);
+			map.put("approvalId",id);
+			map.put("status",oaAll.getStatus());
+			List<Act> list = actTaskService.histoicFlowList(oaAll.getProcessInstanceId(), "", "");
+			List<Act> list2 = actTaskService.toMyStartedList(oaAll.getProcessInstanceId());
+			if (list2!=null && list2.size()!=0){
+				Act act1 = list2.get(list2.size()-1);
+				map.put("taskId", act1.getTaskId());
+				map.put("taskName",act1.getTaskName());
+				map.put("procInsId", act1.getProcInsId());
+				map.put("procDefId", act1.getProcDefId());
+				map.put("actStatus", act1.getStatus()==null?"todo":act1.getStatus());
+				map.put("taskDefKey", act1.getTaskDefKey());
+				map.put("procDefKey", "allApprove");
+			}
+			List list1 = new ArrayList();
+			String approvalStatus = "0";
+			String assigneeName = "";
+			if (list!=null && list.size()!=0) {
+				if (list.get(0).getHistIns().getActivityName().contains("审批")) {
+					for (int i = list.size() - 1; i > -1; i--) {
+						Act act = list.get(i);
+						Map<String, Object> maps = new HashMap<String, Object>();
+						String state = "0";
+						String activityName = "";
+						if (act.getHistIns().getActivityName().contains("审批")) {
+							if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+								activityName = "已审批";
+								if (UserUtils.getUser().getName().equals(act.getAssigneeName())){
+									approvalStatus = "1";
+								}
+							} else {
+								activityName = "待审批";
+								state = "2";
+							}
+						} else {
+							activityName = act.getHistIns().getActivityName();
+						}
+						if (type.equals("1") || type.equals("2")) {
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(act.getAssigneeName()) ? "我" : act.getAssigneeName());
+						} else if (type.equals("3")) {
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", act.getAssigneeName());
+						}
+						maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+						maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+						maps.put("durationTime", act.getDurationTime());
+						maps.put("state", state);
+						maps.put("userId", act.getCurrentUser().getId());
+						list1.add(maps);
+					}
+				} else {
+					if (oaAll.getStatus().equals("4") || oaAll.getStatus().equals("3")){
+						for (int i = 0; i < list.size()-1; i++) {
+							Act act = list.get(i);
+							Map<String, Object> maps = new HashMap<String, Object>();
+							String state = "0";
+							String activityName = "";
+							if (act.getHistIns().getActivityName().contains("发起申请")) {
+								activityName = act.getHistIns().getActivityName();
+								assigneeName = act.getAssigneeName();
+							}else if (act.getHistIns().getActivityName().contains("审批")) {
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+									activityName = "已审批";
+									if (UserUtils.getUser().getName().equals(assigneeName)){
+										approvalStatus = "1";
+									}
+									if (i == (list.size()-2) && oaAll.getStatus().equals("4")){
+										activityName = "审核驳回";
+										state = "1";
+									}else if (i == (list.size()-2) && oaAll.getStatus().equals("3")){
+										activityName = "审核成功";
+									}
+								} else {
+									activityName = "待审批";
+									state = "2";
+								}
+							}
+							else {
+								activityName = act.getHistIns().getActivityName();
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+							}
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+							maps.put("durationTime", act.getDurationTime());
+							maps.put("state", state);
+							maps.put("userId", act.getCurrentUser().getId());
+							list1.add(maps);
+						}
+					}else {
+						for (int i = 0; i < list.size(); i++) {
+							Act act = list.get(i);
+							Map<String, Object> maps = new HashMap<String, Object>();
+							String state = "0";
+							String activityName = "";
+							if (act.getHistIns().getActivityName().contains("发起申请")) {
+								activityName = act.getHistIns().getActivityName();
+								assigneeName = act.getAssigneeName();
+							}else if (act.getHistIns().getActivityName().contains("审批")) {
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+									activityName = "已审批";
+									if (UserUtils.getUser().getName().equals(assigneeName)){
+										approvalStatus = "1";
+									}
+								} else {
+									activityName = "待审批";
+									state = "2";
+								}
+							}
+							else {
+								activityName = act.getHistIns().getActivityName();
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+							}
+							if (oaAll.getStatus().equals("5") && i == list.size() - 1) {
+								activityName = "已撤销";
+								state = "1";
+							}
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+							maps.put("durationTime", act.getDurationTime());
+							maps.put("state", state);
+							maps.put("userId", act.getCurrentUser().getId());
+							list1.add(maps);
+						}
+					}
+				}
+			}
+			map.put("approvalStatus", approvalStatus);
+			ApprovalCopy approvalCopy = new ApprovalCopy();
+			approvalCopy.setApprovalId(id);
+			List<ApprovalCopy> approvalCopyList = approvalCopyService.findList(approvalCopy);
+			String CCName = "";
+			String CCId = "";
+			Boolean readFlag = false;
+			if (approvalCopyList!=null && approvalCopyList.size()!=0) {
+				ApprovalCopy approvalCopy1 = approvalCopyList.get(0);
+				CCId = approvalCopy1.getCCId();
+				String[] CCid = approvalCopy1.getCCId().split(",");
+				readFlag = approvalCopy1.getReadFlag().equals("0");
+				if (type.equals("3") && readFlag){
+					approvalCopy1.setReadFlag("1");
+					approvalCopyService.save(approvalCopy1);
+				}
+				for (String userId : CCid) {
+					User CCUser = UserUtils.get(userId);
+					if (CCUser != null) {
+						CCName = CCUser.getName() + ",";
+					}
+				}
+				if (CCName.length() > 1) {
+					CCName = CCName.substring(0, CCName.length() - 1);
+				} else {
+					CCName = "";
+				}
+			}
+
+			map.put("nameCopy",CCName);
+			map.put("CCId",CCId);
+			map.put("process",list1);
+		}
+		return map;
+	}
+	@Transactional(readOnly = false)
+	public void saveFile(OaAll oaAll) {
+		if (StringUtils.isBlank(oaAll.getId())){
+			oaAll.preInsert();
+			oaAllDao.insert(oaAll);
+		}else{
+			oaAll.preUpdate();
+			oaAllDao.update(oaAll);
+		}
+	}
+
+	//APP端使用,一次上传一个
+	@Transactional(readOnly = false)
+	public String uploadFile(OSSClientUtil ossClientUtil, MultipartFile file, OaAll oaAll, String flag) {
+		String fileName = file.getOriginalFilename();
+		String fileType = fileName.substring(fileName.lastIndexOf("."));
+		String url = ossClientUtil.uploadFile2OSS(file,"oaAll");
+		Workattachment workattachment = new Workattachment();
+		workattachment.setUrl(url);
+		workattachment.setAttachmentName(fileName);
+		workattachment.setType(fileType);
+		workattachment.setAttachmentId(oaAll.getId());
+		workattachment.setAttachmentUser(UserUtils.getUser().getId());
+		workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+		workattachment.setAttachmentFlag(flag);
+		workattachmentService.save(workattachment);
+		return url;
+	}
+}

+ 518 - 0
src/main/java/com/jeeplus/modules/oaall/web/OaAllController.java

@@ -0,0 +1,518 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaall.web;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.websocket.onchat.ChatServerPool;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActAuditService;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.oaall.entity.OaAll;
+import com.jeeplus.modules.oaall.service.OaAllService;
+import com.jeeplus.modules.pushinfo.entity.Pushinfo;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.TaskService;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.java_websocket.WebSocket;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 通用审批功能Controller
+ * @author mpb
+ * @version 2018-01-11
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oaall/oaAll")
+public class OaAllController extends BaseController {
+
+	@Autowired
+	private OaAllService oaAllService;
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+	@Autowired
+	private PushinfoService pushinfoService;
+	@Autowired
+	protected TaskService taskService;
+	@Autowired
+	protected HistoryService historyService;
+	@Autowired
+	protected RepositoryService repositoryService;
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private ActAuditService actAuditService;
+	
+	@ModelAttribute
+	public OaAll get(@RequestParam(required=false) String id) {
+		OaAll entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = oaAllService.get(id);
+		}
+		if (entity == null){
+			entity = new OaAll();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 通用审批功能列表页面
+	 */
+	@RequiresPermissions("oaall:oaAll:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OaAll oaAll, HttpServletRequest request, HttpServletResponse response, Model model) {
+		oaAll.setOfficeId(UserUtils.getSelectOffice().getId());
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()){
+			oaAll.setCompanyId(user.getComId());
+			if (!UserUtils.isManager()){
+				oaAll.setCreateBy(user);
+			}
+		}
+		Page<OaAll> page = oaAllService.findPage(new Page<OaAll>(request, response), oaAll);
+		model.addAttribute("page", page);
+		return "modules/oaall/oaAllList";
+	}
+
+	/**
+	 * 查看,增加,编辑通用审批功能表单页面
+	 */
+	@RequiresPermissions(value={"oaall:oaAll:view","oaall:oaAll:add","oaall:oaAll:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(OaAll oaAll, Model model,HttpServletRequest request) {
+		String view = "oaAllForm";
+		String tabId = request.getParameter("tabId");
+		if("0".equals(tabId)){
+			view = "oaAllView";
+		}
+		// 环节编号
+		String taskDefKey = oaAll.getAct().getTaskDefKey();
+		// 审核环节
+		if ("audit1".equals(taskDefKey)){
+			if (org.apache.commons.lang3.StringUtils.isBlank(oaAll.getAct().getStatus())){
+				model.addAttribute("disabled","true");
+				oaAll.getAct().setProcInsId(oaAll.getProcessInstanceId());
+			}else {
+				model.addAttribute("disabled","false");
+			}
+			view = "oaAllAudit";
+		}else if ("apply_end".equals(taskDefKey)){
+			view = "oaAllAudit";
+		}
+		//
+		else if ("modifyApply".equals(taskDefKey)){
+			view = "oaAllForm";
+		}
+
+		model.addAttribute("oaAll", oaAll);
+		return "modules/oaall/" + view;
+	}
+
+	/**
+	 * 保存通用审批功能
+	 */
+	@RequiresPermissions(value={"oaall:oaAll:add","oaall:oaAll:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OaAll oaAll, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (StringUtils.isNotBlank(oaAll.getId())) {
+			OaAll t = oaAllService.get(oaAll.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(oaAll, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			if (t.getStatus().equals("3") || t.getStatus().equals("4")){
+				addMessage(redirectAttributes, "已结束流程不能修改!");
+			}else {
+				oaAllService.save(t);
+			}
+		} else {
+			try {
+				oaAll.setStatus("1");
+				String approverId = "";
+				List<String> adds = oaAll.getAdds();
+				for(int i = 0;i<adds.size();i++){
+					if(i + 1 == adds.size()){
+						approverId += adds.get(i);
+					}else{
+						approverId += adds.get(i) + ",";
+					}
+				}
+				oaAll.setIds(approverId);
+
+				Map<String, Object> variables = Maps.newHashMap();
+				String alias = "1";
+				List<String> assigneeList = new ArrayList<String>(); //分配任务的人员
+				if (approverId != null && !approverId.equals("")) {
+					if (!UserUtils.getUser().isAdmin() && approverId.contains(UserUtils.getUser().getId())) {
+						logger.error("启动通用审批失败:");
+						addMessage(redirectAttributes, "申请失败,审批人不能为本人!");
+						return "redirect:" + adminPath + "/oaall/oaAll";
+					}
+					String[] approverIds = approverId.split(",");
+					for (int i = 0; i < approverIds.length; i++) {
+						assigneeList.add(approverIds[i]);
+					}
+					alias = approverIds[0];
+				}
+				variables.put("assigneeList", assigneeList);
+				variables.put("count", assigneeList.size());
+				User CC = new User();
+				CC.setId(oaAll.getCCId());
+				User user = UserUtils.getUser();
+				oaAll.setUser(user);
+				oaAll.setCreateBy(user);
+				oaAll.setUpdateBy(user);
+				oaAll.setStatus("1");
+				oaAll.setDelFlag("0");
+				oaAll.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				oaAll.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+				oaAllService.save(oaAll, variables);
+				ApprovalCopy approvalCopy = new ApprovalCopy();
+				approvalCopy.setCCId(oaAll.getCCId());
+				approvalCopy.setUserId(user.getId());
+				approvalCopy.setType("allApprove");
+				approvalCopy.setApprovalId(oaAll.getId());
+				approvalCopy.setApproverId(approverId);
+				approvalCopy.setReadFlag("0");
+				approvalCopyService.save(approvalCopy);
+
+				//给抄送人、审批人发送通知
+				if(approvalCopy!=null && org.apache.commons.lang3.StringUtils.isNotBlank(approvalCopy.getId())){
+					String chaosongIds = approvalCopy.getCCId();//给所有抄送人发送通知
+					String shenpiIds = alias;//给审批流程的第一个人发送通知
+					oaAllService.sendNotify(chaosongIds,shenpiIds,approvalCopy.getApprovalId());
+					UserUtils.pushIm(alias,"申请人 "+user.getName() + ",通用审批申请 待审批!");
+					/*List<WebSocket> toUserConns = ChatServerPool.getWebSocketByUser(alias);
+					for (WebSocket toUserConn:toUserConns) {
+						String message = "{\"to\":\""+alias+"\"," +
+								"\"msg\":\"审批信息 申请人:" + user.getName() + ",通用审批申请 待审批!\"," +
+								"\"useType\":\"sys\"}";
+						ChatServerPool.sendMessageToUser(toUserConn, message);//同时向本人发送消息
+					}*/
+				}
+
+
+				//推送
+				String title = "审批";
+				String content = UserUtils.getUser().getName() + "的通用审批申请需要你审批";
+				String status = "待审批";
+				String remarks = "通用审批申请内容类型:" + oaAll.getApplyContent();
+				Map extras = new HashMap();
+				extras.put("type", "4001");
+				extras.put("id", oaAll.getId());
+				extras.put("procDefKey", "oaApprove");
+
+				boolean b = JPushClientUtil.sendNotificationToAlias(title, content, extras, alias);
+				Pushinfo pushinfo = new Pushinfo();
+				pushinfo.setCurrentUser(UserUtils.getUser());
+				pushinfo.setRemarks(remarks);
+				pushinfo.setUserId(UserUtils.getUser().getId());
+				pushinfo.setType("4001");
+				pushinfo.setPushId(oaAll.getId());
+				pushinfo.setTitle(title);
+				pushinfo.setContent(content);
+				pushinfo.setStatus(status);
+				pushinfo.setAddcontent("allApprove");
+				pushinfo.setPushUserId(alias);
+				pushinfo.setParentType("singleApproval");
+				pushinfo.setMobile("ios,android");
+				pushinfo.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				pushinfoService.save(pushinfo);
+				if (b) {
+					addMessage(redirectAttributes, "通用审批申请已经提交");
+				} else {
+					logger.error("启动通用审批申请流程失败:");
+					addMessage(redirectAttributes, "请假申请失败,通用审批申请推送失败!");
+					return "redirect:" + adminPath + "/oaall/oaAll";
+				}
+			} catch (Exception e) {
+				logger.error("启动通用审批流程失败:", e);
+				addMessage(redirectAttributes, "系统内部错误!");
+			}
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaall/oaAll/?repage";
+	}
+	
+	/**
+	 * 删除通用审批功能
+	 */
+	@RequiresPermissions("oaall:oaAll:del")
+	@RequestMapping(value = "delete")
+	public String delete(OaAll oaAll, RedirectAttributes redirectAttributes) {
+		oaAllService.delete(oaAll);
+		addMessage(redirectAttributes, "删除通用审批功能成功");
+		return "redirect:"+Global.getAdminPath()+"/oaall/oaAll/?repage";
+	}
+	
+	/**
+	 * 批量删除通用审批功能
+	 */
+	@RequiresPermissions("oaall:oaAll:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			oaAllService.delete(oaAllService.get(id));
+		}
+		addMessage(redirectAttributes, "删除通用审批功能成功");
+		return "redirect:"+Global.getAdminPath()+"/oaall/oaAll/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("oaall:oaAll:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(OaAll oaAll, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "通用审批功能"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<OaAll> page = oaAllService.findPage(new Page<OaAll>(request, response, -1), oaAll);
+    		new ExportExcel("通用审批功能", OaAll.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出通用审批功能记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaall/oaAll/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("oaall:oaAll:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<OaAll> list = ei.getDataList(OaAll.class);
+			for (OaAll oaAll : list){
+				try{
+					oaAllService.save(oaAll);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条通用审批功能记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条通用审批功能记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入通用审批功能失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaall/oaAll/?repage";
+    }
+	
+	/**
+	 * 下载导入通用审批功能数据模板
+	 */
+	@RequiresPermissions("oaall:oaAll:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "通用审批功能数据导入模板.xlsx";
+    		List<OaAll> list = Lists.newArrayList(); 
+    		new ExportExcel("通用审批功能数据", OaAll.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaall/oaAll/?repage";
+    }
+
+
+	/**
+	 * 工单执行(完成任务)
+	 * @param
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "saveAudit")
+	public String saveAudit(OaAll oaAll, Model model) {
+		//oaAllService.auditSave(oaAll);
+		Act act = oaAll.getAct();
+		actAuditService.saveAudit(act, act.getProcInsId(), "allApprove", oaAll.getAct().getComment(), oaAll.getId(), "2");
+		if (oaAll!=null && org.apache.commons.lang3.StringUtils.isNotBlank(oaAll.getHome()) && oaAll.getHome().equals("home")){
+			return "redirect:" + adminPath + "/home";
+		}
+		return "redirect:" + adminPath + "/oa/leave";
+	}
+
+
+	/**
+	 * 待办任务列表页面
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"leaveTodoList"})
+	public String leaveTodoList(Act act, HttpServletRequest request, HttpServletResponse response, Model model) {
+		act.setProcDefKey("allApprove");
+		List<Act> list = actTaskService.todoList(act);
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<OaAll> lists = new ArrayList<OaAll>();
+		for (Act a : list) {
+			OaAll oaAll = oaAllService.getByProcessInstanceId(a.getProcInsId());
+			if (oaAll != null && oaAll.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					User user = UserUtils.get(a.getVars().getMap().get("applyUserId").toString());
+					if (user!=null) {
+						a.getVars().getMap().put("applyUserId", UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+					}
+				}
+				oaAll.setAct(a);
+//				if (com.jeeplus.common.utils.StringUtils.isNotBlank(oaAll.getId())){
+//					oaAll.setName(officeService.get(oaAll.getCompanyId()).getName());
+//				}
+				lists.add(oaAll);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oaall/oaAllTodoList";
+	}
+
+
+	/**
+	 * 已办任务
+	 * @param act
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"leaveHistoricList"})
+	public String leaveHistoricList (Act act, HttpServletRequest request, HttpServletResponse response, Model model){
+		act.setProcDefKey("allApprove");
+		Page<Act> page = actTaskService.historicList(new Page<Act>(request, response), act);
+		List<Act> list = page.getList();
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<OaAll> lists = new ArrayList<OaAll>();
+		for (Act a : list) {
+			OaAll oaAll = oaAllService.getByProcessInstanceId(a.getHistTask().getProcessInstanceId());
+			if (oaAll != null && oaAll.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					a.getVars().getMap().put("applyUserId",UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+				}
+				oaAll.setAct(a);
+//				if (StringUtils.isNotBlank(a.getId())){
+//					oaAll.setName(officeService.get(oaAll.getCompanyId()).getName());
+//				}
+//				if (oaAll.getCreateDate()!=null){
+//					oaAll.setTime(sdf.format(oaAll.getCreateDate()));
+//				}
+				lists.add(oaAll);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oaall/oaAllHistoricList";
+	}
+	/**
+	 * 审核企业信息
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "applyOnLeave")
+	public String applyOnCompany(Act act, HttpServletResponse response, Model model) {
+		// 获取流程XML上的表单KEY
+		//String formKey = "/oa/leave/applyOnLeave";
+		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
+		//logger.info("------formKeys:"+formKeys);
+		// 获取流程实例对象
+		if (act.getProcInsId() != null){
+			if(actTaskService.getProcIns(act.getProcInsId())!=null){
+				act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+			}else{
+				act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+			}
+		}
+		return "redirect:" + ActUtils.getFormUrl(formKey, act);
+	}
+
+	@RequestMapping(value = "getProcess")
+	public String getProcess(OaAll oaAll, Model model) {
+		model.addAttribute("processInstanceId", oaAll.getProcessInstanceId());
+		return "modules/oaall/oaAllTrack";
+
+	}
+
+	/**
+	 * 请假申请撤销
+	 * @param
+	 * @return
+	 */
+	@RequestMapping(value = "revoke")
+	public String revoke(HttpServletRequest request, HttpServletResponse response) {
+
+		HashMap<String, String> requestMap = findRequestMap(request);
+		String processInstanceId = requestMap.get("processInstanceId");
+		String id = requestMap.get("id");
+		AjaxJson j = new AjaxJson();
+		try {
+			OaAll oaAll = oaAllService.getById(id);
+			oaAll.setStatus("5");
+			oaAll.preUpdate();
+			oaAllService.update(oaAll);
+			Map map = oaAllService.getLeaveById(id,"1");
+			j.put("data",map);
+			actTaskService.endProcessInstance(processInstanceId, "");
+			j.setMsg("撤销申请成功");
+
+			//撤销后,更改所有发送过的通知的阅读状态
+			WorkProjectNotify notify = new WorkProjectNotify();
+			notify.setNotifyId(oaAll.getId());
+			workProjectNotifyService.readByNotifyId(notify);
+		}catch (Exception e){
+			j.setErrorCode("101");
+			logger.info(e.getMessage());
+			j.setMsg("撤销申请失败");
+			j.setSuccess(false);
+		}
+		return "redirect:" + adminPath + "/oaall/oaAll?repage";
+	}
+}

+ 31 - 0
src/main/java/com/jeeplus/modules/oabuy/dao/OaBuyDao.java

@@ -0,0 +1,31 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oabuy.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oabuy.entity.OaBuy;
+
+/**
+ * 采购申请DAO接口
+ * @author liuw
+ * @version 2018-01-16
+ */
+@MyBatisDao
+public interface OaBuyDao extends CrudDao<OaBuy> {
+
+    /**
+     * 更新流程实例ID
+     * @param oaBuy
+     * @return
+     */
+    public int updateProcessInstanceId(OaBuy oaBuy);
+
+    /**
+     * 根据流程实例ID获取Leave
+     * @param processInstanceId
+     * @return
+     */
+    public OaBuy getByProcessInstanceId(String processInstanceId);
+}

+ 274 - 0
src/main/java/com/jeeplus/modules/oabuy/entity/OaBuy.java

@@ -0,0 +1,274 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oabuy.entity;
+
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.buydetails.entity.BuyDetails;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 采购申请Entity
+ * @author liuw
+ * @version 2018-01-16
+ */
+public class OaBuy extends ActEntity<OaBuy> {
+	
+	private static final long serialVersionUID = 1L;
+	private String status;		// 申请状态
+	private String companyId;		// 公司
+	private String officeId;		// 部门
+	private String processInstanceId;		// 流程实例编号
+	private String applyContent;		// 申请事由
+	private String buySort;		// 采购类型
+	private Date deliverDate;		// 交付日期
+	private String payStyle;		// 支付方式
+	private String totalPrice;       //总价格
+	private String ids;
+	private String CCId;
+	private String comment; //审核意见 目前只保存手机端审核
+	private List<String> adds = Lists.newArrayList();
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList();
+	private List<BuyDetails> buyDetailsList = Lists.newArrayList();		// 子表列表
+	private Date createDateStart;//搜索条件
+	private Date createDateEnd;
+	private String files;
+	private String home;
+	// 流程任务
+	private Task task;
+	private Map<String, Object> variables;
+	// 运行中的流程实例
+	private ProcessInstance processInstance;
+	// 历史的流程实例
+	private HistoricProcessInstance historicProcessInstance;
+	// 流程定义
+	private ProcessDefinition processDefinition;
+
+	public Date getCreateDateStart() {
+		return createDateStart;
+	}
+
+	public void setCreateDateStart(Date createDateStart) {
+		this.createDateStart = createDateStart;
+	}
+
+	public Date getCreateDateEnd() {
+		return createDateEnd;
+	}
+
+	public void setCreateDateEnd(Date createDateEnd) {
+		this.createDateEnd = createDateEnd;
+	}
+
+	public String getFiles() {
+		return files;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public void setFiles(String files) {
+		this.files = files;
+	}
+
+	public List<BuyDetails> getBuyDetailsList() {
+		return buyDetailsList;
+	}
+
+	public void setBuyDetailsList(List<BuyDetails> buyDetailsList) {
+		this.buyDetailsList = buyDetailsList;
+	}
+
+	public String getTotalPrice() {
+		return totalPrice;
+	}
+
+	public void setTotalPrice(String totalPrice) {
+		this.totalPrice = totalPrice;
+	}
+
+	public String getIds() {
+		return ids;
+	}
+
+	public void setIds(String ids) {
+		this.ids = ids;
+	}
+
+	public String getCCId() {
+		return CCId;
+	}
+
+	public void setCCId(String CCId) {
+		this.CCId = CCId;
+	}
+
+	public List<String> getAdds() {
+		return adds;
+	}
+
+	public void setAdds(List<String> adds) {
+		this.adds = adds;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+	public User getUser() {
+		return createBy;
+	}
+
+	public void setUser(User user) {
+		this.createBy = user;
+	}
+	public Task getTask() {
+		return task;
+	}
+
+	public void setTask(Task task) {
+		this.task = task;
+	}
+
+	public Map<String, Object> getVariables() {
+		return variables;
+	}
+
+	public void setVariables(Map<String, Object> variables) {
+		this.variables = variables;
+	}
+
+	public ProcessInstance getProcessInstance() {
+		return processInstance;
+	}
+
+	public void setProcessInstance(ProcessInstance processInstance) {
+		this.processInstance = processInstance;
+	}
+
+	public HistoricProcessInstance getHistoricProcessInstance() {
+		return historicProcessInstance;
+	}
+
+	public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
+		this.historicProcessInstance = historicProcessInstance;
+	}
+
+	public ProcessDefinition getProcessDefinition() {
+		return processDefinition;
+	}
+
+	public void setProcessDefinition(ProcessDefinition processDefinition) {
+		this.processDefinition = processDefinition;
+	}
+
+	public OaBuy() {
+		super();
+	}
+
+	public OaBuy(String id){
+		super(id);
+	}
+
+	@ExcelField(title="申请状态", align=2, sort=7)
+	public String getStatus() {
+		return status;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+	
+	@ExcelField(title="公司", align=2, sort=8)
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+	
+	@ExcelField(title="部门", align=2, sort=9)
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+	
+	@ExcelField(title="流程实例编号", align=2, sort=10)
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+	
+	@ExcelField(title="申请事由", align=2, sort=11)
+	public String getApplyContent() {
+		return applyContent;
+	}
+
+	public void setApplyContent(String applyContent) {
+		this.applyContent = applyContent;
+	}
+	
+	@ExcelField(title="采购类型", dictType="", align=2, sort=12)
+	public String getBuySort() {
+		return buySort;
+	}
+
+	public void setBuySort(String buySort) {
+		this.buySort = buySort;
+	}
+	
+	@ExcelField(title="交付日期", align=2, sort=13)
+	public Date getDeliverDate() {
+		return deliverDate;
+	}
+
+	public void setDeliverDate(Date deliverDate) {
+		this.deliverDate = deliverDate;
+	}
+	
+	@ExcelField(title="支付方式", dictType="", align=2, sort=14)
+	public String getPayStyle() {
+		return payStyle;
+	}
+
+	public void setPayStyle(String payStyle) {
+		this.payStyle = payStyle;
+	}
+
+
+	public String getHome() {
+		return home;
+	}
+
+	public void setHome(String home) {
+		this.home = home;
+	}
+}

+ 627 - 0
src/main/java/com/jeeplus/modules/oabuy/service/OaBuyService.java

@@ -0,0 +1,627 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oabuy.service;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.Collections3;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.buydetails.dao.BuyDetailsDao;
+import com.jeeplus.modules.buydetails.entity.BuyDetails;
+import com.jeeplus.modules.buydetails.service.BuyDetailsService;
+import com.jeeplus.modules.oabuy.dao.OaBuyDao;
+import com.jeeplus.modules.oabuy.entity.OaBuy;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 采购申请Service
+ * @author liuw
+ * @version 2018-01-16
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaBuyService extends CrudService<OaBuyDao, OaBuy> {
+
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private BuyDetailsService buyDetailsService;
+
+	@Autowired
+	private RuntimeService runtimeService;
+	@Autowired
+	protected TaskService taskService;
+	@Autowired
+	protected HistoryService historyService;
+	@Autowired
+	protected RepositoryService repositoryService;
+	@Autowired
+	private IdentityService identityService;
+	@Autowired
+	private OaBuyDao oaBuyDao;
+	@Autowired
+	private BuyDetailsDao buyDetailsDao;
+
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+	@Autowired
+	private UserDao userDao;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+	@Autowired
+	private WorkattachmentService workattachmentService;
+
+	public OaBuy get(String id) {
+		OaBuy oaBuy = oaBuyDao.get(id);
+		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
+		workClientAttachment.setAttachmentId(id);
+		workClientAttachment.setAttachmentFlag("69");//附件类型(files_info)
+		List<WorkClientAttachment> list = workClientAttachmentDao.findList(workClientAttachment);
+		if(list.size() > 0){
+			oaBuy.setWorkAttachments(list);
+		}
+		Map<String,Object> variables=null;
+		if(oaBuy != null){
+			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(oaBuy.getProcessInstanceId()).singleResult();
+			if(historicProcessInstance!=null) {
+				variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
+			} else {
+				variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(oaBuy.getProcessInstanceId()).active().singleResult().getId());
+			}
+			oaBuy.setVariables(variables);
+		}
+		return oaBuy;
+	}
+
+	public List<OaBuy> findList(OaBuy oaBuy) {
+		return super.findList(oaBuy);
+	}
+
+	public Page<OaBuy> findPage(Page<OaBuy> page, OaBuy oaBuy) {
+		oaBuy.getSqlMap().put("dsf", dataScopeFilter(oaBuy.getCurrentUser(), "o", "u","s", MenuStatusEnum.OA_BUY.getValue()));
+		oaBuy.setPage(page);
+		page.setList(findList(oaBuy));
+		return page;
+	}
+
+	@Transactional(readOnly = false)
+	public void save(OaBuy oaBuy,Map<String, Object> variables) {
+		super.save(oaBuy);
+		//采购详情
+		for (BuyDetails buyDetails : oaBuy.getBuyDetailsList()){
+			if (buyDetails.getId() == null){
+				continue;
+			}
+			if (buyDetails.DEL_FLAG_NORMAL.equals(buyDetails.getDelFlag())){
+				buyDetails.setOaBuy(oaBuy);
+				if (StringUtils.isBlank(buyDetails.getId())){
+					buyDetails.preInsert();
+					buyDetailsDao.insert(buyDetails);
+				}else{
+					buyDetails.preUpdate();
+					buyDetailsDao.update(buyDetails);
+				}
+			}else{
+				buyDetailsDao.delete(buyDetails);
+			}
+		}
+		for (WorkClientAttachment workClientAttachment : oaBuy.getWorkAttachments()){
+			if (workClientAttachment.getId() == null){
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())){
+				workClientAttachment.setAttachmentId(oaBuy.getId());
+				workClientAttachment.setAttachmentFlag("69");
+				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())&&StringUtils.isNotBlank(workClientAttachment.getUrl()) && !workClientAttachment.getUrl().equals("null")){
+					workClientAttachment.preInsert();
+					workClientAttachmentDao.insert(workClientAttachment);
+				}else{
+					workClientAttachment.preUpdate();
+					workClientAttachmentDao.update(workClientAttachment);
+				}
+			}else{
+				workClientAttachmentDao.delete(workClientAttachment);
+			}
+		}
+		// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+		identityService.setAuthenticatedUserId(oaBuy.getCurrentUser().getId());
+		// 启动流程
+		String businessKey = oaBuy.getId().toString();
+		variables.put("type", "oaBuy");
+		variables.put("busId", businessKey);
+		variables.put("title", "采购申请");//设置标题;
+		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ActUtils.PD_OABUY[0], businessKey, variables);
+		oaBuy.setProcessInstance(processInstance);
+		// 更新流程实例ID
+		oaBuy.setProcessInstanceId(processInstance.getId());
+		oaBuyDao.updateProcessInstanceId(oaBuy);
+	}
+
+	@Transactional(readOnly = false)
+	public void delete(OaBuy oaBuy) {
+		super.delete(oaBuy);
+	}
+
+	@Transactional(readOnly = false)
+	public void sendNotify(String chaosongIds,String shenpiId,String oaLeaveId) {
+		if(StringUtils.isNotBlank(oaLeaveId)){
+			if(StringUtils.isNotBlank(chaosongIds)){
+				WorkProjectNotify notify = new WorkProjectNotify();
+				notify.setTitle(UserUtils.getUser().getName()+"发起了采购申请");
+				notify.setRemarks("待通知");
+				notify.setContent(UserUtils.getUser().getName()+"的采购申请");
+				notify.setNotifyRole("");
+				notify.setNotifyId(oaLeaveId);
+				notify.setStatus("0");
+				notify.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify.setType("35");
+				String[] arr = chaosongIds.split(",");
+				for (String id : arr){
+					if(StringUtils.isNotBlank(id)){
+						notify.setId("");
+						notify.setUser(new User(id));
+						workProjectNotifyService.save(notify);
+					}
+				}
+			}
+			if(StringUtils.isNotBlank(shenpiId)){
+				WorkProjectNotify notify = new WorkProjectNotify();
+				notify.setTitle("您有新的采购申请待审批");
+				notify.setRemarks("待审批");
+				notify.setContent("采购申请--待审批");
+				notify.setNotifyRole("");
+				notify.setUser(new User(shenpiId));
+				notify.setNotifyId(oaLeaveId);
+				notify.setStatus("0");
+				notify.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify.setType("35");
+				workProjectNotifyService.save(notify);
+			}
+		}
+	}
+
+
+	@Transactional(readOnly = false)
+	public void auditSave(OaBuy oaBuy) {
+		// 设置意见
+		oaBuy.getAct().setComment(("yes".equals(oaBuy.getAct().getFlag())?"[同意] ":"[驳回] ")+oaBuy.getAct().getComment());
+		// 对不同环节的业务逻辑进行操作
+		String taskDefKey = oaBuy.getAct().getTaskDefKey();
+		//发送通知
+		WorkProjectNotify notify = new WorkProjectNotify();
+		notify.setNotifyId(oaBuy.getId());
+		notify.setCompanyId(UserUtils.getSelectCompany().getId());
+		notify.setType("35");
+		notify.setStatus("0");
+		notify.setNotifyRole("");
+
+		//业务逻辑对应的条件表达式
+		String exp = "";
+		// 审核环节
+		if ("audit1".equals(taskDefKey)){
+			exp = "pass";
+		} else if ("audit2".equals(taskDefKey)) {
+			exp = "pass";
+		} else if ("audit3".equals(taskDefKey)){
+			exp = "pass";
+		}else if ("audit4".equals(taskDefKey)){
+			exp = "pass";
+		}else if ("audit5".equals(taskDefKey)){
+			exp = "pass";
+		}else if("apply_end".equals(taskDefKey)){
+			exp = "pass";
+		}
+		// 未知环节,直接返回
+		else{
+			return;
+		}
+		// 提交流程任务
+		Map<String, Object> vars = Maps.newHashMap();
+		vars.put(exp, "yes".equals(oaBuy.getAct().getFlag()) ? false : true);
+		// 提交流程任务
+		actTaskService.complete(oaBuy.getAct().getTaskId(), oaBuy.getAct().getProcInsId(), oaBuy.getAct().getComment(), vars);
+		boolean state = actTaskService.isProcessEnd(oaBuy.getAct().getProcInsId());
+		oaBuy.setStatus("2");
+		if (!state){
+			if ("yes".equals(oaBuy.getAct().getFlag())){
+				oaBuy.setStatus("3");
+			}else {
+				oaBuy.setStatus("4");
+			}
+		}
+		oaBuy.preUpdate();
+		oaBuyDao.update(oaBuy);
+
+		//需在leave更新后 操作:
+		//1待审核  2审核中 3通过 4驳回 5已撤销 6催办中
+		if("2".equals(oaBuy.getStatus())){
+			oaBuy = this.get(oaBuy.getId());
+			String userId = oaBuy.getVariables().get("assignee").toString();
+			if(StringUtils.isNotBlank(userId)){
+				notify.setUser(UserUtils.get(userId));
+			}
+			notify.setTitle("您有新的采购申请待审批");
+			notify.setRemarks("待审批");
+			notify.setContent("采购申请--待审批");
+
+		}else if("3".equals(oaBuy.getStatus())){
+			notify.setUser(oaBuy.getCreateBy());
+			notify.setTitle("您的采购申请已通过");
+			notify.setRemarks("待通知");
+			notify.setContent(oaBuy.getAct().getComment());
+		}else if("4".equals(oaBuy.getStatus())){
+			notify.setUser(oaBuy.getCreateBy());
+			notify.setTitle("您的采购申请被驳回");
+			notify.setRemarks("待通知");
+			notify.setContent(oaBuy.getAct().getComment());
+		}
+		workProjectNotifyService.save(notify);
+
+		//更新审核人的阅读状态
+		WorkProjectNotify notify2 = new WorkProjectNotify();
+		notify2.setUser(UserUtils.getUser());
+		notify2.setNotifyId(oaBuy.getId());
+		workProjectNotifyService.readByNotifyIdAndNotifyUser(notify2);
+
+		//抄送
+		if("3".equals(oaBuy.getStatus()) || "4".equals(oaBuy.getStatus())){
+			ApprovalCopy approvalCopy = approvalCopyService.getByApprovalId(oaBuy.getId());
+			if(approvalCopy!=null && StringUtils.isNotBlank(approvalCopy.getCCId())){
+				WorkProjectNotify notify1= new WorkProjectNotify();
+				notify1.setNotifyId(oaBuy.getId());
+				notify1.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify1.setType("35");
+				notify1.setStatus("0");
+				notify1.setNotifyRole("");
+				notify1.setContent(oaBuy.getAct().getComment());
+				String[] ccIds = approvalCopy.getCCId().split(",");
+				for(String ccId : ccIds){
+					if(StringUtils.isNotBlank(ccId)){
+						notify1.setUser(new User(ccId));
+						if("3".equals(oaBuy.getStatus())){
+							notify1.setTitle(UserUtils.get(oaBuy.getCreateBy().getId()).getName()+"的采购申请已通过");
+						}
+						if("4".equals(oaBuy.getStatus())){
+							notify1.setTitle(UserUtils.get(oaBuy.getCreateBy().getId()).getName()+"的采购申请被驳回");
+						}
+						notify1.setRemarks("待通知");
+						notify1.setId("");
+						workProjectNotifyService.save(notify1);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * 获取流程详细Leave
+	 * @param processInstanceId
+	 */
+	@SuppressWarnings("unchecked")
+	public OaBuy getByProcessInstanceId(String processInstanceId) {
+		OaBuy oaBuy = oaBuyDao.getByProcessInstanceId(processInstanceId);
+		return oaBuy;
+	}
+
+	/**
+	 * 获取流程详细及工作流参数
+	 * @param id
+	 */
+	@SuppressWarnings("unchecked")
+	public OaBuy getById(String id) {
+		OaBuy oaBuy = oaBuyDao.get(id);
+		return oaBuy;
+	}
+
+	@Transactional(readOnly = false)
+	public void update(OaBuy oaBuy) {
+		oaBuy.preUpdate();
+		oaBuyDao.update(oaBuy);
+	}
+
+	@Transactional(readOnly = false)
+	public Map getBuyById(String id,String type) {
+
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
+		OaBuy oaBuy = this.getById(id);
+		Map<String,Object> map = Maps.newHashMap();
+		String officeName = "";
+		String officeId = "";
+		if(oaBuy!=null){
+			User user = userDao.get(oaBuy.getCreateBy());
+			if(user!=null){
+				map.put("userName", user.getName());
+				map.put("photo",user.getPhoto());
+				map.put("users", user.getId());
+				Office office = user.getOffice();
+				if(office!=null && office.getName()!=null){
+					officeName = office.getName();
+					officeId = office.getId();
+				}
+			}
+			List<BuyDetails> buyDetailsList = new ArrayList<BuyDetails>();
+			if(StringUtils.isNotBlank(oaBuy.getId())){
+				BuyDetails buyDetails = new BuyDetails();
+				buyDetails.setOaBuy(oaBuy);
+				buyDetailsList = buyDetailsService.findList(buyDetails);
+				if(buyDetails!=null){
+					oaBuy.setBuyDetailsList(buyDetailsList);
+				}
+			}
+			String buySort = oaBuy.getBuySort();
+			String payStyle = oaBuy.getPayStyle();
+			if (buySort.equals("1")){
+				buySort = "办公用品";
+			}else if (buySort.equals("2")){
+				buySort = "生产原料";
+			}else if (buySort.equals("3")){
+				buySort = "其它";
+			}
+			if (payStyle.equals("1")){
+				payStyle = "现金";
+			}else if (payStyle.equals("2")){
+				payStyle = "汇款";
+			}else if (payStyle.equals("3")){
+				payStyle = "第三方支付软件";
+			}
+			map.put("deliverDate",oaBuy.getDeliverDate() == null ? "" : sd.format(oaBuy.getDeliverDate()));
+			map.put("buySort", buySort);
+			map.put("totalPrice",oaBuy.getTotalPrice());
+			map.put("payStyle", payStyle);
+			List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(oaBuy.getId(),"69");
+			String files = "";
+			if (workattachmentList!=null && workattachmentList.size()!=0){
+				for (Workattachment workattachment : workattachmentList){
+					files += workattachment.getUrl()+",";
+				}
+				if (files.length() > 1) {
+					files = files.substring(0, files.length() - 1);
+				}
+			}
+			map.put("files", files);
+			map.put("buyDetailsList",buyDetailsList);
+			map.put("createDate",oaBuy.getCreateDate()==null?"":sdf.format(oaBuy.getCreateDate()));
+			map.put("remarks",oaBuy.getRemarks());
+			map.put("applyContent",oaBuy.getApplyContent());
+			//map.put("approveDetail",oaBuy.getApproveDetail());
+			map.put("companyId",oaBuy.getCompanyId());
+			map.put("officeName",officeName);
+			map.put("officeId",officeId);
+			map.put("approvalId",id);
+			map.put("status",oaBuy.getStatus());
+			List<Act> list = actTaskService.histoicFlowList(oaBuy.getProcessInstanceId(), "", "");
+			List<Act> list2 = actTaskService.toMyStartedList(oaBuy.getProcessInstanceId());
+			if (list2!=null && list2.size()!=0){
+				Act act1 = list2.get(list2.size()-1);
+				map.put("taskId", act1.getTaskId());
+				map.put("taskName",act1.getTaskName());
+				map.put("procInsId", act1.getProcInsId());
+				map.put("procDefId", act1.getProcDefId());
+				map.put("actStatus", act1.getStatus()==null?"todo":act1.getStatus());
+				map.put("taskDefKey", act1.getTaskDefKey());
+				map.put("procDefKey", "oaBuy");
+			}
+			List list1 = new ArrayList();
+			String approvalStatus = "0";
+			String assigneeName = "";
+			if (list!=null && list.size()!=0) {
+				if (list.get(0).getHistIns().getActivityName().contains("审批")) {
+					for (int i = list.size() - 1; i > -1; i--) {
+						Act act = list.get(i);
+						Map<String, Object> maps = new HashMap<String, Object>();
+						String state = "0";
+						String activityName = "";
+						if (act.getHistIns().getActivityName().contains("审批")) {
+							if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+								activityName = "已审批";
+								if (UserUtils.getUser().getName().equals(act.getAssigneeName())){
+									approvalStatus = "1";
+								}
+							} else {
+								activityName = "待审批";
+								state = "2";
+							}
+						} else {
+							activityName = act.getHistIns().getActivityName();
+						}
+						if (type.equals("1") || type.equals("2")) {
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(act.getAssigneeName()) ? "我" : act.getAssigneeName());
+						} else if (type.equals("3")) {
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", act.getAssigneeName());
+						}
+						maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+						maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+						maps.put("durationTime", act.getDurationTime());
+						maps.put("state", state);
+						maps.put("userId", act.getCurrentUser().getId());
+						list1.add(maps);
+					}
+				} else {
+					if (oaBuy.getStatus().equals("4") || oaBuy.getStatus().equals("3")){
+						for (int i = 0; i < list.size()-1; i++) {
+							Act act = list.get(i);
+							Map<String, Object> maps = new HashMap<String, Object>();
+							String state = "0";
+							String activityName = "";
+							if (act.getHistIns().getActivityName().contains("发起申请")) {
+								activityName = act.getHistIns().getActivityName();
+								assigneeName = act.getAssigneeName();
+							}else if (act.getHistIns().getActivityName().contains("审批")) {
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+									activityName = "已审批";
+									if (UserUtils.getUser().getName().equals(assigneeName)){
+										approvalStatus = "1";
+									}
+									if (i == (list.size()-2) && oaBuy.getStatus().equals("4")){
+										activityName = "审核驳回";
+										state = "1";
+									}else if (i == (list.size()-2) && oaBuy.getStatus().equals("3")){
+										activityName = "审核成功";
+									}
+								} else {
+									activityName = "待审批";
+									state = "2";
+								}
+							}
+							else {
+								activityName = act.getHistIns().getActivityName();
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+							}
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+							maps.put("durationTime", act.getDurationTime());
+							maps.put("state", state);
+							maps.put("userId", act.getCurrentUser().getId());
+							list1.add(maps);
+						}
+					}else {
+						for (int i = 0; i < list.size(); i++) {
+							Act act = list.get(i);
+							Map<String, Object> maps = new HashMap<String, Object>();
+							String state = "0";
+							String activityName = "";
+							if (act.getHistIns().getActivityName().contains("发起申请")) {
+								activityName = act.getHistIns().getActivityName();
+								assigneeName = act.getAssigneeName();
+							}else if (act.getHistIns().getActivityName().contains("审批")) {
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+									activityName = "已审批";
+									if (UserUtils.getUser().getName().equals(assigneeName)){
+										approvalStatus = "1";
+									}
+								} else {
+									activityName = "待审批";
+									state = "2";
+								}
+							}
+							else {
+								activityName = act.getHistIns().getActivityName();
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+							}
+							if (oaBuy.getStatus().equals("5") && i == list.size() - 1) {
+								activityName = "已撤销";
+								state = "1";
+							}
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+							maps.put("durationTime", act.getDurationTime());
+							maps.put("state", state);
+							maps.put("userId", act.getCurrentUser().getId());
+							list1.add(maps);
+						}
+					}
+				}
+			}
+			map.put("approvalStatus", approvalStatus);
+			ApprovalCopy approvalCopy = new ApprovalCopy();
+			approvalCopy.setApprovalId(id);
+			List<ApprovalCopy> approvalCopyList = approvalCopyService.findList(approvalCopy);
+			String CCName = "";
+			String CCId = "";
+			Boolean readFlag = false;
+			if (approvalCopyList!=null && approvalCopyList.size()!=0) {
+				ApprovalCopy approvalCopy1 = approvalCopyList.get(0);
+				CCId = approvalCopy1.getCCId();
+				String[] CCid = approvalCopy1.getCCId().split(",");
+				readFlag = approvalCopy1.getReadFlag().equals("0");
+				if (type.equals("3") && readFlag){
+					approvalCopy1.setReadFlag("1");
+					approvalCopyService.save(approvalCopy1);
+				}
+				for (String userId : CCid) {
+					User CCUser = UserUtils.get(userId);
+					if (CCUser != null) {
+						CCName = CCUser.getName() + ",";
+					}
+				}
+				if (CCName.length() > 1) {
+					CCName = CCName.substring(0, CCName.length() - 1);
+				} else {
+					CCName = "";
+				}
+			}
+
+			map.put("nameCopy",CCName);
+			map.put("CCId",CCId);
+			map.put("process",list1);
+		}
+		return map;
+	}
+
+	@Transactional(readOnly = false)
+	public void saveFile(OaBuy oaBuy) {
+		if (StringUtils.isBlank(oaBuy.getId())){
+			oaBuy.preInsert();
+			oaBuyDao.insert(oaBuy);
+		}else{
+			oaBuy.preUpdate();
+			oaBuyDao.update(oaBuy);
+		}
+	}
+
+	//APP端使用,一次上传一个
+	@Transactional(readOnly = false)
+	public String uploadFile(OSSClientUtil ossClientUtil, MultipartFile file, OaBuy oaBuy, String flag) {
+		String fileName = file.getOriginalFilename();
+		String fileType = fileName.substring(fileName.lastIndexOf("."));
+		String url = ossClientUtil.uploadFile2OSS(file,"oaBuy");
+		Workattachment workattachment = new Workattachment();
+		workattachment.setUrl(url);
+		workattachment.setType(fileType);
+		workattachment.setAttachmentName(fileName);
+		workattachment.setAttachmentId(oaBuy.getId());
+		workattachment.setAttachmentUser(UserUtils.getUser().getId());
+		workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+		workattachment.setAttachmentFlag(flag);
+		workattachmentService.save(workattachment);
+		return url;
+	}
+}

+ 50 - 0
src/main/java/com/jeeplus/modules/oabuy/service/OaBuyServicess.java

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oabuy.service;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.oabuy.entity.OaBuy;
+import com.jeeplus.modules.oabuy.dao.OaBuyDao;
+
+/**
+ * 采购申请Service
+ * @author liuw
+ * @version 2018-01-16
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaBuyServicess extends CrudService<OaBuyDao, OaBuy> {
+
+	public OaBuy get(String id) {
+		return super.get(id);
+	}
+	
+	public List<OaBuy> findList(OaBuy oaBuy) {
+		return super.findList(oaBuy);
+	}
+	
+	public Page<OaBuy> findPage(Page<OaBuy> page, OaBuy oaBuy) {
+		return super.findPage(page, oaBuy);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(OaBuy oaBuy) {
+		super.save(oaBuy);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(OaBuy oaBuy) {
+		super.delete(oaBuy);
+	}
+	
+	
+	
+	
+}

+ 520 - 0
src/main/java/com/jeeplus/modules/oabuy/web/OaBuyController.java

@@ -0,0 +1,520 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oabuy.web;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActAuditService;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.buydetails.entity.BuyDetails;
+import com.jeeplus.modules.buydetails.service.BuyDetailsService;
+import com.jeeplus.modules.oabuy.service.OaBuyService;
+import com.jeeplus.modules.pushinfo.entity.Pushinfo;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.TaskService;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.oabuy.entity.OaBuy;
+import com.jeeplus.modules.oabuy.service.OaBuyServicess;
+
+/**
+ * 采购申请Controller
+ * @author liuw
+ * @version 2018-01-16
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oabuy/oaBuy")
+public class OaBuyController extends BaseController {
+
+	@Autowired
+	private OaBuyService oaBuyService;
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+	@Autowired
+	private PushinfoService pushinfoService;
+	@Autowired
+	protected TaskService taskService;
+	@Autowired
+	protected HistoryService historyService;
+	@Autowired
+	protected RepositoryService repositoryService;
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private BuyDetailsService buyDetailsService;
+
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private ActAuditService actAuditService;
+	@ModelAttribute
+	public OaBuy get(@RequestParam(required=false) String id) {
+		OaBuy entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = oaBuyService.get(id);
+		}
+		if (entity == null){
+			entity = new OaBuy();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 采购申请列表页面
+	 */
+	@RequiresPermissions("oabuy:oaBuy:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OaBuy oaBuy, HttpServletRequest request, HttpServletResponse response, Model model) {
+		oaBuy.setOfficeId(UserUtils.getSelectOffice().getId());
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()){
+			oaBuy.setCompanyId(user.getComId());
+			if (!UserUtils.isManager()){
+				oaBuy.setCreateBy(user);
+			}
+		}
+		Page<OaBuy> page = oaBuyService.findPage(new Page<OaBuy>(request, response), oaBuy); 
+		model.addAttribute("page", page);
+		return "modules/oabuy/oaBuyList";
+	}
+
+	/**
+	 * 查看,增加,编辑采购申请表单页面
+	 */
+	@RequiresPermissions(value={"oabuy:oaBuy:view","oabuy:oaBuy:add","oabuy:oaBuy:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(OaBuy oaBuy, Model model,HttpServletRequest request) {
+		String view = "oaBuyForm";
+		String tabId = request.getParameter("tabId");
+		if(StringUtils.isNotBlank(oaBuy.getId())){
+			BuyDetails buyDetails = new BuyDetails();
+			buyDetails.setOaBuy(oaBuy);
+			List<BuyDetails> buyDetailsList = buyDetailsService.findList(buyDetails);
+			oaBuy.setBuyDetailsList(buyDetailsList);
+		}
+		if("0".equals(tabId)){
+			view = "oaBuyView";
+		}
+		// 环节编号
+		String taskDefKey = oaBuy.getAct().getTaskDefKey();
+		// 审核环节
+		if ("audit1".equals(taskDefKey)){
+			if (org.apache.commons.lang3.StringUtils.isBlank(oaBuy.getAct().getStatus())){
+				model.addAttribute("disabled","true");
+				oaBuy.getAct().setProcInsId(oaBuy.getProcessInstanceId());
+			}else {
+				model.addAttribute("disabled","false");
+			}
+			view = "oaBuyAudit";
+		}else if ("apply_end".equals(taskDefKey)){
+			view = "oaBuyAudit";
+		}
+		//
+		else if ("modifyApply".equals(taskDefKey)){
+			view = "oaBuyForm";
+		}
+		model.addAttribute("oaBuy", oaBuy);
+		return "modules/oabuy/"+ view;
+	}
+
+	/**
+	 * 保存采购申请
+	 */
+	@RequiresPermissions(value={"oabuy:oaBuy:add","oabuy:oaBuy:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OaBuy oaBuy, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (StringUtils.isNotBlank(oaBuy.getId())) {
+			OaBuy t = oaBuyService.get(oaBuy.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(oaBuy, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			if (t.getStatus().equals("3") || t.getStatus().equals("4")){
+				addMessage(redirectAttributes, "已结束流程不能修改!");
+			}else {
+				oaBuyService.save(t);
+			}
+		} else {
+			try {
+				oaBuy.setStatus("1");
+				String approverId = "";
+				List<String> adds = oaBuy.getAdds();
+				for(int i = 0;i<adds.size();i++){
+					if(i + 1 == adds.size()){
+						approverId += adds.get(i);
+					}else{
+						approverId += adds.get(i) + ",";
+					}
+				}
+				oaBuy.setIds(approverId);
+
+				Map<String, Object> variables = Maps.newHashMap();
+				String alias = "1";
+				List<String> assigneeList = new ArrayList<String>(); //分配任务的人员
+				if (approverId != null && !approverId.equals("")) {
+					if (!UserUtils.getUser().isAdmin() && approverId.contains(UserUtils.getUser().getId())) {
+						logger.error("启动请假流程失败:");
+						addMessage(redirectAttributes, "申请失败,审批人不能为本人!");
+						return "redirect:" + adminPath + "/oabuy/oaBuy";
+					}
+					String[] approverIds = approverId.split(",");
+					for (int i = 0; i < approverIds.length; i++) {
+						assigneeList.add(approverIds[i]);
+					}
+					alias = approverIds[0];
+				}
+				variables.put("assigneeList", assigneeList);
+				variables.put("count", assigneeList.size());
+				User CC = new User();
+				CC.setId(oaBuy.getCCId());
+				User user = UserUtils.getUser();
+				//oaBuy.setUser(user);
+				oaBuy.setCreateBy(user);
+				oaBuy.setUpdateBy(user);
+				oaBuy.setStatus("1");
+				oaBuy.setDelFlag("0");
+				oaBuy.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				oaBuy.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+				oaBuyService.save(oaBuy, variables);
+				ApprovalCopy approvalCopy = new ApprovalCopy();
+				approvalCopy.setCCId(oaBuy.getCCId());
+				approvalCopy.setUserId(user.getId());
+				approvalCopy.setType("oaBuy");
+				approvalCopy.setApprovalId(oaBuy.getId());
+				approvalCopy.setApproverId(approverId);
+				approvalCopy.setReadFlag("0");
+				approvalCopyService.save(approvalCopy);
+
+				//给抄送人、审批人发送通知
+				if(approvalCopy!=null && org.apache.commons.lang3.StringUtils.isNotBlank(approvalCopy.getId())){
+					String chaosongIds = approvalCopy.getCCId();//给所有抄送人发送通知
+					String shenpiIds = alias;//给审批流程的第一个人发送通知
+					oaBuyService.sendNotify(chaosongIds,shenpiIds,approvalCopy.getApprovalId());
+					String content = "审批信息 申请人:" + user.getName() + ",采购申请 待审批!";
+					UserUtils.pushIm(alias,content);
+				}
+
+
+				//推送
+				String title = "审批";
+				String content = UserUtils.getUser().getName() + "的采购申请需要你审批";
+				String status = "待审批";
+				String remarks = "采购申请内容类型:" + oaBuy.getApplyContent();
+				Map extras = new HashMap();
+				extras.put("type", "4001");
+				extras.put("id", oaBuy.getId());
+				extras.put("procDefKey", "oaBuy");
+
+				boolean b = JPushClientUtil.sendNotificationToAlias(title, content, extras, alias);
+				Pushinfo pushinfo = new Pushinfo();
+				pushinfo.setCurrentUser(UserUtils.getUser());
+				pushinfo.setRemarks(remarks);
+				pushinfo.setUserId(UserUtils.getUser().getId());
+				pushinfo.setType("4001");
+				pushinfo.setPushId(oaBuy.getId());
+				pushinfo.setTitle(title);
+				pushinfo.setContent(content);
+				pushinfo.setStatus(status);
+				pushinfo.setAddcontent("oaBuy");
+				pushinfo.setPushUserId(alias);
+				pushinfo.setParentType("singleApproval");
+				pushinfo.setMobile("ios,android");
+				pushinfo.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				pushinfoService.save(pushinfo);
+				if (b) {
+					addMessage(redirectAttributes, "采购申请已经提交");
+				} else {
+					logger.error("启动采购申请流程失败:");
+					addMessage(redirectAttributes, "采购申请失败,采购申请推送失败!");
+					return "redirect:" + adminPath + "/oabuy/oaBuy";
+				}
+			} catch (Exception e) {
+				logger.error("启动采购申请流程失败:", e);
+				addMessage(redirectAttributes, "系统内部错误!");
+			}
+		}
+		return "redirect:"+Global.getAdminPath()+"/oabuy/oaBuy/?repage";
+	}
+	
+	/**
+	 * 删除采购申请
+	 */
+	@RequiresPermissions("oabuy:oaBuy:del")
+	@RequestMapping(value = "delete")
+	public String delete(OaBuy oaBuy, RedirectAttributes redirectAttributes) {
+		oaBuyService.delete(oaBuy);
+		addMessage(redirectAttributes, "删除采购申请成功");
+		return "redirect:"+Global.getAdminPath()+"/oabuy/oaBuy/?repage";
+	}
+	
+	/**
+	 * 批量删除采购申请
+	 */
+	@RequiresPermissions("oabuy:oaBuy:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			oaBuyService.delete(oaBuyService.get(id));
+		}
+		addMessage(redirectAttributes, "删除采购申请成功");
+		return "redirect:"+Global.getAdminPath()+"/oabuy/oaBuy/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("oabuy:oaBuy:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(OaBuy oaBuy, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "采购申请"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<OaBuy> page = oaBuyService.findPage(new Page<OaBuy>(request, response, -1), oaBuy);
+    		new ExportExcel("采购申请", OaBuy.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出采购申请记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oabuy/oaBuy/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("oabuy:oaBuy:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<OaBuy> list = ei.getDataList(OaBuy.class);
+			for (OaBuy oaBuy : list){
+				try{
+					oaBuyService.save(oaBuy);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条采购申请记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条采购申请记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入采购申请失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oabuy/oaBuy/?repage";
+    }
+	
+	/**
+	 * 下载导入采购申请数据模板
+	 */
+	@RequiresPermissions("oabuy:oaBuy:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "采购申请数据导入模板.xlsx";
+    		List<OaBuy> list = Lists.newArrayList(); 
+    		new ExportExcel("采购申请数据", OaBuy.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oabuy/oaBuy/?repage";
+    }
+
+	/**
+	 * 待办任务列表页面
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"oaBuyTodoList"})
+	public String oaBuyTodoList(Act act, HttpServletRequest request, HttpServletResponse response, Model model) {
+		act.setProcDefKey("oaBuy");
+		List<Act> list = actTaskService.todoList(act);
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<OaBuy> lists = new ArrayList<OaBuy>();
+		for (Act a : list) {
+			OaBuy oaAll = oaBuyService.getByProcessInstanceId(a.getProcInsId());
+			if (oaAll != null && oaAll.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					User user = UserUtils.get(a.getVars().getMap().get("applyUserId").toString());
+					if (user!=null) {
+						a.getVars().getMap().put("applyUserId", UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+					}
+				}
+				oaAll.setAct(a);
+//				if (com.jeeplus.common.utils.StringUtils.isNotBlank(oaAll.getId())){
+//					oaAll.setName(officeService.get(oaAll.getCompanyId()).getName());
+//				}
+				lists.add(oaAll);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oabuy/oaBuyTodoList";
+	}
+
+
+	/**
+	 * 已办任务
+	 * @param act
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"oaBuyHistoricList"})
+	public String oaBuyHistoricList (Act act, HttpServletRequest request, HttpServletResponse response, Model model){
+		act.setProcDefKey("oaBuy");
+		Page<Act> page = actTaskService.historicList(new Page<Act>(request, response), act);
+		List<Act> list = page.getList();
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<OaBuy> lists = new ArrayList<OaBuy>();
+		for (Act a : list) {
+			OaBuy oaAll = oaBuyService.getByProcessInstanceId(a.getHistTask().getProcessInstanceId());
+			if (oaAll != null && oaAll.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					a.getVars().getMap().put("applyUserId",UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+				}
+				oaAll.setAct(a);
+//				if (StringUtils.isNotBlank(a.getId())){
+//					oaAll.setName(officeService.get(oaAll.getCompanyId()).getName());
+//				}
+//				if (oaAll.getCreateDate()!=null){
+//					oaAll.setTime(sdf.format(oaAll.getCreateDate()));
+//				}
+				lists.add(oaAll);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oabuy/oaBuyHistoricList";
+	}
+
+	/**
+	 * 工单执行(完成任务)
+	 * @param
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "saveAudit")
+	public String saveAudit(OaBuy oaBuy, Model model) {
+		//oaBuyService.auditSave(oaBuy);
+		Act act = oaBuy.getAct();
+		actAuditService.saveAudit(act, act.getProcInsId(), "oaBuy", oaBuy.getAct().getComment(), oaBuy.getId(), "2");
+		if (oaBuy!=null && org.apache.commons.lang3.StringUtils.isNotBlank(oaBuy.getHome()) && oaBuy.getHome().equals("home")){
+			return "redirect:" + adminPath + "/home";
+		}
+		return "redirect:" + adminPath + "/oabuy/oaBuy";
+	}
+	/**
+	 * 审核信息
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "applyOnLeave")
+	public String applyOnCompany(Act act, HttpServletResponse response, Model model) {
+		// 获取流程XML上的表单KEY
+		//String formKey = "/oa/leave/applyOnLeave";
+		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
+		//logger.info("------formKeys:"+formKeys);
+		// 获取流程实例对象
+		if (act.getProcInsId() != null){
+			if(actTaskService.getProcIns(act.getProcInsId())!=null){
+				act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+			}else{
+				act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+			}
+		}
+		return "redirect:" + ActUtils.getFormUrl(formKey, act);
+	}
+
+	@RequestMapping(value = "getProcess")
+	public String getProcess(OaBuy oaBuy, Model model) {
+		model.addAttribute("processInstanceId", oaBuy.getProcessInstanceId());
+		return "modules/oabuy/oaBuyTrack";
+
+	}
+
+	/**
+	 * 采购申请撤销
+	 * @param
+	 * @return
+	 */
+	@RequestMapping(value = "revoke")
+	public String revoke(HttpServletRequest request, HttpServletResponse response) {
+
+		HashMap<String, String> requestMap = findRequestMap(request);
+		String processInstanceId = requestMap.get("processInstanceId");
+		String id = requestMap.get("id");
+		AjaxJson j = new AjaxJson();
+		try {
+			OaBuy oaAll = oaBuyService.getById(id);
+			oaAll.setStatus("5");
+			oaAll.preUpdate();
+			oaBuyService.update(oaAll);
+			Map map = oaBuyService.getBuyById(id,"1");
+			j.put("data",map);
+			actTaskService.endProcessInstance(processInstanceId, "");
+			j.setMsg("撤销申请成功");
+
+			//撤销后,更改所有发送过的通知的阅读状态
+			WorkProjectNotify notify = new WorkProjectNotify();
+			notify.setNotifyId(oaAll.getId());
+			workProjectNotifyService.readByNotifyId(notify);
+		}catch (Exception e){
+			j.setErrorCode("101");
+			logger.info(e.getMessage());
+			j.setMsg("撤销申请失败");
+			j.setSuccess(false);
+		}
+		return "redirect:" + adminPath + "/oabuy/oaBuy?repage";
+	}
+}

+ 31 - 0
src/main/java/com/jeeplus/modules/oaperformance/dao/OaPerformanceDao.java

@@ -0,0 +1,31 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaperformance.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.oaperformance.entity.OaPerformance;
+
+/**
+ * 绩效自评DAO接口
+ * @author liuw
+ * @version 2018-01-17
+ */
+@MyBatisDao
+public interface OaPerformanceDao extends CrudDao<OaPerformance> {
+
+    /**
+     * 更新流程实例ID
+     * @param OaPerformance
+     * @return
+     */
+    public int updateProcessInstanceId(OaPerformance oaPerformance);
+
+    /**
+     * 根据流程实例ID获取Leave
+     * @param processInstanceId
+     * @return
+     */
+    public OaPerformance getByProcessInstanceId(String processInstanceId);
+}

+ 266 - 0
src/main/java/com/jeeplus/modules/oaperformance/entity/OaPerformance.java

@@ -0,0 +1,266 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaperformance.entity;
+
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+/**
+ * 绩效自评Entity
+ * @author liuw
+ * @version 2018-01-17
+ */
+public class OaPerformance extends ActEntity<OaPerformance> {
+	
+	private static final long serialVersionUID = 1L;
+	private String status;		// 申请状态
+	private String companyId;		// 公司
+	private String officeId;		// 部门
+	private String processInstanceId;		// 流程id
+	private String lastWork;		// 上月工作任务
+	private String finishWork;		// 实际完成任务
+	private String finishRate;		// 任务达成率
+	private String lastPerformance;		// 上月工作自评
+	private String nowWork;		// 本月工作任务
+	private String nowPlan;		// 本月工作计划
+	private String home;		// 本月工作计划
+/*=================================================================================*/
+	private String comment; //审核意见 目前只保存手机端审核
+	private String ids;
+	private String CCId;
+	private List<String> adds = Lists.newArrayList();
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList();
+	private Date createDateStart;//搜索条件
+	private Date createDateEnd;
+	// 流程任务
+	private Task task;
+	private Map<String, Object> variables;
+	// 运行中的流程实例
+	private ProcessInstance processInstance;
+	// 历史的流程实例
+	private HistoricProcessInstance historicProcessInstance;
+	// 流程定义
+	private ProcessDefinition processDefinition;
+
+	public String getIds() {
+		return ids;
+	}
+
+	public void setIds(String ids) {
+		this.ids = ids;
+	}
+
+	public String getCCId() {
+		return CCId;
+	}
+
+	public void setCCId(String CCId) {
+		this.CCId = CCId;
+	}
+
+	public List<String> getAdds() {
+		return adds;
+	}
+
+	public void setAdds(List<String> adds) {
+		this.adds = adds;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+	public User getUser() {
+		return createBy;
+	}
+
+	public void setUser(User user) {
+		this.createBy = user;
+	}
+	public Date getCreateDateStart() {
+		return createDateStart;
+	}
+
+	public void setCreateDateStart(Date createDateStart) {
+		this.createDateStart = createDateStart;
+	}
+
+	public Date getCreateDateEnd() {
+		return createDateEnd;
+	}
+
+	public void setCreateDateEnd(Date createDateEnd) {
+		this.createDateEnd = createDateEnd;
+	}
+
+	public Task getTask() {
+		return task;
+	}
+
+	public void setTask(Task task) {
+		this.task = task;
+	}
+
+	public Map<String, Object> getVariables() {
+		return variables;
+	}
+
+	public void setVariables(Map<String, Object> variables) {
+		this.variables = variables;
+	}
+
+	public ProcessInstance getProcessInstance() {
+		return processInstance;
+	}
+
+	public void setProcessInstance(ProcessInstance processInstance) {
+		this.processInstance = processInstance;
+	}
+
+	public HistoricProcessInstance getHistoricProcessInstance() {
+		return historicProcessInstance;
+	}
+
+	public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
+		this.historicProcessInstance = historicProcessInstance;
+	}
+
+	public ProcessDefinition getProcessDefinition() {
+		return processDefinition;
+	}
+
+	public void setProcessDefinition(ProcessDefinition processDefinition) {
+		this.processDefinition = processDefinition;
+	}
+
+	public OaPerformance() {
+		super();
+	}
+
+	public OaPerformance(String id){
+		super(id);
+	}
+
+	@ExcelField(title="申请状态", align=2, sort=7)
+	public String getStatus() {
+		return status;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+	
+	@ExcelField(title="公司", align=2, sort=8)
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+	
+	@ExcelField(title="部门", align=2, sort=9)
+	public String getOfficeId() {
+		return officeId;
+	}
+
+	public void setOfficeId(String officeId) {
+		this.officeId = officeId;
+	}
+	
+	@ExcelField(title="流程id", align=2, sort=10)
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+	
+	@ExcelField(title="上月工作任务", align=2, sort=11)
+	public String getLastWork() {
+		return lastWork;
+	}
+
+	public void setLastWork(String lastWork) {
+		this.lastWork = lastWork;
+	}
+	
+	@ExcelField(title="实际完成任务", align=2, sort=12)
+	public String getFinishWork() {
+		return finishWork;
+	}
+
+	public void setFinishWork(String finishWork) {
+		this.finishWork = finishWork;
+	}
+	
+	@ExcelField(title="任务达成率", align=2, sort=13)
+	public String getFinishRate() {
+		return finishRate;
+	}
+
+	public void setFinishRate(String finishRate) {
+		this.finishRate = finishRate;
+	}
+	
+	@ExcelField(title="上月工作自评", align=2, sort=14)
+	public String getLastPerformance() {
+		return lastPerformance;
+	}
+
+	public void setLastPerformance(String lastPerformance) {
+		this.lastPerformance = lastPerformance;
+	}
+	
+	@ExcelField(title="本月工作任务", align=2, sort=15)
+	public String getNowWork() {
+		return nowWork;
+	}
+
+	public void setNowWork(String nowWork) {
+		this.nowWork = nowWork;
+	}
+	
+	@ExcelField(title="本月工作计划", align=2, sort=16)
+	public String getNowPlan() {
+		return nowPlan;
+	}
+
+	public void setNowPlan(String nowPlan) {
+		this.nowPlan = nowPlan;
+	}
+
+	public String getHome() {
+		return home;
+	}
+
+	public void setHome(String home) {
+		this.home = home;
+	}
+}

+ 533 - 0
src/main/java/com/jeeplus/modules/oaperformance/service/OaPerformanceService.java

@@ -0,0 +1,533 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaperformance.service;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.utils.Collections3;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.buydetails.entity.BuyDetails;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.*;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.oaperformance.entity.OaPerformance;
+import com.jeeplus.modules.oaperformance.dao.OaPerformanceDao;
+
+/**
+ * 绩效自评Service
+ * @author liuw
+ * @version 2018-01-17
+ */
+@Service
+@Transactional(readOnly = true)
+public class OaPerformanceService extends CrudService<OaPerformanceDao, OaPerformance> {
+
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+
+	@Autowired
+	private RuntimeService runtimeService;
+	@Autowired
+	protected TaskService taskService;
+	@Autowired
+	protected HistoryService historyService;
+	@Autowired
+	protected RepositoryService repositoryService;
+	@Autowired
+	private IdentityService identityService;
+	@Autowired
+	private OaPerformanceDao oaPerformanceDao;
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+	@Autowired
+	private UserDao userDao;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+
+	public OaPerformance get(String id) {
+		OaPerformance oaPerformance = oaPerformanceDao.get(id);
+		Map<String,Object> variables=null;
+		if(oaPerformance != null){
+			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(oaPerformance.getProcessInstanceId()).singleResult();
+			if(historicProcessInstance!=null) {
+				variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
+			} else {
+				variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(oaPerformance.getProcessInstanceId()).active().singleResult().getId());
+			}
+			oaPerformance.setVariables(variables);
+		}
+		return oaPerformance;
+	}
+
+	public List<OaPerformance> findList(OaPerformance oaPerformance) {
+		return super.findList(oaPerformance);
+	}
+
+	public Page<OaPerformance> findPage(Page<OaPerformance> page, OaPerformance oaPerformance) {
+		oaPerformance.getSqlMap().put("dsf", dataScopeFilter(oaPerformance.getCurrentUser(), "o", "u","s", MenuStatusEnum.OA_PERFORMANCE.getValue()));
+		oaPerformance.setPage(page);
+		page.setList(findList(oaPerformance));
+		return page;
+	}
+
+	@Transactional(readOnly = false)
+	public void save(OaPerformance oaPerformance,Map<String, Object> variables) {
+		super.save(oaPerformance);
+		// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+		identityService.setAuthenticatedUserId(oaPerformance.getCurrentUser().getId());
+		// 启动流程
+		String businessKey = oaPerformance.getId().toString();
+		variables.put("type", "oaPerformance");
+		variables.put("busId", businessKey);
+		variables.put("title", "绩效自评");//设置标题;
+		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ActUtils.PD_OAPERFORMANCE[0], businessKey, variables);
+		oaPerformance.setProcessInstance(processInstance);
+		// 更新流程实例ID
+		oaPerformance.setProcessInstanceId(processInstance.getId());
+		oaPerformanceDao.updateProcessInstanceId(oaPerformance);
+	}
+
+	@Transactional(readOnly = false)
+	public void delete(OaPerformance oaPerformance) {
+		super.delete(oaPerformance);
+	}
+
+	@Transactional(readOnly = false)
+	public void sendNotify(String chaosongIds,String shenpiId,String oaLeaveId) {
+		if(StringUtils.isNotBlank(oaLeaveId)){
+			if(StringUtils.isNotBlank(chaosongIds)){
+				WorkProjectNotify notify = new WorkProjectNotify();
+				notify.setTitle(UserUtils.getUser().getName()+"发起了绩效自评申请");
+				notify.setRemarks("待通知");
+				notify.setContent(UserUtils.getUser().getName()+"的绩效自评申请");
+				notify.setNotifyRole("");
+				notify.setNotifyId(oaLeaveId);
+				notify.setStatus("0");
+				notify.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify.setType("36");//设置通知编号
+				String[] arr = chaosongIds.split(",");
+				for (String id : arr){
+					if(StringUtils.isNotBlank(id)){
+						notify.setId("");
+						notify.setUser(new User(id));
+						workProjectNotifyService.save(notify);
+					}
+				}
+			}
+			if(StringUtils.isNotBlank(shenpiId)){
+				WorkProjectNotify notify = new WorkProjectNotify();
+				notify.setTitle("您有新的绩效自评申请请待审批");
+				notify.setRemarks("待审批");
+				notify.setContent("绩效自评申请--待审批");
+				notify.setNotifyRole("");
+				notify.setUser(new User(shenpiId));
+				notify.setNotifyId(oaLeaveId);
+				notify.setStatus("0");
+				notify.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify.setType("36");
+				workProjectNotifyService.save(notify);
+			}
+		}
+	}
+
+
+	@Transactional(readOnly = false)
+	public void auditSave(OaPerformance oaPerformance) {
+		// 设置意见
+		oaPerformance.getAct().setComment(("yes".equals(oaPerformance.getAct().getFlag())?"[同意] ":"[驳回] ")+oaPerformance.getAct().getComment());
+		// 对不同环节的业务逻辑进行操作
+		String taskDefKey = oaPerformance.getAct().getTaskDefKey();
+		//发送通知
+		WorkProjectNotify notify = new WorkProjectNotify();
+		notify.setNotifyId(oaPerformance.getId());
+		notify.setCompanyId(UserUtils.getSelectCompany().getId());
+		notify.setType("36");
+		notify.setStatus("0");
+		notify.setNotifyRole("");
+
+		//业务逻辑对应的条件表达式
+		String exp = "";
+		// 审核环节
+		if ("audit1".equals(taskDefKey)){
+			exp = "pass";
+		} else if ("audit2".equals(taskDefKey)) {
+			exp = "pass";
+		} else if ("audit3".equals(taskDefKey)){
+			exp = "pass";
+		}else if ("audit4".equals(taskDefKey)){
+			exp = "pass";
+		}else if ("audit5".equals(taskDefKey)){
+			exp = "pass";
+		}else if("apply_end".equals(taskDefKey)){
+			exp = "pass";
+		}
+		// 未知环节,直接返回
+		else{
+			return;
+		}
+		// 提交流程任务
+		Map<String, Object> vars = Maps.newHashMap();
+		vars.put(exp, "yes".equals(oaPerformance.getAct().getFlag()) ? false : true);
+		// 提交流程任务
+		actTaskService.complete(oaPerformance.getAct().getTaskId(), oaPerformance.getAct().getProcInsId(), oaPerformance.getAct().getComment(), vars);
+		boolean state = actTaskService.isProcessEnd(oaPerformance.getAct().getProcInsId());
+		oaPerformance.setStatus("2");
+		if (!state){
+			if ("yes".equals(oaPerformance.getAct().getFlag())){
+				oaPerformance.setStatus("3");
+			}else {
+				oaPerformance.setStatus("4");
+			}
+		}
+		oaPerformance.preUpdate();
+		oaPerformanceDao.update(oaPerformance);
+
+		//需在leave更新后 操作:
+		//1待审核  2审核中 3通过 4驳回 5已撤销 6催办中
+		if("2".equals(oaPerformance.getStatus())){
+			oaPerformance = this.get(oaPerformance.getId());
+			String userId = oaPerformance.getVariables().get("assignee").toString();
+			if(StringUtils.isNotBlank(userId)){
+				notify.setUser(UserUtils.get(userId));
+			}
+			notify.setTitle("您有新的绩效自评申请待审批");
+			notify.setRemarks("待审批");
+			notify.setContent("绩效自评申请--待审批");
+
+		}else if("3".equals(oaPerformance.getStatus())){
+			notify.setUser(oaPerformance.getCreateBy());
+			notify.setTitle("您的绩效自评申请已通过");
+			notify.setRemarks("待通知");
+			notify.setContent(oaPerformance.getAct().getComment());
+		}else if("4".equals(oaPerformance.getStatus())){
+			notify.setUser(oaPerformance.getCreateBy());
+			notify.setTitle("您的绩效自评申请被驳回");
+			notify.setRemarks("待通知");
+			notify.setContent(oaPerformance.getAct().getComment());
+		}
+		workProjectNotifyService.save(notify);
+
+		//更新审核人的阅读状态
+		WorkProjectNotify notify2 = new WorkProjectNotify();
+		notify2.setUser(UserUtils.getUser());
+		notify2.setNotifyId(oaPerformance.getId());
+		workProjectNotifyService.readByNotifyIdAndNotifyUser(notify2);
+
+		//抄送
+		if("3".equals(oaPerformance.getStatus()) || "4".equals(oaPerformance.getStatus())){
+			ApprovalCopy approvalCopy = approvalCopyService.getByApprovalId(oaPerformance.getId());
+			if(approvalCopy!=null && StringUtils.isNotBlank(approvalCopy.getCCId())){
+				WorkProjectNotify notify1= new WorkProjectNotify();
+				notify1.setNotifyId(oaPerformance.getId());
+				notify1.setCompanyId(UserUtils.getSelectCompany().getId());
+				notify1.setType("36");
+				notify1.setStatus("0");
+				notify1.setNotifyRole("");
+				notify1.setContent(oaPerformance.getAct().getComment());
+				String[] ccIds = approvalCopy.getCCId().split(",");
+				for(String ccId : ccIds){
+					if(StringUtils.isNotBlank(ccId)){
+						notify1.setUser(new User(ccId));
+						if("3".equals(oaPerformance.getStatus())){
+							notify1.setTitle(UserUtils.get(oaPerformance.getCreateBy().getId()).getName()+"的绩效自评申请已通过");
+						}
+						if("4".equals(oaPerformance.getStatus())){
+							notify1.setTitle(UserUtils.get(oaPerformance.getCreateBy().getId()).getName()+"的绩效自评申请被驳回");
+						}
+						notify1.setRemarks("待通知");
+						notify1.setId("");
+						workProjectNotifyService.save(notify1);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * 获取流程详细Leave
+	 * @param processInstanceId
+	 */
+	@SuppressWarnings("unchecked")
+	public OaPerformance getByProcessInstanceId(String processInstanceId) {
+		OaPerformance oaPerformance = oaPerformanceDao.getByProcessInstanceId(processInstanceId);
+		return oaPerformance;
+	}
+
+	/**
+	 * 获取流程详细及工作流参数
+	 * @param id
+	 */
+	@SuppressWarnings("unchecked")
+	public OaPerformance getById(String id) {
+		OaPerformance oaPerformance = oaPerformanceDao.get(id);
+		return oaPerformance;
+	}
+
+	@Transactional(readOnly = false)
+	public void update(OaPerformance oaPerformance) {
+		oaPerformance.preUpdate();
+		oaPerformanceDao.update(oaPerformance);
+	}
+
+	@Transactional(readOnly = false)
+	public Map getBuyById(String id,String type) {
+
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		OaPerformance oaPerformance = this.getById(id);
+		Map<String,Object> map = Maps.newHashMap();
+		String officeName = "";
+		String officeId = "";
+		if(oaPerformance!=null){
+			User user = userDao.get(oaPerformance.getCreateBy());
+			if(user!=null){
+				map.put("userName", user.getName());
+				map.put("photo",user.getPhoto());
+				map.put("users", user.getId());
+				Office office = user.getOffice();
+				if(office!=null && office.getName()!=null){
+					officeName = office.getName();
+					officeId = office.getId();
+				}
+			}
+			map.put("createDate",oaPerformance.getCreateDate()==null?"":sdf.format(oaPerformance.getCreateDate()));
+			map.put("lastWork",oaPerformance.getLastWork());
+			map.put("finishWork",oaPerformance.getFinishWork());
+			map.put("finishRate",oaPerformance.getFinishRate());
+			map.put("lastPerformance",oaPerformance.getLastPerformance());
+			map.put("nowWork",oaPerformance.getNowWork());
+			map.put("nowPlan",oaPerformance.getNowPlan());
+
+			map.put("companyId",oaPerformance.getCompanyId());
+			map.put("officeName",officeName);
+			map.put("officeId",officeId);
+			map.put("approvalId",id);
+			map.put("status",oaPerformance.getStatus());
+			List<Act> list = actTaskService.histoicFlowList(oaPerformance.getProcessInstanceId(), "", "");
+			List<Act> list2 = actTaskService.toMyStartedList(oaPerformance.getProcessInstanceId());
+			if (list2!=null && list2.size()!=0){
+				Act act1 = list2.get(list2.size()-1);
+				map.put("taskId", act1.getTaskId());
+				map.put("taskName",act1.getTaskName());
+				map.put("procInsId", act1.getProcInsId());
+				map.put("procDefId", act1.getProcDefId());
+				map.put("actStatus", act1.getStatus()==null?"todo":act1.getStatus());
+				map.put("taskDefKey", act1.getTaskDefKey());
+				map.put("procDefKey", "oaPerformance");
+			}
+			List list1 = new ArrayList();
+			String approvalStatus = "0";
+			String assigneeName = "";
+			if (list!=null && list.size()!=0) {
+				if (list.get(0).getHistIns().getActivityName().contains("审批")) {
+					for (int i = list.size() - 1; i > -1; i--) {
+						Act act = list.get(i);
+						Map<String, Object> maps = new HashMap<String, Object>();
+						String state = "0";
+						String activityName = "";
+						if (act.getHistIns().getActivityName().contains("审批")) {
+							if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+								activityName = "已审批";
+								if (UserUtils.getUser().getName().equals(act.getAssigneeName())){
+									approvalStatus = "1";
+								}
+							} else {
+								activityName = "待审批";
+								state = "2";
+							}
+						} else {
+							activityName = act.getHistIns().getActivityName();
+						}
+						if (type.equals("1") || type.equals("2")) {
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(act.getAssigneeName()) ? "我" : act.getAssigneeName());
+						} else if (type.equals("3")) {
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", act.getAssigneeName());
+						}
+						maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+						maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+						maps.put("durationTime", act.getDurationTime());
+						maps.put("state", state);
+						maps.put("userId", act.getCurrentUser().getId());
+						list1.add(maps);
+					}
+				} else {
+					if (oaPerformance.getStatus().equals("4") || oaPerformance.getStatus().equals("3")){
+						for (int i = 0; i < list.size()-1; i++) {
+							Act act = list.get(i);
+							Map<String, Object> maps = new HashMap<String, Object>();
+							String state = "0";
+							String activityName = "";
+							if (act.getHistIns().getActivityName().contains("发起申请")) {
+								activityName = act.getHistIns().getActivityName();
+								assigneeName = act.getAssigneeName();
+							}else if (act.getHistIns().getActivityName().contains("审批")) {
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+									activityName = "已审批";
+									if (UserUtils.getUser().getName().equals(assigneeName)){
+										approvalStatus = "1";
+									}
+									if (i == (list.size()-2) && oaPerformance.getStatus().equals("4")){
+										activityName = "审核驳回";
+										state = "1";
+									}else if (i == (list.size()-2) && oaPerformance.getStatus().equals("3")){
+										activityName = "审核成功";
+									}
+								} else {
+									activityName = "待审批";
+									state = "2";
+								}
+							}
+							else {
+								activityName = act.getHistIns().getActivityName();
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+							}
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+							maps.put("durationTime", act.getDurationTime());
+							maps.put("state", state);
+							maps.put("userId", act.getCurrentUser().getId());
+							list1.add(maps);
+						}
+					}else {
+						for (int i = 0; i < list.size(); i++) {
+							Act act = list.get(i);
+							Map<String, Object> maps = new HashMap<String, Object>();
+							String state = "0";
+							String activityName = "";
+							if (act.getHistIns().getActivityName().contains("发起申请")) {
+								activityName = act.getHistIns().getActivityName();
+								assigneeName = act.getAssigneeName();
+							}else if (act.getHistIns().getActivityName().contains("审批")) {
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
+									activityName = "已审批";
+									if (UserUtils.getUser().getName().equals(assigneeName)){
+										approvalStatus = "1";
+									}
+								} else {
+									activityName = "待审批";
+									state = "2";
+								}
+							}
+							else {
+								activityName = act.getHistIns().getActivityName();
+								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
+									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
+								}
+							}
+							if (oaPerformance.getStatus().equals("5") && i == list.size() - 1) {
+								activityName = "已撤销";
+								state = "1";
+							}
+							maps.put("activityName", activityName);
+							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
+							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
+							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
+							maps.put("durationTime", act.getDurationTime());
+							maps.put("state", state);
+							maps.put("userId", act.getCurrentUser().getId());
+							list1.add(maps);
+						}
+					}
+				}
+			}
+			map.put("approvalStatus", approvalStatus);
+			ApprovalCopy approvalCopy = new ApprovalCopy();
+			approvalCopy.setApprovalId(id);
+			List<ApprovalCopy> approvalCopyList = approvalCopyService.findList(approvalCopy);
+			String CCName = "";
+			String CCId = "";
+			Boolean readFlag = false;
+			if (approvalCopyList!=null && approvalCopyList.size()!=0) {
+				ApprovalCopy approvalCopy1 = approvalCopyList.get(0);
+				CCId = approvalCopy1.getCCId();
+				String[] CCid = approvalCopy1.getCCId().split(",");
+				readFlag = approvalCopy1.getReadFlag().equals("0");
+				if (type.equals("3") && readFlag){
+					approvalCopy1.setReadFlag("1");
+					approvalCopyService.save(approvalCopy1);
+				}
+				for (String userId : CCid) {
+					User CCUser = UserUtils.get(userId);
+					if (CCUser != null) {
+						CCName = CCUser.getName() + ",";
+					}
+				}
+				if (CCName.length() > 1) {
+					CCName = CCName.substring(0, CCName.length() - 1);
+				} else {
+					CCName = "";
+				}
+			}
+
+			map.put("nameCopy",CCName);
+			map.put("CCId",CCId);
+			map.put("process",list1);
+		}
+		return map;
+	}
+/*
+	public OaPerformance get(String id) {
+		return super.get(id);
+	}
+
+	public List<OaPerformance> findList(OaPerformance oaPerformance) {
+		return super.findList(oaPerformance);
+	}
+
+	public Page<OaPerformance> findPage(Page<OaPerformance> page, OaPerformance oaPerformance) {
+		return super.findPage(page, oaPerformance);
+	}
+
+	@Transactional(readOnly = false)
+	public void save(OaPerformance oaPerformance) {
+		super.save(oaPerformance);
+	}
+
+	@Transactional(readOnly = false)
+	public void delete(OaPerformance oaPerformance) {
+		super.delete(oaPerformance);
+	}*/
+
+
+
+
+}

+ 516 - 0
src/main/java/com/jeeplus/modules/oaperformance/web/OaPerformanceController.java

@@ -0,0 +1,516 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.oaperformance.web;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActAuditService;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.buydetails.entity.BuyDetails;
+import com.jeeplus.modules.pushinfo.entity.Pushinfo;
+import com.jeeplus.modules.pushinfo.service.PushinfoService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.TaskService;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.oaperformance.entity.OaPerformance;
+import com.jeeplus.modules.oaperformance.service.OaPerformanceService;
+
+/**
+ * 绩效自评Controller
+ * @author liuw
+ * @version 2018-01-17
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/oaperformance/oaPerformance")
+public class OaPerformanceController extends BaseController {
+
+	@Autowired
+	private OaPerformanceService oaPerformanceService;
+	@Autowired
+	private ApprovalCopyService approvalCopyService;
+	@Autowired
+	private PushinfoService pushinfoService;
+	@Autowired
+	protected TaskService taskService;
+	@Autowired
+	protected HistoryService historyService;
+	@Autowired
+	protected RepositoryService repositoryService;
+	@Autowired
+	private ActTaskService actTaskService;
+
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private ActAuditService actAuditService;
+	@ModelAttribute
+	public OaPerformance get(@RequestParam(required=false) String id) {
+		OaPerformance entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = oaPerformanceService.get(id);
+		}
+		if (entity == null){
+			entity = new OaPerformance();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 绩效自评列表页面
+	 */
+	@RequiresPermissions("oaperformance:oaPerformance:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OaPerformance oaPerformance, HttpServletRequest request, HttpServletResponse response, Model model) {
+		oaPerformance.setOfficeId(UserUtils.getSelectOffice().getId());
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()){
+			oaPerformance.setCompanyId(user.getComId());
+			if (!UserUtils.isManager()){
+				oaPerformance.setCreateBy(user);
+			}
+		}
+		Page<OaPerformance> page = oaPerformanceService.findPage(new Page<OaPerformance>(request, response), oaPerformance); 
+		model.addAttribute("page", page);
+		return "modules/oaperformance/oaPerformanceList";
+	}
+
+	/**
+	 * 查看,增加,编辑绩效自评表单页面
+	 */
+	@RequiresPermissions(value={"oaperformance:oaPerformance:view","oaperformance:oaPerformance:add","oaperformance:oaPerformance:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(OaPerformance oaPerformance, Model model,HttpServletRequest request) {
+		String view = "oaPerformanceForm";
+		String tabId = request.getParameter("tabId");
+		if("0".equals(tabId)){
+			view = "oaPerformanceView";
+		}
+		// 环节编号
+		String taskDefKey = oaPerformance.getAct().getTaskDefKey();
+		// 审核环节
+		if ("audit1".equals(taskDefKey)){
+			if (org.apache.commons.lang3.StringUtils.isBlank(oaPerformance.getAct().getStatus())){
+				model.addAttribute("disabled","true");
+				oaPerformance.getAct().setProcInsId(oaPerformance.getProcessInstanceId());
+			}else {
+				model.addAttribute("disabled","false");
+			}
+			view = "oaPerformanceAudit";
+		}else if ("apply_end".equals(taskDefKey)){
+			view = "oaPerformanceAudit";
+		}
+		//
+		else if ("modifyApply".equals(taskDefKey)){
+			view = "oaPerformanceForm";
+		}
+		model.addAttribute("oaPerformance", oaPerformance);
+		return "modules/oaperformance/"+ view;
+
+		/*model.addAttribute("oaPerformance", oaPerformance);
+		return "modules/oaperformance/oaPerformanceForm";*/
+	}
+
+	/**
+	 * 保存绩效自评
+	 */
+	@RequiresPermissions(value={"oaperformance:oaPerformance:add","oaperformance:oaPerformance:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OaPerformance oaPerformance, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (StringUtils.isNotBlank(oaPerformance.getId())) {
+			OaPerformance t = oaPerformanceService.get(oaPerformance.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(oaPerformance, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			if (t.getStatus().equals("3") || t.getStatus().equals("4")){
+				addMessage(redirectAttributes, "已结束流程不能修改!");
+			}else {
+				oaPerformanceService.save(t);
+			}
+		} else {
+			try {
+				oaPerformance.setStatus("1");
+				String approverId = "";
+				List<String> adds = oaPerformance.getAdds();
+				for(int i = 0;i<adds.size();i++){
+					if(i + 1 == adds.size()){
+						approverId += adds.get(i);
+					}else{
+						approverId += adds.get(i) + ",";
+					}
+				}
+				oaPerformance.setIds(approverId);
+
+				Map<String, Object> variables = Maps.newHashMap();
+				String alias = "1";
+				List<String> assigneeList = new ArrayList<String>(); //分配任务的人员
+				if (approverId != null && !approverId.equals("")) {
+					if (!UserUtils.getUser().isAdmin() && approverId.contains(UserUtils.getUser().getId())) {
+						logger.error("启动绩效自评流程失败:");
+						addMessage(redirectAttributes, "申请失败,审批人不能为本人!");
+						return "redirect:" + adminPath + "/oaperformance/oaPerformance";
+					}
+					String[] approverIds = approverId.split(",");
+					for (int i = 0; i < approverIds.length; i++) {
+						assigneeList.add(approverIds[i]);
+					}
+					alias = approverIds[0];
+				}
+				variables.put("assigneeList", assigneeList);
+				variables.put("count", assigneeList.size());
+				User CC = new User();
+				CC.setId(oaPerformance.getCCId());
+				User user = UserUtils.getUser();
+				//oaBuy.setUser(user);
+				oaPerformance.setCreateBy(user);
+				oaPerformance.setUpdateBy(user);
+				oaPerformance.setStatus("1");
+				oaPerformance.setDelFlag("0");
+				oaPerformance.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				oaPerformance.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+				oaPerformanceService.save(oaPerformance, variables);
+				ApprovalCopy approvalCopy = new ApprovalCopy();
+				approvalCopy.setCCId(oaPerformance.getCCId());
+				approvalCopy.setUserId(user.getId());
+				approvalCopy.setType("oaPerformance");
+				approvalCopy.setApprovalId(oaPerformance.getId());
+				approvalCopy.setApproverId(approverId);
+				approvalCopy.setReadFlag("0");
+				approvalCopyService.save(approvalCopy);
+
+				//给抄送人、审批人发送通知
+				if(approvalCopy!=null && org.apache.commons.lang3.StringUtils.isNotBlank(approvalCopy.getId())){
+					String chaosongIds = approvalCopy.getCCId();//给所有抄送人发送通知
+					String shenpiIds = alias;//给审批流程的第一个人发送通知
+					oaPerformanceService.sendNotify(chaosongIds,shenpiIds,approvalCopy.getApprovalId());
+					String content = "审批信息 申请人:" + user.getName() + ",绩效自评申请: 待审批!";
+					UserUtils.pushIm(alias,content);
+				}
+
+
+				//推送
+				String title = "审批";
+				String content = UserUtils.getUser().getName() + "的绩效自评申请需要你审批";
+				String status = "待审批";
+				String remarks = "绩效自评申请内容类型:" + oaPerformance.getLastPerformance();
+				Map extras = new HashMap();
+				extras.put("type", "4001");
+				extras.put("id", oaPerformance.getId());
+				extras.put("procDefKey", "oaPerformance");
+
+				boolean b = JPushClientUtil.sendNotificationToAlias(title, content, extras, alias);
+				Pushinfo pushinfo = new Pushinfo();
+				pushinfo.setCurrentUser(UserUtils.getUser());
+				pushinfo.setRemarks(remarks);
+				pushinfo.setUserId(UserUtils.getUser().getId());
+				pushinfo.setType("4001");
+				pushinfo.setPushId(oaPerformance.getId());
+				pushinfo.setTitle(title);
+				pushinfo.setContent(content);
+				pushinfo.setStatus(status);
+				pushinfo.setAddcontent("oaPerformance");
+				pushinfo.setPushUserId(alias);
+				pushinfo.setParentType("singleApproval");
+				pushinfo.setMobile("ios,android");
+				pushinfo.setCompanyId(UserUtils.getSelectCompany() == null ? "" : UserUtils.getSelectCompany().getId());
+				pushinfoService.save(pushinfo);
+				if (b) {
+					addMessage(redirectAttributes, "绩效自评申请已经提交");
+				} else {
+					logger.error("启动绩效自评申请流程失败:");
+					addMessage(redirectAttributes, "绩效自评申请失败,绩效自评申请推送失败!");
+					return "redirect:" + adminPath + "/oaperformance/oaPerformance";
+				}
+			} catch (Exception e) {
+				logger.error("启动绩效自评申请流程失败:", e);
+				addMessage(redirectAttributes, "系统内部错误!");
+			}
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";
+		/*addMessage(redirectAttributes, "保存绩效自评成功");
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";*/
+	}
+	
+	/**
+	 * 删除绩效自评
+	 */
+	@RequiresPermissions("oaperformance:oaPerformance:del")
+	@RequestMapping(value = "delete")
+	public String delete(OaPerformance oaPerformance, RedirectAttributes redirectAttributes) {
+		oaPerformanceService.delete(oaPerformance);
+		addMessage(redirectAttributes, "删除绩效自评成功");
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";
+	}
+	
+	/**
+	 * 批量删除绩效自评
+	 */
+	@RequiresPermissions("oaperformance:oaPerformance:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			oaPerformanceService.delete(oaPerformanceService.get(id));
+		}
+		addMessage(redirectAttributes, "删除绩效自评成功");
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("oaperformance:oaPerformance:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(OaPerformance oaPerformance, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "绩效自评"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<OaPerformance> page = oaPerformanceService.findPage(new Page<OaPerformance>(request, response, -1), oaPerformance);
+    		new ExportExcel("绩效自评", OaPerformance.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出绩效自评记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("oaperformance:oaPerformance:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<OaPerformance> list = ei.getDataList(OaPerformance.class);
+			for (OaPerformance oaPerformance : list){
+				try{
+					oaPerformanceService.save(oaPerformance);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条绩效自评记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条绩效自评记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入绩效自评失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";
+    }
+	
+	/**
+	 * 下载导入绩效自评数据模板
+	 */
+	@RequiresPermissions("oaperformance:oaPerformance:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "绩效自评数据导入模板.xlsx";
+    		List<OaPerformance> list = Lists.newArrayList(); 
+    		new ExportExcel("绩效自评数据", OaPerformance.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/oaperformance/oaPerformance/?repage";
+    }
+
+	/**
+	 * 待办任务列表页面
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"oaPerformanceTodoList"})
+	public String oaPerformanceTodoList(Act act, HttpServletRequest request, HttpServletResponse response, Model model) {
+		act.setProcDefKey("oaPerformance");
+		List<Act> list = actTaskService.todoList(act);
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<OaPerformance> lists = new ArrayList<OaPerformance>();
+		for (Act a : list) {
+			OaPerformance oaAll = oaPerformanceService.getByProcessInstanceId(a.getProcInsId());
+			if (oaAll != null && oaAll.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					User user = UserUtils.get(a.getVars().getMap().get("applyUserId").toString());
+					if (user!=null) {
+						a.getVars().getMap().put("applyUserId", UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+					}
+				}
+				oaAll.setAct(a);
+//				if (com.jeeplus.common.utils.StringUtils.isNotBlank(oaAll.getId())){
+//					oaAll.setName(officeService.get(oaAll.getCompanyId()).getName());
+//				}
+				lists.add(oaAll);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oaperformance/oaPerformanceTodoList";
+	}
+
+
+	/**
+	 * 已办任务
+	 * @param act
+	 * @param request
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = {"oaPerformanceHistoricList"})
+	public String oaPerformanceHistoricList (Act act, HttpServletRequest request, HttpServletResponse response, Model model){
+		act.setProcDefKey("oaPerformance");
+		Page<Act> page = actTaskService.historicList(new Page<Act>(request, response), act);
+		List<Act> list = page.getList();
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<OaPerformance> lists = new ArrayList<OaPerformance>();
+		for (Act a : list) {
+			OaPerformance oaAll = oaPerformanceService.getByProcessInstanceId(a.getHistTask().getProcessInstanceId());
+			if (oaAll != null && oaAll.getCompanyId().equals(companyId)) {
+				if (a.getVars().getMap().get("applyUserId")!=null){
+					a.getVars().getMap().put("applyUserId",UserUtils.get(a.getVars().getMap().get("applyUserId").toString()).getName());
+				}
+				oaAll.setAct(a);
+//				if (StringUtils.isNotBlank(a.getId())){
+//					oaAll.setName(officeService.get(oaAll.getCompanyId()).getName());
+//				}
+//				if (oaAll.getCreateDate()!=null){
+//					oaAll.setTime(sdf.format(oaAll.getCreateDate()));
+//				}
+				lists.add(oaAll);
+			}
+		}
+		model.addAttribute("list", lists);
+		return "modules/oaperformance/oaPerformanceHistoricList";
+	}
+
+	/**
+	 * 工单执行(完成任务)
+	 * @param
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "saveAudit")
+	public String saveAudit(OaPerformance oaPerformance, Model model) {
+		//oaPerformanceService.auditSave(oaPerformance);
+		Act act = oaPerformance.getAct();
+		actAuditService.saveAudit(act, act.getProcInsId(), "oaPerformance", oaPerformance.getAct().getComment(), oaPerformance.getId(), "2");
+		if (oaPerformance!=null && org.apache.commons.lang3.StringUtils.isNotBlank(oaPerformance.getHome()) && oaPerformance.getHome().equals("home")){
+			return "redirect:" + adminPath + "/home";
+		}
+		return "redirect:" + adminPath + "/oaperformance/oaPerformance";
+	}
+	/**
+	 * 审核信息
+	 * @param response
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping(value = "applyOnLeave")
+	public String applyOnCompany(Act act, HttpServletResponse response, Model model) {
+		// 获取流程XML上的表单KEY
+		//String formKey = "/oa/leave/applyOnLeave";
+		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
+		//logger.info("------formKeys:"+formKeys);
+		// 获取流程实例对象
+		if (act.getProcInsId() != null){
+			if(actTaskService.getProcIns(act.getProcInsId())!=null){
+				act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+			}else{
+				act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+			}
+		}
+		return "redirect:" + ActUtils.getFormUrl(formKey, act);
+	}
+
+	@RequestMapping(value = "getProcess")
+	public String getProcess(OaPerformance oaPerformance, Model model) {
+		model.addAttribute("processInstanceId", oaPerformance.getProcessInstanceId());
+		return "modules/oaperformance/oaPerformanceTrack";
+	}
+
+	/**
+	 * 采购申请撤销
+	 * @param
+	 * @return
+	 */
+	@RequestMapping(value = "revoke")
+	public String revoke(HttpServletRequest request, HttpServletResponse response) {
+
+		HashMap<String, String> requestMap = findRequestMap(request);
+		String processInstanceId = requestMap.get("processInstanceId");
+		String id = requestMap.get("id");
+		AjaxJson j = new AjaxJson();
+		try {
+			OaPerformance oaAll = oaPerformanceService.getById(id);
+			oaAll.setStatus("5");
+			oaAll.preUpdate();
+			oaPerformanceService.update(oaAll);
+			Map map = oaPerformanceService.getBuyById(id,"1");
+			j.put("data",map);
+			actTaskService.endProcessInstance(processInstanceId, "");
+			j.setMsg("撤销申请成功");
+
+			//撤销后,更改所有发送过的通知的阅读状态
+			WorkProjectNotify notify = new WorkProjectNotify();
+			notify.setNotifyId(oaAll.getId());
+			workProjectNotifyService.readByNotifyId(notify);
+		}catch (Exception e){
+			j.setErrorCode("101");
+			logger.info(e.getMessage());
+			j.setMsg("撤销申请失败");
+			j.setSuccess(false);
+		}
+		return "redirect:" + adminPath + "/oaperformance/oaPerformance?repage";
+	}
+	
+
+}

+ 22 - 0
src/main/java/com/jeeplus/modules/officehonor/dao/OfficehonorDao.java

@@ -0,0 +1,22 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officehonor.dao;
+
+import com.jeeplus.modules.sys.entity.Office;
+import java.util.List;
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.officehonor.entity.Officehonor;
+
+/**
+ * 企业荣誉DAO接口
+ * @author liuw
+ * @version 2017-12-05
+ */
+@MyBatisDao
+public interface OfficehonorDao extends CrudDao<Officehonor> {
+
+	public List<Office> findListByoffice(Office office);
+	
+}

+ 200 - 0
src/main/java/com/jeeplus/modules/officehonor/entity/Officehonor.java

@@ -0,0 +1,200 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officehonor.entity;
+
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.google.common.collect.Lists;
+import com.jeeplus.modules.sys.entity.Office;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+/**
+ * 企业荣誉Entity
+ * @author liuw
+ * @version 2017-12-05
+ */
+public class Officehonor extends DataEntity<Officehonor> {
+	//附件110    //编号模板24
+	public static final String SERIAL_BIZCODE = "24";
+	private static final long serialVersionUID = 1L;
+	private String honorType;		// 荣誉类型
+	private Date issuedDate;		// 颁发日期
+	private String issuedAgency;		// 颁发机构
+	private Office office;		// 企业外键
+	private String companyId;  //公司ID
+	private Date uploadDate; //上传日期
+	private String name;   //荣誉名称
+	private String 	companyName;  //公司名称
+	private String num;  //编号(公司简称+4位流水)
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList(); //附件
+	//临时属性
+	private String url;
+	private String uName;
+
+	/*-----------暂弃----------*/
+	private String content;		// 获奖内容
+	private String userName;		// 获奖人员
+	private String proveFile;		// 证明文件
+	private String filePlace;		// 文件存放地
+	private String image;		// 图片
+
+	public Officehonor() {
+		super();
+	}
+
+	public Officehonor(String id){
+		super(id);
+	}
+
+	@ExcelField(title="荣誉类型", dictType="honor_type", align=2, sort=7)
+	public String getHonorType() {
+		return honorType;
+	}
+
+	public void setHonorType(String honorType) {
+		this.honorType = honorType;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="颁发日期", align=2, sort=8)
+	public Date getIssuedDate() {
+		return issuedDate;
+	}
+
+	public void setIssuedDate(Date issuedDate) {
+		this.issuedDate = issuedDate;
+	}
+	
+	@ExcelField(title="获奖内容", align=2, sort=9)
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+	
+	@ExcelField(title="颁发机构", align=2, sort=10)
+	public String getIssuedAgency() {
+		return issuedAgency;
+	}
+
+	public void setIssuedAgency(String issuedAgency) {
+		this.issuedAgency = issuedAgency;
+	}
+	
+	@ExcelField(title="获奖人员", align=2, sort=11)
+	public String getUserName() {
+		return userName;
+	}
+
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+
+	public void setUserName(String userName) {
+		this.userName = userName;
+	}
+	
+	@ExcelField(title="证明文件", align=2, sort=12)
+	public String getProveFile() {
+		return proveFile;
+	}
+
+	public void setProveFile(String proveFile) {
+		this.proveFile = proveFile;
+	}
+	
+	@ExcelField(title="文件存放地", align=2, sort=13)
+	public String getFilePlace() {
+		return filePlace;
+	}
+
+	public void setFilePlace(String filePlace) {
+		this.filePlace = filePlace;
+	}
+	
+	@ExcelField(title="图片", align=2, sort=14)
+	public String getImage() {
+		return image;
+	}
+
+	public void setImage(String image) {
+		this.image = image;
+	}
+	
+	@ExcelField(title="企业外键", align=2, sort=15)
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+
+	public Date getUploadDate() {
+		return uploadDate;
+	}
+
+	public void setUploadDate(Date uploadDate) {
+		this.uploadDate = uploadDate;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getCompanyName() {
+		return companyName;
+	}
+
+	public void setCompanyName(String companyName) {
+		this.companyName = companyName;
+	}
+
+	public String getNum() {
+		return num;
+	}
+
+	public void setNum(String num) {
+		this.num = num;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getuName() {
+		return uName;
+	}
+
+	public void setuName(String uName) {
+		this.uName = uName;
+	}
+}

+ 158 - 0
src/main/java/com/jeeplus/modules/officehonor/service/OfficehonorService.java

@@ -0,0 +1,158 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officehonor.service;
+
+import java.util.List;
+
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.officequalify.entity.Officequalify;
+import com.jeeplus.modules.serialnum.service.SerialNumTplService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.officehonor.entity.Officehonor;
+import com.jeeplus.modules.officehonor.dao.OfficehonorDao;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 企业荣誉Service
+ * @author liuw
+ * @version 2017-12-05
+ */
+@Service
+@Transactional(readOnly = true)
+public class OfficehonorService extends CrudService<OfficehonorDao, Officehonor> {
+	@Autowired
+	private WorkattachmentService workattachmentService;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+	@Autowired
+	private SerialNumTplService serialNumTplService;
+	@Autowired
+	private OfficeService officeService;
+
+	public Officehonor get(String id) {
+		Officehonor officequalify = super.get(id);
+		//附件
+		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
+		workClientAttachment.setAttachmentId(id);
+		workClientAttachment.setAttachmentFlag("110");
+		officequalify.setWorkAttachments(workClientAttachmentDao.findList(workClientAttachment));
+		return officequalify;
+	}
+	
+	public List<Officehonor> findList(Officehonor officehonor) {
+		return super.findList(officehonor);
+	}
+	
+	public Page<Officehonor> findPage(Page<Officehonor> page, Officehonor officehonor) {
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()) {
+			if (officehonor.getOffice() == null || StringUtils.isBlank(officehonor.getOffice().getId())) {
+				officehonor.setOffice(UserUtils.getSelectOffice().getParent());
+			} else {
+				Office office = officeService.get(officehonor.getOffice().getId());
+				if ("1".equals(office.getType())) {
+					//总公司
+					officehonor.setCompanyId(officehonor.getOffice().getId());
+				} else {
+					officehonor.setOffice(officehonor.getOffice());
+				}
+			}
+		}
+		officehonor.setPage(page);
+		page.setList(findList(officehonor));
+
+		return page;
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(Officehonor officehonor) {
+		/*if (!file.isEmpty() && file.getSize() > 0) {
+			OSSClientUtil ossClientUtil = new OSSClientUtil();
+			String fileName = file.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
+			String url = ossClientUtil.uploadFile2OSS(file, "Officehonor");
+			officehonor.setImage(url);
+			*//*Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(url);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentName(fileName);
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentId(officehonor.getId());
+			workattachment.setAttachmentFlag("60");
+			workattachmentService.save(workattachment);*//*
+		}*/
+		super.save(officehonor);
+		if(StringUtils.isBlank(officehonor.getNum())){
+			officehonor.setNum(serialNumTplService.genSerialNum(UserUtils.get(officehonor.getCreateBy().getId()).getCompany(), Officehonor.SERIAL_BIZCODE));
+			super.save(officehonor);
+		}
+		//附件信息
+		for (WorkClientAttachment workClientAttachment : officehonor.getWorkAttachments()) {
+			if (workClientAttachment.getId() == null) {
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())) {
+				workClientAttachment.setAttachmentId(officehonor.getId());
+				workClientAttachment.setAttachmentFlag("110");
+				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())) {
+					workClientAttachment.preInsert();
+					workClientAttachmentDao.insert(workClientAttachment);
+				} else {
+					workClientAttachment.preUpdate();
+					workClientAttachmentDao.update(workClientAttachment);
+				}
+			} else {
+				workClientAttachmentDao.delete(workClientAttachment);
+			}
+		}
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(Officehonor officehonor) {
+		super.delete(officehonor);
+	}
+	
+	public Page<Office> findPageByoffice(Page<Office> page, Office office) {
+		office.setPage(page);
+		page.setList(dao.findListByoffice(office));
+		return page;
+	}
+	//上传
+	@Transactional(readOnly = false)
+	public void uploadattachment(MultipartFile file,Officehonor officehonor) {
+		if (!file.isEmpty() && file.getSize() > 0) {
+			OSSClientUtil ossClientUtil = new OSSClientUtil();
+			String fileName = file.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
+			String url = ossClientUtil.uploadFile2OSS(file, "Officehonor");
+			officehonor.setImage(url);
+			super.save(officehonor);
+			Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(url);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentName(fileName);
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentId(officehonor.getId());
+			workattachment.setAttachmentFlag("110");
+			workattachmentService.save(workattachment);
+		}
+	}
+	
+	
+}

+ 280 - 0
src/main/java/com/jeeplus/modules/officehonor/web/OfficehonorController.java

@@ -0,0 +1,280 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officehonor.web;
+
+import java.io.*;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.officehonor.entity.Officehonor;
+import com.jeeplus.modules.officehonor.service.OfficehonorService;
+
+/**
+ * 企业荣誉Controller
+ * @author liuw
+ * @version 2017-12-05
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/officehonor/officehonor")
+public class OfficehonorController extends BaseController {
+
+	@Autowired
+	private OfficehonorService officehonorService;
+	
+	@ModelAttribute
+	public Officehonor get(@RequestParam(required=false) String id) {
+		Officehonor entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = officehonorService.get(id);
+		}
+		if (entity == null){
+			entity = new Officehonor();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 企业荣誉列表页面
+	 */
+	@RequiresPermissions("officehonor:officehonor:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(Officehonor officehonor, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<Officehonor> page = officehonorService.findPage(new Page<Officehonor>(request, response), officehonor);
+		model.addAttribute("page", page);
+		return "modules/officehonor/officehonorList";
+	}
+
+	/**
+	 * 查看,增加,编辑企业荣誉表单页面
+	 */
+	@RequiresPermissions(value={"officehonor:officehonor:view","officehonor:officehonor:add","officehonor:officehonor:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(Officehonor officehonor, Model model,HttpServletRequest request) {
+		if(StringUtils.isBlank(officehonor.getId())){
+			Office office = UserUtils.getSelectOffice();
+			officehonor.setCompanyName(office.getParent().getName());
+			officehonor.setUploadDate(new Date());
+		}
+		model.addAttribute("officehonor", officehonor);
+		String view=request.getParameter("tabId");
+		if(StringUtils.isNotBlank(view) && view.equals("view")){
+			return "modules/officehonor/officehonorView";
+		}
+		return "modules/officehonor/officehonorForm";
+	}
+
+	/**
+	 * 保存企业荣誉
+	 */
+	@RequiresPermissions(value={"officehonor:officehonor:add","officehonor:officehonor:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(Officehonor officehonor, Model model,HttpServletRequest request, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, officehonor)){
+			return form(officehonor, model,request);
+		}
+		if(!officehonor.getIsNewRecord()){//编辑表单保存
+			Officehonor t = officehonorService.get(officehonor.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(officehonor, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			officehonorService.save(t);//保存
+		}else{//新增表单保存
+			/*Office office = UserUtils.getSelectCompany();
+			officehonor.setOffice(office);//当前用户所在企业*/
+			officehonor.setCompanyId(UserUtils.getSelectCompany().getId());
+			officehonorService.save(officehonor);//保存
+		}
+		addMessage(redirectAttributes, "保存企业荣誉成功");
+		return "redirect:"+Global.getAdminPath()+"/officehonor/officehonor/?repage";
+	}
+	
+	/**
+	 * 删除企业荣誉
+	 */
+	@RequiresPermissions("officehonor:officehonor:del")
+	@RequestMapping(value = "delete")
+	public String delete(Officehonor officehonor, RedirectAttributes redirectAttributes) {
+		officehonorService.delete(officehonor);
+		addMessage(redirectAttributes, "删除企业荣誉成功");
+		return "redirect:"+Global.getAdminPath()+"/officehonor/officehonor/?repage";
+	}
+	
+	/**
+	 * 批量删除企业荣誉
+	 */
+	@RequiresPermissions("officehonor:officehonor:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			officehonorService.delete(officehonorService.get(id));
+		}
+		addMessage(redirectAttributes, "删除企业荣誉成功");
+		return "redirect:"+Global.getAdminPath()+"/officehonor/officehonor/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("officehonor:officehonor:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(Officehonor officehonor, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业荣誉"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<Officehonor> page = officehonorService.findPage(new Page<Officehonor>(request, response, -1), officehonor);
+    		new ExportExcel("企业荣誉", Officehonor.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出企业荣誉记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officehonor/officehonor/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("officehonor:officehonor:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<Officehonor> list = ei.getDataList(Officehonor.class);
+			for (Officehonor officehonor : list){
+				try{
+					officehonorService.save(officehonor);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条企业荣誉记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条企业荣誉记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入企业荣誉失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officehonor/officehonor/?repage";
+    }
+	
+	/**
+	 * 下载导入企业荣誉数据模板
+	 */
+	@RequiresPermissions("officehonor:officehonor:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业荣誉数据导入模板.xlsx";
+    		List<Officehonor> list = Lists.newArrayList(); 
+    		new ExportExcel("企业荣誉数据", Officehonor.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officehonor/officehonor/?repage";
+    }
+	
+	
+	/**
+	 * 选择企业外键
+	 */
+	@RequestMapping(value = "selectoffice")
+	public String selectoffice(Office office, String url, String fieldLabels, String fieldKeys, String searchLabel, String searchKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<Office> page = officehonorService.findPageByoffice(new Page<Office>(request, response),  office);
+		try {
+			fieldLabels = URLDecoder.decode(fieldLabels, "UTF-8");
+			fieldKeys = URLDecoder.decode(fieldKeys, "UTF-8");
+			searchLabel = URLDecoder.decode(searchLabel, "UTF-8");
+			searchKey = URLDecoder.decode(searchKey, "UTF-8");
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		model.addAttribute("labelNames", fieldLabels.split("\\|"));
+		model.addAttribute("labelValues", fieldKeys.split("\\|"));
+		model.addAttribute("fieldLabels", fieldLabels);
+		model.addAttribute("fieldKeys", fieldKeys);
+		model.addAttribute("url", url);
+		model.addAttribute("searchLabel", searchLabel);
+		model.addAttribute("searchKey", searchKey);
+		model.addAttribute("obj", office);
+		model.addAttribute("page", page);
+		return "modules/sys/gridselect";
+	}
+	//--- 上传图片
+	private void upload_image(MultipartFile[] next_upload_files, HttpServletRequest request, StringBuilder office_himage){
+		String  next_uploadFolder = request.getSession().getServletContext().getRealPath("local_upload/office_himage/"+System.nanoTime());
+		new File(next_uploadFolder).mkdirs();
+		List<String> next_imgList = new ArrayList<>();
+		if(next_upload_files!=null && next_upload_files.length>0){
+			for(int i=0;i<next_upload_files.length;i++){
+				if(next_upload_files[i]==null || next_upload_files[i].getSize()==0)
+					continue;
+				String imageName = System.nanoTime()+next_upload_files[i].getOriginalFilename();
+				String imageNewName = next_uploadFolder+"/"+imageName;
+				next_imgList.add(imageNewName);
+				try{
+					next_upload_files[i].transferTo(new File(imageNewName));
+				}catch (IllegalStateException | IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		InputStream next_inputStream = null;
+		for(int i=0;i<next_imgList.size();i++) {
+			String filePath = next_imgList.get(i);
+			try {
+				next_inputStream = new FileInputStream(new File(filePath));
+				OSSClientUtil ossUtil = new OSSClientUtil();
+				String suffix = filePath.substring(filePath.lastIndexOf("."));
+				String name = System.nanoTime() + suffix;
+				ossUtil.uploadFile2OSS(next_inputStream, Global.getLogo(), name);
+				office_himage.append(Global.getAliyunUrl() + "/" + Global.getLogo() + name + ",");
+			} catch (IOException e) {
+				e.printStackTrace();
+			} finally {
+				try {
+					if (next_inputStream != null)
+						next_inputStream.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+}

+ 22 - 0
src/main/java/com/jeeplus/modules/officeintroduce/dao/OfficeintroduceDao.java

@@ -0,0 +1,22 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officeintroduce.dao;
+
+import com.jeeplus.modules.sys.entity.Office;
+import java.util.List;
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.officeintroduce.entity.Officeintroduce;
+
+/**
+ * 企业介绍DAO接口
+ * @author liuw
+ * @version 2017-12-05
+ */
+@MyBatisDao
+public interface OfficeintroduceDao extends CrudDao<Officeintroduce> {
+
+	public List<Office> findListByoffice(Office office);
+	
+}

+ 116 - 0
src/main/java/com/jeeplus/modules/officeintroduce/entity/Officeintroduce.java

@@ -0,0 +1,116 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officeintroduce.entity;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.modules.sys.entity.Office;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 企业介绍Entity
+ * @author liuw
+ * @version 2017-12-05
+ */
+public class Officeintroduce extends DataEntity<Officeintroduce> {
+	//附件111    //编号模板25
+	public static final String SERIAL_BIZCODE = "25";
+	private static final long serialVersionUID = 1L;
+	private String introduce;		// 企业介绍
+	private Office office;		// 企业外键
+
+	private Date uploadDate; //上传日期
+	private String 	companyName;  //公司名称
+	private String num;  //编号(公司简称+4位流水)
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList(); //附件
+	//临时属性
+	private String url;
+	private String uName;
+	public Officeintroduce() {
+		super();
+	}
+	private String companyId;  //公司ID
+	public Officeintroduce(String id){
+		super(id);
+	}
+
+	@ExcelField(title="企业介绍", align=2, sort=7)
+	public String getIntroduce() {
+		return introduce;
+	}
+
+	public void setIntroduce(String introduce) {
+		this.introduce = introduce;
+	}
+	
+	@ExcelField(title="企业外键", align=2, sort=8)
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+
+	public Date getUploadDate() {
+		return uploadDate;
+	}
+
+	public void setUploadDate(Date uploadDate) {
+		this.uploadDate = uploadDate;
+	}
+
+	public String getCompanyName() {
+		return companyName;
+	}
+
+	public void setCompanyName(String companyName) {
+		this.companyName = companyName;
+	}
+
+	public String getNum() {
+		return num;
+	}
+
+	public void setNum(String num) {
+		this.num = num;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getuName() {
+		return uName;
+	}
+
+	public void setuName(String uName) {
+		this.uName = uName;
+	}
+}

+ 121 - 0
src/main/java/com/jeeplus/modules/officeintroduce/service/OfficeintroduceService.java

@@ -0,0 +1,121 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officeintroduce.service;
+
+import java.util.List;
+
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.officehonor.entity.Officehonor;
+import com.jeeplus.modules.serialnum.service.SerialNumTplService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.officeintroduce.entity.Officeintroduce;
+import com.jeeplus.modules.officeintroduce.dao.OfficeintroduceDao;
+
+/**
+ * 企业介绍Service
+ * @author liuw
+ * @version 2017-12-05
+ */
+@Service
+@Transactional(readOnly = true)
+public class OfficeintroduceService extends CrudService<OfficeintroduceDao, Officeintroduce> {
+	@Autowired
+	private WorkattachmentService workattachmentService;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+	@Autowired
+	private SerialNumTplService serialNumTplService;
+	@Autowired
+	private OfficeService officeService;
+
+	public Officeintroduce get(String id) {
+		Officeintroduce officeintroduce = super.get(id);
+		//附件
+		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
+		workClientAttachment.setAttachmentId(id);
+		workClientAttachment.setAttachmentFlag("111");
+		officeintroduce.setWorkAttachments(workClientAttachmentDao.findList(workClientAttachment));
+		return officeintroduce;
+	}
+	
+	public List<Officeintroduce> findList(Officeintroduce officeintroduce) {
+		return super.findList(officeintroduce);
+	}
+	
+	public Page<Officeintroduce> findPage(Page<Officeintroduce> page, Officeintroduce officeintroduce) {
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()){
+			if(officeintroduce.getOffice() == null || StringUtils.isBlank(officeintroduce.getOffice().getId())){
+				officeintroduce.setOffice(UserUtils.getSelectOffice().getParent());
+			}else{
+				Office office = officeService.get(officeintroduce.getOffice().getId());
+				if("1".equals(office.getType())){
+					//总公司
+					officeintroduce.setCompanyId(officeintroduce.getOffice().getId());
+				}else{
+					officeintroduce.setOffice(officeintroduce.getOffice());
+				}
+			}
+		}
+		officeintroduce.setPage(page);
+		page.setList(findList(officeintroduce));
+
+		return page;
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(Officeintroduce officeintroduce) {
+		super.save(officeintroduce);
+		if(StringUtils.isBlank(officeintroduce.getNum())){
+			officeintroduce.setNum(serialNumTplService.genSerialNum(UserUtils.get(officeintroduce.getCreateBy().getId()).getCompany(), Officeintroduce.SERIAL_BIZCODE));
+			super.save(officeintroduce);
+		}
+		//附件信息
+		for (WorkClientAttachment workClientAttachment : officeintroduce.getWorkAttachments()) {
+			if (workClientAttachment.getId() == null) {
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())) {
+				workClientAttachment.setAttachmentId(officeintroduce.getId());
+				workClientAttachment.setAttachmentFlag("111");
+				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())) {
+					workClientAttachment.preInsert();
+					workClientAttachmentDao.insert(workClientAttachment);
+				} else {
+					workClientAttachment.preUpdate();
+					workClientAttachmentDao.update(workClientAttachment);
+				}
+			} else {
+				workClientAttachmentDao.delete(workClientAttachment);
+			}
+		}
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(Officeintroduce officeintroduce) {
+		super.delete(officeintroduce);
+	}
+	
+	public Page<Office> findPageByoffice(Page<Office> page, Office office) {
+		office.setPage(page);
+		page.setList(dao.findListByoffice(office));
+		return page;
+	}
+	
+	
+	
+}

+ 237 - 0
src/main/java/com/jeeplus/modules/officeintroduce/web/OfficeintroduceController.java

@@ -0,0 +1,237 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officeintroduce.web;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.officeintroduce.entity.Officeintroduce;
+import com.jeeplus.modules.officeintroduce.service.OfficeintroduceService;
+
+/**
+ * 企业介绍Controller
+ * @author liuw
+ * @version 2017-12-05
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/officeintroduce/officeintroduce")
+public class OfficeintroduceController extends BaseController {
+
+	@Autowired
+	private OfficeintroduceService officeintroduceService;
+	
+	@ModelAttribute
+	public Officeintroduce get(@RequestParam(required=false) String id) {
+		Officeintroduce entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = officeintroduceService.get(id);
+		}
+		if (entity == null){
+			entity = new Officeintroduce();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 企业介绍列表页面
+	 */
+	@RequiresPermissions("officeintroduce:officeintroduce:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(Officeintroduce officeintroduce, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<Officeintroduce> page = officeintroduceService.findPage(new Page<Officeintroduce>(request, response), officeintroduce);
+		model.addAttribute("page", page);
+		return "modules/officeintroduce/officeintroduceList";
+	}
+
+	/**
+	 * 查看,增加,编辑企业介绍表单页面
+	 */
+	@RequiresPermissions(value={"officeintroduce:officeintroduce:view","officeintroduce:officeintroduce:add","officeintroduce:officeintroduce:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(Officeintroduce officeintroduce, Model model,HttpServletRequest request) {
+
+		if(StringUtils.isBlank(officeintroduce.getId())){
+			Office office = UserUtils.getSelectOffice();
+			officeintroduce.setCompanyName(office.getParent().getName());
+			officeintroduce.setUploadDate(new Date());
+		}
+		model.addAttribute("officeintroduce", officeintroduce);
+		String view=request.getParameter("tabId");
+		if(StringUtils.isNotBlank(view) && view.equals("view")){
+			return "modules/officeintroduce/officeintroduceView";
+		}
+		return "modules/officeintroduce/officeintroduceForm";
+	}
+
+	/**
+	 * 保存企业介绍
+	 */
+	@RequiresPermissions(value={"officeintroduce:officeintroduce:add","officeintroduce:officeintroduce:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(Officeintroduce officeintroduce, Model model, RedirectAttributes redirectAttributes,HttpServletRequest request) throws Exception{
+		if (!beanValidator(model, officeintroduce)){
+			return form(officeintroduce, model,request);
+		}
+		if(!officeintroduce.getIsNewRecord()){//编辑表单保存
+			Officeintroduce t = officeintroduceService.get(officeintroduce.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(officeintroduce, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			officeintroduceService.save(t);//保存
+		}else{//新增表单保存
+			officeintroduce.setCompanyId(UserUtils.getSelectCompany().getId());
+			officeintroduceService.save(officeintroduce);//保存
+		}
+		addMessage(redirectAttributes, "保存企业介绍成功");
+		return "redirect:"+Global.getAdminPath()+"/officeintroduce/officeintroduce/?repage";
+	}
+	
+	/**
+	 * 删除企业介绍
+	 */
+	@RequiresPermissions("officeintroduce:officeintroduce:del")
+	@RequestMapping(value = "delete")
+	public String delete(Officeintroduce officeintroduce, RedirectAttributes redirectAttributes) {
+		officeintroduceService.delete(officeintroduce);
+		addMessage(redirectAttributes, "删除企业介绍成功");
+		return "redirect:"+Global.getAdminPath()+"/officeintroduce/officeintroduce/?repage";
+	}
+	
+	/**
+	 * 批量删除企业介绍
+	 */
+	@RequiresPermissions("officeintroduce:officeintroduce:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			officeintroduceService.delete(officeintroduceService.get(id));
+		}
+		addMessage(redirectAttributes, "删除企业介绍成功");
+		return "redirect:"+Global.getAdminPath()+"/officeintroduce/officeintroduce/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("officeintroduce:officeintroduce:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(Officeintroduce officeintroduce, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业介绍"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<Officeintroduce> page = officeintroduceService.findPage(new Page<Officeintroduce>(request, response, -1), officeintroduce);
+    		new ExportExcel("企业介绍", Officeintroduce.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出企业介绍记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officeintroduce/officeintroduce/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("officeintroduce:officeintroduce:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<Officeintroduce> list = ei.getDataList(Officeintroduce.class);
+			for (Officeintroduce officeintroduce : list){
+				try{
+					officeintroduceService.save(officeintroduce);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条企业介绍记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条企业介绍记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入企业介绍失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officeintroduce/officeintroduce/?repage";
+    }
+	
+	/**
+	 * 下载导入企业介绍数据模板
+	 */
+	@RequiresPermissions("officeintroduce:officeintroduce:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业介绍数据导入模板.xlsx";
+    		List<Officeintroduce> list = Lists.newArrayList(); 
+    		new ExportExcel("企业介绍数据", Officeintroduce.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officeintroduce/officeintroduce/?repage";
+    }
+	
+	
+	/**
+	 * 选择企业外键
+	 */
+	@RequestMapping(value = "selectoffice")
+	public String selectoffice(Office office, String url, String fieldLabels, String fieldKeys, String searchLabel, String searchKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<Office> page = officeintroduceService.findPageByoffice(new Page<Office>(request, response),  office);
+		try {
+			fieldLabels = URLDecoder.decode(fieldLabels, "UTF-8");
+			fieldKeys = URLDecoder.decode(fieldKeys, "UTF-8");
+			searchLabel = URLDecoder.decode(searchLabel, "UTF-8");
+			searchKey = URLDecoder.decode(searchKey, "UTF-8");
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		model.addAttribute("labelNames", fieldLabels.split("\\|"));
+		model.addAttribute("labelValues", fieldKeys.split("\\|"));
+		model.addAttribute("fieldLabels", fieldLabels);
+		model.addAttribute("fieldKeys", fieldKeys);
+		model.addAttribute("url", url);
+		model.addAttribute("searchLabel", searchLabel);
+		model.addAttribute("searchKey", searchKey);
+		model.addAttribute("obj", office);
+		model.addAttribute("page", page);
+		return "modules/sys/gridselect";
+	}
+	
+
+}

+ 19 - 0
src/main/java/com/jeeplus/modules/officelicense/dao/OfficeLicenseDao.java

@@ -0,0 +1,19 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officelicense.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.officelicense.entity.OfficeLicense;
+
+/**
+ * 企业证照DAO接口
+ * @author lw
+ * @version 2018-08-14
+ */
+@MyBatisDao
+public interface OfficeLicenseDao extends CrudDao<OfficeLicense> {
+
+	
+}

+ 130 - 0
src/main/java/com/jeeplus/modules/officelicense/entity/OfficeLicense.java

@@ -0,0 +1,130 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officelicense.entity;
+
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+/**
+ * 企业证照Entity
+ * @author lw
+ * @version 2018-08-14
+ */
+public class OfficeLicense extends DataEntity<OfficeLicense> {
+	//附件112   //编号模板26
+	public static final String SERIAL_BIZCODE = "26";
+	private static final long serialVersionUID = 1L;
+	private String companyName;		// 公司名称
+	private String num;		// 编号
+	private Date uploadDate;		// 上传时间
+	private Office office;		// 企业外键
+	private String name;		// 证照名称
+	private String isChapter;		// 是否电子章
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList(); //附件
+	private String companyId;  //公司ID
+	//临时属性
+	private String url;
+	private String uName;
+	public OfficeLicense() {
+		super();
+	}
+
+	public OfficeLicense(String id){
+		super(id);
+	}
+
+	@ExcelField(title="公司名称", align=2, sort=7)
+	public String getCompanyName() {
+		return companyName;
+	}
+
+	public void setCompanyName(String companyName) {
+		this.companyName = companyName;
+	}
+	
+	@ExcelField(title="编号", align=2, sort=8)
+	public String getNum() {
+		return num;
+	}
+
+	public void setNum(String num) {
+		this.num = num;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="上传时间", align=2, sort=9)
+	public Date getUploadDate() {
+		return uploadDate;
+	}
+
+	public void setUploadDate(Date uploadDate) {
+		this.uploadDate = uploadDate;
+	}
+
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getuName() {
+		return uName;
+	}
+
+	public void setuName(String uName) {
+		this.uName = uName;
+	}
+
+	@ExcelField(title="证照名称", align=2, sort=11)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@ExcelField(title="是否电子章", align=2, sort=12)
+	public String getIsChapter() {
+		return isChapter;
+	}
+
+	public void setIsChapter(String isChapter) {
+		this.isChapter = isChapter;
+	}
+
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+}

+ 117 - 0
src/main/java/com/jeeplus/modules/officelicense/service/OfficeLicenseService.java

@@ -0,0 +1,117 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officelicense.service;
+
+import java.util.List;
+
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.officehonor.entity.Officehonor;
+import com.jeeplus.modules.serialnum.service.SerialNumTplService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.officelicense.entity.OfficeLicense;
+import com.jeeplus.modules.officelicense.dao.OfficeLicenseDao;
+
+/**
+ * 企业证照Service
+ * @author lw
+ * @version 2018-08-14
+ */
+@Service
+@Transactional(readOnly = true)
+public class OfficeLicenseService extends CrudService<OfficeLicenseDao, OfficeLicense> {
+	@Autowired
+	private WorkattachmentService workattachmentService;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+	@Autowired
+	private SerialNumTplService serialNumTplService;
+
+	@Autowired
+	private OfficeService officeService;
+
+	public OfficeLicense get(String id) {
+		OfficeLicense officequalify = super.get(id);
+		//附件
+		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
+		workClientAttachment.setAttachmentId(id);
+		workClientAttachment.setAttachmentFlag("112");
+		officequalify.setWorkAttachments(workClientAttachmentDao.findList(workClientAttachment));
+		return officequalify;
+	}
+	
+	public List<OfficeLicense> findList(OfficeLicense officeLicense) {
+		return super.findList(officeLicense);
+	}
+	
+	public Page<OfficeLicense> findPage(Page<OfficeLicense> page, OfficeLicense officeLicense) {
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()) {
+			if (officeLicense.getOffice() == null || StringUtils.isBlank(officeLicense.getOffice().getId())) {
+				officeLicense.setOffice(UserUtils.getSelectOffice().getParent());
+			} else {
+				Office office = officeService.get(officeLicense.getOffice().getId());
+				if ("1".equals(office.getType())) {
+					//总公司
+					officeLicense.setCompanyId(officeLicense.getOffice().getId());
+				} else {
+					officeLicense.setOffice(officeLicense.getOffice());
+				}
+			}
+		}
+		officeLicense.setPage(page);
+		page.setList(findList(officeLicense));
+
+		return page;
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(OfficeLicense officeLicense) {
+		super.save(officeLicense);
+		if(StringUtils.isBlank(officeLicense.getNum())){
+			officeLicense.setNum(serialNumTplService.genSerialNum(UserUtils.get(officeLicense.getCreateBy().getId()).getCompany(), OfficeLicense.SERIAL_BIZCODE));
+			super.save(officeLicense);
+		}
+		//附件信息
+		for (WorkClientAttachment workClientAttachment : officeLicense.getWorkAttachments()) {
+			if (workClientAttachment.getId() == null) {
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())) {
+				workClientAttachment.setAttachmentId(officeLicense.getId());
+				workClientAttachment.setAttachmentFlag("112");
+				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())) {
+					workClientAttachment.preInsert();
+					workClientAttachmentDao.insert(workClientAttachment);
+				} else {
+					workClientAttachment.preUpdate();
+					workClientAttachmentDao.update(workClientAttachment);
+				}
+			} else {
+				workClientAttachmentDao.delete(workClientAttachment);
+			}
+		}
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(OfficeLicense officeLicense) {
+		super.delete(officeLicense);
+	}
+	
+	
+	
+	
+}

+ 212 - 0
src/main/java/com/jeeplus/modules/officelicense/web/OfficeLicenseController.java

@@ -0,0 +1,212 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officelicense.web;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.officelicense.entity.OfficeLicense;
+import com.jeeplus.modules.officelicense.service.OfficeLicenseService;
+
+/**
+ * 企业证照Controller
+ * @author lw
+ * @version 2018-08-14
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/officelicense/officeLicense")
+public class OfficeLicenseController extends BaseController {
+
+	@Autowired
+	private OfficeLicenseService officeLicenseService;
+	@Autowired
+	private HttpServletRequest request;
+	@ModelAttribute
+	public OfficeLicense get(@RequestParam(required=false) String id) {
+		OfficeLicense entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = officeLicenseService.get(id);
+		}
+		if (entity == null){
+			entity = new OfficeLicense();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 企业证照列表页面
+	 */
+	@RequiresPermissions("officelicense:officeLicense:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(OfficeLicense officeLicense, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<OfficeLicense> page = officeLicenseService.findPage(new Page<OfficeLicense>(request, response), officeLicense); 
+		model.addAttribute("page", page);
+		return "modules/officelicense/officeLicenseList";
+	}
+
+	/**
+	 * 查看,增加,编辑企业证照表单页面
+	 */
+	@RequiresPermissions(value={"officelicense:officeLicense:view","officelicense:officeLicense:add","officelicense:officeLicense:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(OfficeLicense officeLicense, Model model) {
+
+		if(StringUtils.isBlank(officeLicense.getId())){
+			Office office = UserUtils.getSelectOffice();
+			officeLicense.setCompanyName(office.getParent().getName());
+			officeLicense.setUploadDate(new Date());
+		}
+		model.addAttribute("officeLicense", officeLicense);
+		String view=request.getParameter("tabId");
+		if(StringUtils.isNotBlank(view) && view.equals("view")){
+			return "modules/officelicense/officeLicenseView";
+		}
+
+		return "modules/officelicense/officeLicenseForm";
+	}
+
+	/**
+	 * 保存企业证照
+	 */
+	@RequiresPermissions(value={"officelicense:officeLicense:add","officelicense:officeLicense:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(OfficeLicense officeLicense, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, officeLicense)){
+			return form(officeLicense, model);
+		}
+		if(!officeLicense.getIsNewRecord()){//编辑表单保存
+			OfficeLicense t = officeLicenseService.get(officeLicense.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(officeLicense, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			officeLicenseService.save(t);//保存
+		}else{//新增表单保存
+			officeLicense.setCompanyId(UserUtils.getSelectCompany().getId());
+			officeLicenseService.save(officeLicense);//保存
+		}
+		addMessage(redirectAttributes, "保存企业证照成功");
+		return "redirect:"+Global.getAdminPath()+"/officelicense/officeLicense/?repage";
+	}
+	
+	/**
+	 * 删除企业证照
+	 */
+	@RequiresPermissions("officelicense:officeLicense:del")
+	@RequestMapping(value = "delete")
+	public String delete(OfficeLicense officeLicense, RedirectAttributes redirectAttributes) {
+		officeLicenseService.delete(officeLicense);
+		addMessage(redirectAttributes, "删除企业证照成功");
+		return "redirect:"+Global.getAdminPath()+"/officelicense/officeLicense/?repage";
+	}
+	
+	/**
+	 * 批量删除企业证照
+	 */
+	@RequiresPermissions("officelicense:officeLicense:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			officeLicenseService.delete(officeLicenseService.get(id));
+		}
+		addMessage(redirectAttributes, "删除企业证照成功");
+		return "redirect:"+Global.getAdminPath()+"/officelicense/officeLicense/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("officelicense:officeLicense:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(OfficeLicense officeLicense, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业证照"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<OfficeLicense> page = officeLicenseService.findPage(new Page<OfficeLicense>(request, response, -1), officeLicense);
+    		new ExportExcel("企业证照", OfficeLicense.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出企业证照记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officelicense/officeLicense/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("officelicense:officeLicense:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<OfficeLicense> list = ei.getDataList(OfficeLicense.class);
+			for (OfficeLicense officeLicense : list){
+				try{
+					officeLicenseService.save(officeLicense);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条企业证照记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条企业证照记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入企业证照失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officelicense/officeLicense/?repage";
+    }
+	
+	/**
+	 * 下载导入企业证照数据模板
+	 */
+	@RequiresPermissions("officelicense:officeLicense:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业证照数据导入模板.xlsx";
+    		List<OfficeLicense> list = Lists.newArrayList(); 
+    		new ExportExcel("企业证照数据", OfficeLicense.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officelicense/officeLicense/?repage";
+    }
+	
+	
+	
+
+}

+ 22 - 0
src/main/java/com/jeeplus/modules/officequalify/dao/OfficequalifyDao.java

@@ -0,0 +1,22 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officequalify.dao;
+
+import com.jeeplus.modules.sys.entity.Office;
+import java.util.List;
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.officequalify.entity.Officequalify;
+
+/**
+ * 企业资质DAO接口
+ * @author liuw
+ * @version 2017-12-05
+ */
+@MyBatisDao
+public interface OfficequalifyDao extends CrudDao<Officequalify> {
+
+	public List<Office> findListByoffice(Office office);
+	
+}

+ 201 - 0
src/main/java/com/jeeplus/modules/officequalify/entity/Officequalify.java

@@ -0,0 +1,201 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officequalify.entity;
+
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.google.common.collect.Lists;
+import com.jeeplus.modules.sys.entity.Office;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+/**
+ * 企业资质Entity
+ * @author liuw
+ * @version 2017-12-05
+ */
+public class Officequalify extends DataEntity<Officequalify> {
+	//附件 109   //编号模板23
+	public static final String SERIAL_BIZCODE = "23";
+	private static final long serialVersionUID = 1L;
+	private String name;		// 资质名称
+	private String qualifyGrade;		// 资质等级
+	private String specialty;		// 专业
+	private Date firstDate;		// 初次取得时间
+	private Date endDate;		// 到期时间
+	private Date continueDate;		// 延续注册时间
+	private String issuedAgency;		// 颁发机构
+	private String introduction;		// 企业简介
+	private String image;		// 图片
+	private Office office;		// 企业外键
+	private String companyId;  //公司ID
+	private String 	companyName;  //公司名称
+	private String num;  //编号(公司简称+4位流水)
+	private Date uploadDate; //上传日期
+	private List<WorkClientAttachment> workAttachments = Lists.newArrayList(); //附件
+
+	private String url;
+	private String uName;
+
+	public Officequalify() {
+		super();
+	}
+
+	public Officequalify(String id){
+		super(id);
+	}
+
+	@ExcelField(title="资质名称", align=2, sort=7)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@ExcelField(title="资质等级", dictType="qualify_grade", align=2, sort=8)
+	public String getQualifyGrade() {
+		return qualifyGrade;
+	}
+
+	public void setQualifyGrade(String qualifyGrade) {
+		this.qualifyGrade = qualifyGrade;
+	}
+
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+
+	@ExcelField(title="专业", align=2, sort=9)
+	public String getSpecialty() {
+		return specialty;
+	}
+
+	public void setSpecialty(String specialty) {
+		this.specialty = specialty;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="初次取得时间", align=2, sort=10)
+	public Date getFirstDate() {
+		return firstDate;
+	}
+
+	public void setFirstDate(Date firstDate) {
+		this.firstDate = firstDate;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="到期时间", align=2, sort=11)
+	public Date getEndDate() {
+		return endDate;
+	}
+
+	public void setEndDate(Date endDate) {
+		this.endDate = endDate;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="延续注册时间", align=2, sort=12)
+	public Date getContinueDate() {
+		return continueDate;
+	}
+
+	public void setContinueDate(Date continueDate) {
+		this.continueDate = continueDate;
+	}
+	
+	@ExcelField(title="颁发机构", align=2, sort=13)
+	public String getIssuedAgency() {
+		return issuedAgency;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getuName() {
+		return uName;
+	}
+
+	public void setuName(String uName) {
+		this.uName = uName;
+	}
+
+	public void setIssuedAgency(String issuedAgency) {
+		this.issuedAgency = issuedAgency;
+	}
+	
+	@ExcelField(title="企业简介", align=2, sort=14)
+	public String getIntroduction() {
+		return introduction;
+	}
+
+	public void setIntroduction(String introduction) {
+		this.introduction = introduction;
+	}
+	
+	@ExcelField(title="图片", align=2, sort=15)
+	public String getImage() {
+		return image;
+	}
+
+	public void setImage(String image) {
+		this.image = image;
+	}
+	
+	@ExcelField(title="企业外键", align=2, sort=16)
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+
+	public String getCompanyName() {
+		return companyName;
+	}
+
+	public void setCompanyName(String companyName) {
+		this.companyName = companyName;
+	}
+
+	public String getNum() {
+		return num;
+	}
+
+	public void setNum(String num) {
+		this.num = num;
+	}
+
+	public Date getUploadDate() {
+		return uploadDate;
+	}
+
+	public void setUploadDate(Date uploadDate) {
+		this.uploadDate = uploadDate;
+	}
+
+	public List<WorkClientAttachment> getWorkAttachments() {
+		return workAttachments;
+	}
+
+	public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+		this.workAttachments = workAttachments;
+	}
+}

+ 132 - 0
src/main/java/com/jeeplus/modules/officequalify/service/OfficequalifyService.java

@@ -0,0 +1,132 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officequalify.service;
+
+import java.util.List;
+
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.serialnum.service.SerialNumTplService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.officequalify.entity.Officequalify;
+import com.jeeplus.modules.officequalify.dao.OfficequalifyDao;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 企业资质Service
+ * @author liuw
+ * @version 2017-12-05
+ */
+@Service
+@Transactional(readOnly = true)
+public class OfficequalifyService extends CrudService<OfficequalifyDao, Officequalify> {
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+	@Autowired
+	private SerialNumTplService serialNumTplService;
+	@Autowired
+	private OfficeService officeService;
+
+	public Officequalify get(String id) {
+		Officequalify officequalify = super.get(id);
+		//附件
+		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
+		workClientAttachment.setAttachmentId(id);
+		workClientAttachment.setAttachmentFlag("109");
+		officequalify.setWorkAttachments(workClientAttachmentDao.findList(workClientAttachment));
+		return officequalify;
+	}
+	
+	public List<Officequalify> findList(Officequalify officequalify) {
+		return super.findList(officequalify);
+	}
+	
+	public Page<Officequalify> findPage(Page<Officequalify> page, Officequalify officequalify) {
+		User user = UserUtils.getUser();
+		if (!user.isAdmin()) {
+			if (officequalify.getOffice() == null || StringUtils.isBlank(officequalify.getOffice().getId())) {
+				officequalify.setOffice(UserUtils.getSelectOffice().getParent());
+			} else {
+				Office office = officeService.get(officequalify.getOffice().getId());
+				if ("1".equals(office.getType())) {
+					//总公司
+					officequalify.setCompanyId(officequalify.getOffice().getId());
+				} else {
+					officequalify.setOffice(officequalify.getOffice());
+				}
+			}
+		}
+		officequalify.setPage(page);
+		page.setList(findList(officequalify));
+
+		return page;
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(Officequalify officequalify) {
+	/*	if (!file.isEmpty() && file.getSize() > 0) {
+			OSSClientUtil ossClientUtil = new OSSClientUtil();
+			String fileName = file.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
+			String url = ossClientUtil.uploadFile2OSS(file, "Officehonor");
+			officequalify.setImage(url);
+			*//*Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(url);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentName(fileName);
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentId(officehonor.getId());
+			workattachment.setAttachmentFlag("60");
+			workattachmentService.save(workattachment);*//*
+		}*/
+		super.save(officequalify);
+		if(StringUtils.isBlank(officequalify.getNum())){
+			officequalify.setNum(serialNumTplService.genSerialNum(UserUtils.get(officequalify.getCreateBy().getId()).getCompany(), Officequalify.SERIAL_BIZCODE));
+			super.save(officequalify);
+		}
+		//附件信息
+		for (WorkClientAttachment workClientAttachment : officequalify.getWorkAttachments()) {
+			if (workClientAttachment.getId() == null) {
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())) {
+				workClientAttachment.setAttachmentId(officequalify.getId());
+				workClientAttachment.setAttachmentFlag("109");
+				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())) {
+					workClientAttachment.preInsert();
+					workClientAttachmentDao.insert(workClientAttachment);
+				} else {
+					workClientAttachment.preUpdate();
+					workClientAttachmentDao.update(workClientAttachment);
+				}
+			} else {
+				workClientAttachmentDao.delete(workClientAttachment);
+			}
+		}
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(Officequalify officequalify) {
+		super.delete(officequalify);
+	}
+	
+	public Page<Office> findPageByoffice(Page<Office> page, Office office) {
+		office.setPage(page);
+		page.setList(dao.findListByoffice(office));
+		return page;
+	}
+}

+ 237 - 0
src/main/java/com/jeeplus/modules/officequalify/web/OfficequalifyController.java

@@ -0,0 +1,237 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.officequalify.web;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.jeeplus.modules.sys.entity.Office;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.officequalify.entity.Officequalify;
+import com.jeeplus.modules.officequalify.service.OfficequalifyService;
+
+/**
+ * 企业资质Controller
+ * @author liuw
+ * @version 2017-12-05
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/officequalify/officequalify")
+public class OfficequalifyController extends BaseController {
+
+	@Autowired
+	private OfficequalifyService officequalifyService;
+	
+	@ModelAttribute
+	public Officequalify get(@RequestParam(required=false) String id) {
+		Officequalify entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = officequalifyService.get(id);
+		}
+		if (entity == null){
+			entity = new Officequalify();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 企业资质列表页面
+	 */
+	@RequiresPermissions("officequalify:officequalify:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(Officequalify officequalify, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<Officequalify> page = officequalifyService.findPage(new Page<Officequalify>(request, response), officequalify);
+		model.addAttribute("page", page);
+		return "modules/officequalify/officequalifyList";
+	}
+
+	/**
+	 * 查看,增加,编辑企业资质表单页面
+	 */
+	@RequiresPermissions(value={"officequalify:officequalify:view","officequalify:officequalify:add","officequalify:officequalify:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(Officequalify officequalify, Model model,HttpServletRequest request) {
+		if(StringUtils.isBlank(officequalify.getId())){
+			Office office = UserUtils.getSelectOffice();
+			officequalify.setCompanyName(office.getParent().getName());
+			officequalify.setUploadDate(new Date());
+		}
+		model.addAttribute("officequalify", officequalify);
+		String view=request.getParameter("tabId");
+		if(StringUtils.isNotBlank(view) && view.equals("view")){
+			return "modules/officequalify/officequalifyView";
+		}
+		return "modules/officequalify/officequalifyForm";
+	}
+
+	/**
+	 * 保存企业资质
+	 */
+	@RequiresPermissions(value={"officequalify:officequalify:add","officequalify:officequalify:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(Officequalify officequalify, Model model, RedirectAttributes redirectAttributes,HttpServletRequest request) throws Exception{
+	//public String save(Officequalify officequalify, Model model, RedirectAttributes redirectAttributes,@RequestParam("next_upload_files") MultipartFile next_upload_files,HttpServletRequest request) throws Exception{
+		if (!beanValidator(model, officequalify)){
+			return form(officequalify, model,request);
+		}
+		if(!officequalify.getIsNewRecord()){//编辑表单保存
+			Officequalify t = officequalifyService.get(officequalify.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(officequalify, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			officequalifyService.save(t);//保存
+		}else{//新增表单保存
+			officequalify.setCompanyId(UserUtils.getSelectCompany().getId());
+			officequalifyService.save(officequalify);//保存
+		}
+		addMessage(redirectAttributes, "保存企业资质成功");
+		return "redirect:"+Global.getAdminPath()+"/officequalify/officequalify/?repage";
+	}
+	
+	/**
+	 * 删除企业资质
+	 */
+	@RequiresPermissions("officequalify:officequalify:del")
+	@RequestMapping(value = "delete")
+	public String delete(Officequalify officequalify, RedirectAttributes redirectAttributes) {
+		officequalifyService.delete(officequalify);
+		addMessage(redirectAttributes, "删除企业资质成功");
+		return "redirect:"+Global.getAdminPath()+"/officequalify/officequalify/?repage";
+	}
+	
+	/**
+	 * 批量删除企业资质
+	 */
+	@RequiresPermissions("officequalify:officequalify:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			officequalifyService.delete(officequalifyService.get(id));
+		}
+		addMessage(redirectAttributes, "删除企业资质成功");
+		return "redirect:"+Global.getAdminPath()+"/officequalify/officequalify/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("officequalify:officequalify:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(Officequalify officequalify, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业资质"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<Officequalify> page = officequalifyService.findPage(new Page<Officequalify>(request, response, -1), officequalify);
+    		new ExportExcel("企业资质", Officequalify.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出企业资质记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officequalify/officequalify/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("officequalify:officequalify:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+		try {
+			int successNum = 0;
+			int failureNum = 0;
+			StringBuilder failureMsg = new StringBuilder();
+			ImportExcel ei = new ImportExcel(file, 1, 0);
+			List<Officequalify> list = ei.getDataList(Officequalify.class);
+			for (Officequalify officequalify : list){
+				try{
+					officequalifyService.save(officequalify);
+					successNum++;
+				}catch(ConstraintViolationException ex){
+					failureNum++;
+				}catch (Exception ex) {
+					failureNum++;
+				}
+			}
+			if (failureNum>0){
+				failureMsg.insert(0, ",失败 "+failureNum+" 条企业资质记录。");
+			}
+			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条企业资质记录"+failureMsg);
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入企业资质失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officequalify/officequalify/?repage";
+    }
+	
+	/**
+	 * 下载导入企业资质数据模板
+	 */
+	@RequiresPermissions("officequalify:officequalify:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "企业资质数据导入模板.xlsx";
+    		List<Officequalify> list = Lists.newArrayList(); 
+    		new ExportExcel("企业资质数据", Officequalify.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/officequalify/officequalify/?repage";
+    }
+	
+	
+	/**
+	 * 选择企业外键
+	 */
+	@RequestMapping(value = "selectoffice")
+	public String selectoffice(Office office, String url, String fieldLabels, String fieldKeys, String searchLabel, String searchKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<Office> page = officequalifyService.findPageByoffice(new Page<Office>(request, response),  office);
+		try {
+			fieldLabels = URLDecoder.decode(fieldLabels, "UTF-8");
+			fieldKeys = URLDecoder.decode(fieldKeys, "UTF-8");
+			searchLabel = URLDecoder.decode(searchLabel, "UTF-8");
+			searchKey = URLDecoder.decode(searchKey, "UTF-8");
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		model.addAttribute("labelNames", fieldLabels.split("\\|"));
+		model.addAttribute("labelValues", fieldKeys.split("\\|"));
+		model.addAttribute("fieldLabels", fieldLabels);
+		model.addAttribute("fieldKeys", fieldKeys);
+		model.addAttribute("url", url);
+		model.addAttribute("searchLabel", searchLabel);
+		model.addAttribute("searchKey", searchKey);
+		model.addAttribute("obj", office);
+		model.addAttribute("page", page);
+		return "modules/sys/gridselect";
+	}
+	
+
+}