chengqiang 5 jaren geleden
bovenliggende
commit
d0ca8d880f
100 gewijzigde bestanden met toevoegingen van 20582 en 0 verwijderingen
  1. 12 0
      src/main/java/com/easemob/server/example/api/AuthTokenAPI.java
  2. 39 0
      src/main/java/com/easemob/server/example/api/impl/EasemobFile.java
  3. 33 0
      src/main/java/com/jeeplus/common/mapper/adapters/MapAdapter.java
  4. 48 0
      src/main/java/com/jeeplus/common/oss/OSSConfig.java
  5. 50 0
      src/main/java/com/jeeplus/common/persistence/dialect/db/HSQLDialect.java
  6. 104 0
      src/main/java/com/jeeplus/common/persistence/proxy/PaginationMapperProxy.java
  7. 65 0
      src/main/java/com/jeeplus/common/servlet/UserfilesDownloadServlet.java
  8. 391 0
      src/main/java/com/jeeplus/common/utils/JPushClientUtil.java
  9. 125 0
      src/main/java/com/jeeplus/common/utils/WordToPic.java
  10. 132 0
      src/main/java/com/jeeplus/common/utils/WorkDayUtils.java
  11. 994 0
      src/main/java/com/jeeplus/common/utils/excel/ExportExcel.java
  12. 637 0
      src/main/java/com/jeeplus/common/utils/excel/ImportExcel.java
  13. 260 0
      src/main/java/com/jeeplus/common/web/Servlets.java
  14. 260 0
      src/main/java/com/jeeplus/common/websocket/onchat/ChatServer_bak.java
  15. 89 0
      src/main/java/com/jeeplus/modules/API/iim/ImContactController.java
  16. 222 0
      src/main/java/com/jeeplus/modules/API/maillist/GroupController.java
  17. 1173 0
      src/main/java/com/jeeplus/modules/API/oa/AttendanceController.java
  18. 37 0
      src/main/java/com/jeeplus/modules/API/userinfo/ManageInfoController.java
  19. 258 0
      src/main/java/com/jeeplus/modules/API/works/manageCalendar/manageCalendarController.java
  20. 265 0
      src/main/java/com/jeeplus/modules/API/works/oaallccontroller/OaAController.java
  21. 309 0
      src/main/java/com/jeeplus/modules/API/works/oabuycontroller/OaBController.java
  22. 231 0
      src/main/java/com/jeeplus/modules/API/works/pushInfo/pushInfoCortroller.java
  23. 20 0
      src/main/java/com/jeeplus/modules/act/dao/ActDao.java
  24. 48 0
      src/main/java/com/jeeplus/modules/act/rest/GenericResponseWrapper.java
  25. 1089 0
      src/main/java/com/jeeplus/modules/act/service/ActTaskService.java
  26. 222 0
      src/main/java/com/jeeplus/modules/act/web/ActProcessController.java
  27. 54 0
      src/main/java/com/jeeplus/modules/casecategory/service/CaseCategoryService.java
  28. 50 0
      src/main/java/com/jeeplus/modules/caseexecuteinfo/service/CaseExecuteInfoService.java
  29. 50 0
      src/main/java/com/jeeplus/modules/casenorm/service/CaseNormService.java
  30. 97 0
      src/main/java/com/jeeplus/modules/casepeoplenorm/entity/CasePeopleNorm.java
  31. 50 0
      src/main/java/com/jeeplus/modules/casepeoplenorm/service/CasePeopleNormService.java
  32. 196 0
      src/main/java/com/jeeplus/modules/contractclient/web/WorkContractClientController.java
  33. 60 0
      src/main/java/com/jeeplus/modules/esignature/kinggridserver/KingGridServer.java
  34. 171 0
      src/main/java/com/jeeplus/modules/esignature/web/EsignatureController.java
  35. 27 0
      src/main/java/com/jeeplus/modules/exampleexpend/dao/ExampleExpendDao.java
  36. 26 0
      src/main/java/com/jeeplus/modules/exampleproject/dao/ExampleProjectDao.java
  37. 268 0
      src/main/java/com/jeeplus/modules/hr/service/UserInfoService.java
  38. 60 0
      src/main/java/com/jeeplus/modules/iim/entity/LayGroup.java
  39. 56 0
      src/main/java/com/jeeplus/modules/iim/service/MailBoxService.java
  40. 118 0
      src/main/java/com/jeeplus/modules/leaveapply/entity/LeaveCount.java
  41. 2946 0
      src/main/java/com/jeeplus/modules/leaveapply/service/LeaveApplyService.java
  42. 57 0
      src/main/java/com/jeeplus/modules/leaveapply/service/LeaveTaskService.java
  43. 196 0
      src/main/java/com/jeeplus/modules/leaveapply/web/LeaveCountController.java
  44. 58 0
      src/main/java/com/jeeplus/modules/mongo/web/UserMongoController.java
  45. 47 0
      src/main/java/com/jeeplus/modules/monitor/service/MonitorService.java
  46. 648 0
      src/main/java/com/jeeplus/modules/monitor/utils/Common.java
  47. 81 0
      src/main/java/com/jeeplus/modules/oa/entity/OaAttendancePlace.java
  48. 27 0
      src/main/java/com/jeeplus/modules/oa/service/OaAttendancePlaceService.java
  49. 169 0
      src/main/java/com/jeeplus/modules/oa/web/TestAuditController.java
  50. 201 0
      src/main/java/com/jeeplus/modules/officequalify/entity/Officequalify.java
  51. 187 0
      src/main/java/com/jeeplus/modules/project/entity/Projectgeneral.java
  52. 67 0
      src/main/java/com/jeeplus/modules/project/entity/Workprojectgroup.java
  53. 85 0
      src/main/java/com/jeeplus/modules/project/service/ProjectService.java
  54. 22 0
      src/main/java/com/jeeplus/modules/projectcontentinfo/dao/ProjectReportDataCompanyDao.java
  55. 40 0
      src/main/java/com/jeeplus/modules/projectcontentinfo/dao/ProjectcontentinfoDao.java
  56. 80 0
      src/main/java/com/jeeplus/modules/projectcontentinfo/service/ProjectBasedDataService.java
  57. 233 0
      src/main/java/com/jeeplus/modules/projectcontentinfo/web/ProjectReportDataController.java
  58. 1382 0
      src/main/java/com/jeeplus/modules/projectcontentinfo/web/ProjectcontentinfoController.java
  59. 273 0
      src/main/java/com/jeeplus/modules/projectcontroltable/web/ProjectControlTableController.java
  60. 537 0
      src/main/java/com/jeeplus/modules/projectrecord/web/ProjectRecordsAlterController.java
  61. 12 0
      src/main/java/com/jeeplus/modules/serialnum/exception/SerialGenException.java
  62. 148 0
      src/main/java/com/jeeplus/modules/sys/entity/Log.java
  63. 68 0
      src/main/java/com/jeeplus/modules/sys/interceptor/LogInterceptor.java
  64. 305 0
      src/main/java/com/jeeplus/modules/sys/utils/DictUtils.java
  65. 221 0
      src/main/java/com/jeeplus/modules/sys/web/SysRoleActivityController.java
  66. 23 0
      src/main/java/com/jeeplus/modules/sysmodular/dao/SysModularFieldDao.java
  67. 264 0
      src/main/java/com/jeeplus/modules/sysmodular/web/SysModularController.java
  68. 18 0
      src/main/java/com/jeeplus/modules/sysnumberclass/dao/SysNumberClassDao.java
  69. 69 0
      src/main/java/com/jeeplus/modules/sysnumberclass/entity/SysNumberClass.java
  70. 155 0
      src/main/java/com/jeeplus/modules/sysnumberinfo/entity/SysNumberInfo.java
  71. 50 0
      src/main/java/com/jeeplus/modules/sysparameter/service/SysParameterValueService.java
  72. 196 0
      src/main/java/com/jeeplus/modules/sysparameter/web/SysParameterValueController.java
  73. 19 0
      src/main/java/com/jeeplus/modules/syswarning/dao/SysWarningLogDao.java
  74. 196 0
      src/main/java/com/jeeplus/modules/syswarning/web/SysWarningUserController.java
  75. 19 0
      src/main/java/com/jeeplus/modules/test/dao/onetomany/TestDataChild3Dao.java
  76. 19 0
      src/main/java/com/jeeplus/modules/test/dao/validation/TestValidationDao.java
  77. 74 0
      src/main/java/com/jeeplus/modules/test/entity/onetomany/TestDataChild2.java
  78. 50 0
      src/main/java/com/jeeplus/modules/test/service/one/FormLeaveService.java
  79. 196 0
      src/main/java/com/jeeplus/modules/test/web/note/TestNoteController.java
  80. 18 0
      src/main/java/com/jeeplus/modules/tools/dao/TestInterfaceDao.java
  81. 43 0
      src/main/java/com/jeeplus/modules/work/dao/report/WorkReportDao.java
  82. 88 0
      src/main/java/com/jeeplus/modules/work/entity/report/WorkReportRecord.java
  83. 414 0
      src/main/java/com/jeeplus/modules/workactivity/service/WorkActivityProcessService.java
  84. 176 0
      src/main/java/com/jeeplus/modules/workadministrativeatamp/entity/WorkAdministrativeAtamp.java
  85. 56 0
      src/main/java/com/jeeplus/modules/workaftermath/service/WorkAftermathService.java
  86. 474 0
      src/main/java/com/jeeplus/modules/workaftermath/web/WorkAftermathController.java
  87. 72 0
      src/main/java/com/jeeplus/modules/workaftermath/web/WorkBidingProjectRdController.java
  88. 64 0
      src/main/java/com/jeeplus/modules/workapprovalcopy/service/ApprovalCopyService.java
  89. 20 0
      src/main/java/com/jeeplus/modules/workattendance/dao/WorkAttendanceRuleDao.java
  90. 338 0
      src/main/java/com/jeeplus/modules/workattendance/entity/WorkAttendanceRule.java
  91. 124 0
      src/main/java/com/jeeplus/modules/workattendance/service/WorkAttendanceCountService.java
  92. 226 0
      src/main/java/com/jeeplus/modules/workattendance/web/WorkAttendanceInfoController.java
  93. 20 0
      src/main/java/com/jeeplus/modules/workborrowmangement/dao/WorkBorrowBackDao.java
  94. 63 0
      src/main/java/com/jeeplus/modules/workclientinfo/entity/WorkClientBank.java
  95. 139 0
      src/main/java/com/jeeplus/modules/workclientinfo/entity/WorkClientLinkman.java
  96. 121 0
      src/main/java/com/jeeplus/modules/workcontent/entity/WorkContentBudget.java
  97. 117 0
      src/main/java/com/jeeplus/modules/workcontent/entity/WorkContentContprogram.java
  98. 80 0
      src/main/java/com/jeeplus/modules/workcontractinfo/service/WorkContractReviewService.java
  99. 95 0
      src/main/java/com/jeeplus/modules/workdailyroutine/service/WorkDailyRoutineDetailService.java
  100. 0 0
      src/main/java/com/jeeplus/modules/workdevicerecord/web/WorkDeviceXjRecordController.java

+ 12 - 0
src/main/java/com/easemob/server/example/api/AuthTokenAPI.java

@@ -0,0 +1,12 @@
+package com.easemob.server.example.api;
+
+import io.swagger.client.ApiException;
+
+public interface AuthTokenAPI{
+	/**
+	 * Request an Authentication Token
+	 * @return String
+	 * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+	 */
+	Object getAuthToken ();
+}

+ 39 - 0
src/main/java/com/easemob/server/example/api/impl/EasemobFile.java

@@ -0,0 +1,39 @@
+package com.easemob.server.example.api.impl;
+
+import com.easemob.server.example.api.FileAPI;
+import com.easemob.server.example.comm.EasemobAPI;
+import com.easemob.server.example.comm.OrgInfo;
+import com.easemob.server.example.comm.ResponseHandler;
+import com.easemob.server.example.comm.TokenUtil;
+
+import io.swagger.client.ApiException;
+import io.swagger.client.api.UploadAndDownloadFilesApi;
+
+import java.io.File;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class EasemobFile implements FileAPI {
+    private ResponseHandler responseHandler = new ResponseHandler();
+    private UploadAndDownloadFilesApi api = new UploadAndDownloadFilesApi();
+    @Override
+    public Object uploadFile(final Object file) {
+        return responseHandler.handle(new EasemobAPI() {
+            @Override
+            public Object invokeEasemobAPI() throws ApiException {
+                return api.orgNameAppNameChatfilesPost(OrgInfo.ORG_NAME,OrgInfo.APP_NAME,TokenUtil.getAccessToken(),(File)file,true);
+             }
+        });
+    }
+
+    @Override
+    public Object downloadFile(final String fileUUID,final  String shareSecret,final Boolean isThumbnail) {
+        return responseHandler.handle(new EasemobAPI() {
+            @Override
+            public Object invokeEasemobAPI() throws ApiException {
+               return api.orgNameAppNameChatfilesUuidGet(OrgInfo.ORG_NAME,OrgInfo.APP_NAME,TokenUtil.getAccessToken(),fileUUID,shareSecret,isThumbnail);
+            }
+        });
+    }
+}

+ 33 - 0
src/main/java/com/jeeplus/common/mapper/adapters/MapAdapter.java

@@ -0,0 +1,33 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.mapper.adapters;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {  
+	  
+    @Override  
+    public MapConvertor marshal(Map<String, Object> map) throws Exception {  
+        MapConvertor convertor = new MapConvertor();  
+        for (Map.Entry<String, Object> entry : map.entrySet()) {  
+            MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);  
+            convertor.addEntry(e);  
+        }  
+        return convertor;  
+    }  
+  
+    @Override  
+    public Map<String, Object> unmarshal(MapConvertor map) throws Exception {  
+        Map<String, Object> result = new HashMap<String, Object>();  
+        for (MapConvertor.MapEntry e : map.getEntries()) {  
+            result.put(e.getKey(), e.getValue());  
+        }  
+        return result;  
+    }
+    
+}  
+

+ 48 - 0
src/main/java/com/jeeplus/common/oss/OSSConfig.java

@@ -0,0 +1,48 @@
+package com.jeeplus.common.oss;
+
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.Bucket;
+import com.jeeplus.common.config.Global;
+
+/**
+ * @author
+ * @create 2016-10-31 15:05
+ * @others 存放存储上传的信息
+ */
+public class OSSConfig {
+
+    // endpoint为访问域名
+    // 可以使用OSS域名、自定义域名(CNAME)、IP、STS作为endpoint
+    // STS(介绍:https://help.aliyun.com/document_detail/31931.html?spm=5176.doc32010.2.6.u4i4ck)
+    // 访问域名对照中心可参看;https://help.aliyun.com/document_detail/31837.html?spm=5176.doc32010.2.1.EwrB1F
+    // 此处endpoint以杭州为例,其它region请按实际情况填写:http://oss-cn-hangzhou.aliyuncs.com
+
+    protected static String endpoint = Global.getEndpoint();
+
+    // accessKey请登录https://ak-console.aliyun.com/#/查看
+    // accessKeyId和accessKeySecret为申请的秘钥
+
+    protected static String accessKeyId = Global.getAccessKeyId();
+    protected static String accessKeySecret = Global.getAccessKeySecret();
+
+    // 随机生成一个15位的BucketName,相当于命名空间(容器)的名称 "mybucket"+RandomUtils.getNumRandom(15)
+    protected static String bucketName = Global.getBucketName();
+
+    protected static String localFilePath = "文件下载位置";
+
+    // 创建OSSClient实例
+    protected static OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+
+    /**
+     * 创建一个Bucket 存储空间
+     * @param buckets 创建Bucket的名称
+     * @return 创建的Bucket对象
+     */
+    public Bucket createBucket(String buckets){
+        Bucket bucket = ossClient.createBucket(buckets);
+        // 关闭client
+        ossClient.shutdown();
+        return bucket;
+    }
+
+}

+ 50 - 0
src/main/java/com/jeeplus/common/persistence/dialect/db/HSQLDialect.java

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.persistence.dialect.db;
+
+import com.jeeplus.common.persistence.dialect.Dialect;
+
+/**
+ * Dialect for HSQLDB
+ *
+ * @author poplar.yfyang
+ * @version 1.0 2010-10-10 下午12:31
+ * @since JDK 1.5
+ */
+public class HSQLDialect implements Dialect {
+    @Override
+    public boolean supportsLimit() {
+        return true;
+    }
+
+    @Override
+    public String getLimitString(String sql, int offset, int limit) {
+        return getLimitString(sql, offset, Integer.toString(offset),
+                Integer.toString(limit));
+    }
+
+    /**
+     * 将sql变成分页sql语句,提供将offset及limit使用占位符号(placeholder)替换.
+     * <pre>
+     * 如mysql
+     * dialect.getLimitString("select * from user", 12, ":offset",0,":limit") 将返回
+     * select * from user limit :offset,:limit
+     * </pre>
+     *
+     * @param sql               实际SQL语句
+     * @param offset            分页开始纪录条数
+     * @param offsetPlaceholder 分页开始纪录条数-占位符号
+     * @param limitPlaceholder  分页纪录条数占位符号
+     * @return 包含占位符的分页sql
+     */
+    public String getLimitString(String sql, int offset, String offsetPlaceholder, String limitPlaceholder) {
+        boolean hasOffset = offset > 0;
+        return
+                new StringBuffer(sql.length() + 10)
+                        .append(sql)
+                        .insert(sql.toLowerCase().indexOf("select") + 6, hasOffset ? " limit " + offsetPlaceholder + " " + limitPlaceholder : " top " + limitPlaceholder)
+                        .toString();
+    }
+
+}

+ 104 - 0
src/main/java/com/jeeplus/common/persistence/proxy/PaginationMapperProxy.java

@@ -0,0 +1,104 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.persistence.proxy;
+
+import org.apache.ibatis.binding.BindingException;
+import org.apache.ibatis.binding.MapperMethod;
+import org.apache.ibatis.session.SqlSession;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.Reflections;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * <p>
+ * .
+ * </p>
+ *
+ * @author poplar.yfyang
+ * @version 1.0 2012-05-13 上午10:07
+ * @since JDK 1.5
+ */
+public class PaginationMapperProxy implements InvocationHandler {
+
+
+    private static final Set<String> OBJECT_METHODS = new HashSet<String>() {
+        private static final long serialVersionUID = -1782950882770203583L;
+        {
+            add("toString");
+            add("getClass");
+            add("hashCode");
+            add("equals");
+            add("wait");
+            add("notify");
+            add("notifyAll");
+        }
+    };
+
+    private boolean isObjectMethod(Method method) {
+        return OBJECT_METHODS.contains(method.getName());
+    }
+
+    private final SqlSession sqlSession;
+
+    private PaginationMapperProxy(final SqlSession sqlSession) {
+        this.sqlSession = sqlSession;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args)
+            throws Throwable {
+        if (isObjectMethod(method)) {
+            return null;
+        }
+        final Class<?> declaringInterface = findDeclaringInterface(proxy, method);
+        if (Page.class.isAssignableFrom(method.getReturnType())) {
+            // 分页处理
+            return new PaginationMapperMethod(declaringInterface, method, sqlSession).execute(args);
+        }
+        // 原处理方式
+        final MapperMethod mapperMethod = new MapperMethod(declaringInterface, method, sqlSession.getConfiguration());
+        final Object result = mapperMethod.execute(sqlSession, args);
+        if (result == null && method.getReturnType().isPrimitive()) {
+            throw new BindingException(
+                    "Mapper method '"
+                            + method.getName()
+                            + "' ("
+                            + method.getDeclaringClass()
+                            + ") attempted to return null from a method with a primitive return type ("
+                            + method.getReturnType() + ").");
+        }
+        return result;
+    }
+
+    private Class<?> findDeclaringInterface(Object proxy, Method method) {
+        Class<?> declaringInterface = null;
+        for (Class<?> mapperFaces : proxy.getClass().getInterfaces()) {
+            Method m = Reflections.getAccessibleMethod(mapperFaces,
+                    method.getName(),
+                    method.getParameterTypes());
+            if (m != null) {
+                declaringInterface = mapperFaces;
+            }
+        }
+        if (declaringInterface == null) {
+            throw new BindingException(
+                    "Could not find interface with the given method " + method);
+        }
+        return declaringInterface;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T newMapperProxy(Class<T> mapperInterface, SqlSession sqlSession) {
+        ClassLoader classLoader = mapperInterface.getClassLoader();
+        Class<?>[] interfaces = new Class[]{mapperInterface};
+        PaginationMapperProxy proxy = new PaginationMapperProxy(sqlSession);
+        return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
+    }
+}

+ 65 - 0
src/main/java/com/jeeplus/common/servlet/UserfilesDownloadServlet.java

@@ -0,0 +1,65 @@
+package com.jeeplus.common.servlet;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.util.UriUtils;
+
+import com.jeeplus.common.config.Global;
+
+/**
+ * 查看CK上传的图片
+ * @author jeeplus
+ * @version 2014-06-25
+ */
+public class UserfilesDownloadServlet extends HttpServlet {
+
+	private static final long serialVersionUID = 1L;
+	private Logger logger = LoggerFactory.getLogger(getClass());
+
+	public void fileOutputStream(HttpServletRequest req, HttpServletResponse resp) 
+			throws ServletException, IOException {
+		String filepath = req.getRequestURI();
+		int index = filepath.indexOf(Global.USERFILES_BASE_URL);
+		if(index >= 0) {
+			filepath = filepath.substring(index + Global.USERFILES_BASE_URL.length());
+		}
+		try {
+			filepath = UriUtils.decode(filepath, "UTF-8");
+		} catch (UnsupportedEncodingException e1) {
+			logger.error(String.format("解释文件路径失败,URL地址为%s", filepath), e1);
+		}
+		File file = new File(Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + filepath);
+		try {
+			FileCopyUtils.copy(new FileInputStream(file), resp.getOutputStream());
+			resp.setHeader("Content-Type", "application/octet-stream");
+			return;
+		} catch (FileNotFoundException e) {
+			req.setAttribute("exception", new FileNotFoundException("请求的文件不存在"));
+			req.getRequestDispatcher("/webpage/error/404.jsp").forward(req, resp);
+		}
+	}
+
+	@Override
+	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		fileOutputStream(req, resp);
+	}
+
+	@Override
+	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		fileOutputStream(req, resp);
+	}
+}

+ 391 - 0
src/main/java/com/jeeplus/common/utils/JPushClientUtil.java

@@ -0,0 +1,391 @@
+package com.jeeplus.common.utils;
+
+import cn.jpush.api.JPushClient;
+import cn.jpush.api.push.model.Options;
+import cn.jpush.api.push.model.Platform;
+import cn.jpush.api.push.model.PushPayload;
+import cn.jpush.api.push.model.PushPayload.Builder;
+import cn.jpush.api.push.model.audience.Audience;
+import cn.jpush.api.push.model.notification.AndroidNotification;
+import cn.jpush.api.push.model.notification.IosNotification;
+import cn.jpush.api.push.model.notification.Notification;
+import cn.jpush.api.schedule.ScheduleResult;
+import com.easemob.server.example.api.impl.EasemobIMUsers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+/**
+ * 极光推送工具类
+ * 
+ * @author yangfan
+ * @version 2017-8-1
+ */
+
+
+public class JPushClientUtil {
+    private static final Logger logger = LoggerFactory.getLogger(JPushClientUtil.class);
+	//static String appKey = "50deb4032691dca76b445e25";
+	//static String masterSecret = "65d3be2c5fe8b352004f63a7";
+//	static String appKey = "a4378a0373412f39bf6fb4b5";
+//	static String masterSecret = "7aa1eb136050f7a395521214";
+    static String appKey ="b9596dea64c5ee1b143494eb";
+    static String masterSecret ="d04a9854eb26a0540ff02835";
+
+//	static int timeToLive = 864000;
+	static JPushClient jpush = new JPushClient(masterSecret, appKey);
+
+	/**
+	 * 发送通知给全员
+	 * @param title 通知标题,必须
+	 * @param content 通知内容,必须
+	 * @param extras 附加内容,可以为空
+	 * @return 推送结果成功为true
+	 */
+	public static boolean sendNotificationToAll(String title, String content, Map extras) {
+		boolean ret = false;
+		try {
+			Builder builder = PushPayload.newBuilder().setPlatform(Platform.android()).setNotification(Notification.android(content, title, extras)).setAudience(Audience.all()); 
+			try {
+				jpush.sendPush(builder.build());
+				ret = true;
+			} catch(Exception e) { 
+			}
+			builder = PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.all());
+			builder.setNotification(Notification.newBuilder().addPlatformNotification(IosNotification.newBuilder().setAlert(content).autoBadge().addExtras(extras).setSound("default").setBadge(1).setContentAvailable(true).setSound("default").build()).build());
+//			builder.setAudience(Audience.registrationId("0012d749fe5", "081f90d0e0e")); 
+			jpush.sendPush(builder.build());
+			ret = true;
+		} catch (Exception e) { 
+		}
+		return ret;
+    }
+	/**
+	 * 发送通知给Android 或 IOS
+	 * @param title 通知标题,必须
+	 * @param content 通知内容,必须
+	 * @param extras 附加内容,可以为空
+	 * @return 推送结果成功为true
+	 */
+	public static boolean sendNotificationTo_Android_or_IOS(String remarks,String title, String content, Map extras) {
+		boolean ret = false;
+		Builder  builder = null ;
+		try {
+			if("android".equals(remarks.toLowerCase())){
+
+				builder = PushPayload.newBuilder().setPlatform(Platform.android()).setNotification(Notification.android(content, title, extras)).setAudience(Audience.all());
+			}else if("ios".equals(remarks.toLowerCase())){
+
+				builder = PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.all());
+				builder.setNotification(Notification.newBuilder().addPlatformNotification(IosNotification.newBuilder().setAlert(content).autoBadge().addExtras(extras).setSound("default").setBadge(1).setContentAvailable(true).setSound("default").build()).build());
+			}
+
+			jpush.sendPush(builder.build());
+			ret = true;
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return ret;
+	}
+    /**
+     * 发送通知到别名,别名由客户端登录后设置成用户账号
+	 * @param title 通知标题,必须
+	 * @param content 通知内容,必须
+	 * @param extras 附加内容,可以为空
+	 * @return 推送结果成功为true
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public static boolean sendNotificationToAliases(String title, String content, Map extras, List aliases) {
+		List list = new ArrayList();
+		for (Object id :aliases){
+			Jedis jedis = null;
+			try {
+				jedis = JedisUtils.getResource();
+				String userId = jedis.get(id.toString());
+				if (StringUtils.isNotBlank(userId)){
+					list.add(id);
+				}
+			} catch (Exception e) {
+				logger.error("getActiveSessions", e);
+			} finally {
+				JedisUtils.returnResource(jedis);
+			}
+		}
+
+		boolean ret = true;
+		try {
+			if(null == aliases || aliases.size() < 1) {
+				return false;
+			}
+			if(null == title || title.length() < 1) {
+				return false;
+			}
+			if(null == content || content.length() < 1) {
+				return false;
+			}
+			Builder builder = PushPayload.newBuilder().setPlatform(Platform.android()).setNotification(Notification.android(content, title, extras)).setAudience(Audience.alias(list));
+			try {
+				jpush.sendPush(builder.build());
+				ret = true;
+			} catch(Exception e) {
+
+			}
+			builder = PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.alias(list));
+			builder.setNotification(Notification.newBuilder().setAlert(content).addPlatformNotification(IosNotification.newBuilder().addExtras(extras).autoBadge().setSound("default").setBadge(1).setContentAvailable(true).setSound("default").build()).build());
+			jpush.sendPush(builder.build());
+			ret = true;
+		} catch (Exception e) {
+		}
+		return ret; 
+	}
+	/**
+	 * 发送通知到别名,别名由客户端登录后设置成用户账号
+	 * @param title 通知标题,必须
+	 * @param content 通知内容,必须
+	 * @param extras 附加内容,可以为空
+	 * @return 推送结果成功为true
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public static Map<String,Object> sendNotificationToAliasesMap(String title, String content, Map extras, List aliases) {
+		Map<String,Object> map = new HashMap<>();
+		List list = new ArrayList();
+		List returnList = new ArrayList();
+		logger.info("---------------------");
+		logger.info("aliases="+aliases.toString());
+		for (Object id :aliases){
+			Jedis jedis = null;
+			try {
+				jedis = JedisUtils.getResource();
+				String userId = jedis.get(id.toString());
+				logger.info("-----user:"+userId);
+				if (StringUtils.isNotBlank(userId)){
+					list.add(id);
+				}
+			} catch (Exception e) {
+				logger.error("getActiveSessions", e);
+			} finally {
+				JedisUtils.returnResource(jedis);
+			}
+		}
+		logger.info("---------------------");
+
+		boolean ret = true;
+		try {
+			if(null == list || list.size() < 1) {
+				map.put("status","false");
+				return map;
+			}
+			if(null == title || title.length() < 1) {
+				map.put("status","false");
+				return map;
+			}
+			if(null == content || content.length() < 1) {
+				map.put("status","false");
+				return map;
+			}
+			Builder builder = PushPayload.newBuilder().setPlatform(Platform.android()).setNotification(Notification.android(content, title, extras)).setAudience(Audience.alias(list));
+			try {
+				jpush.sendPush(builder.build());
+			} catch(Exception e) {
+
+			}
+			builder = PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.alias(list));
+			builder.setNotification(Notification.newBuilder().setAlert(content).addPlatformNotification(IosNotification.newBuilder().addExtras(extras).autoBadge().setSound("default").setBadge(1).setContentAvailable(true).setSound("default").build()).build());
+			jpush.sendPush(builder.build());
+		} catch (Exception e) {
+		}
+		map.put("list",returnList);
+		map.put("status","true");
+		return map;
+	}
+	/**
+	 * 发送通知到别名数组,别名由客户端登录后设置成用户账号
+	 * @param title 通知标题,必须
+	 * @param content 通知内容,必须
+	 * @param extras 附加内容,可以为空
+	 * @return 推送结果成功为true
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static boolean sendNotificationToAlias(String title, String content, Map extras, String alias) {
+		if(null == alias || alias.length() < 1) {
+			return false;
+		}
+		ArrayList aliases = new ArrayList();
+		aliases.add(alias);  
+		return sendNotificationToAliases(title, content, extras, aliases);
+	}
+    /**
+     * 定时发送
+     * @param title 通知标题,必须
+     * @param content 通知内容,必须
+     * @param extras 附加内容,可以为空
+     * @return 推送结果成功为true
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static boolean sendNotificationToAliasByTime(String title, String content, Map extras, String alias,String time) {
+        if(null == alias || alias.length() < 1) {
+            return false;
+        }
+        ArrayList aliases = new ArrayList();
+        aliases.add(alias);
+        return sendNotificationToAliasesByTime(title, content, extras, aliases, time);
+    }
+
+    /**
+     * 定时发送
+     * @param title 通知标题,必须
+     * @param content 通知内容,必须
+     * @param extras 附加内容,可以为空
+     * @return 推送结果成功为true
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static boolean sendNotificationToAliasesByTime(String title, String content, Map extras, List aliases,String time) {
+        boolean ret = true;
+        try {
+            if(null == aliases || aliases.size() < 1) {
+                return false;
+            }
+            if(null == title || title.length() < 1) {
+                return false;
+            }
+            if(null == content || content.length() < 1) {
+                return false;
+            }
+            PushPayload push = JPushClientUtil.buildPushObject_android_ios_alias_alert(title,content,extras,aliases);
+            ScheduleResult result = jpush.createSingleSchedule(content, time, push);
+
+            System.err.println("==================推送调度====================");
+            logger.info("schedule result is " + result);
+            ret = true;
+        } catch (Exception e) {
+        }
+        return ret;
+    }
+
+    /**
+     * 生成极光推送对象PushPayload(采用java SDK)
+     * @param alias
+     * @param content
+     * @return PushPayload
+     */
+    public static PushPayload buildPushObject_android_ios_alias_alert(String title, String content, Map extras,List alias){
+        return PushPayload.newBuilder()
+                .setPlatform(Platform.android_ios())
+                .setAudience(Audience.alias(alias))
+                .setNotification(Notification.newBuilder()
+                        .addPlatformNotification(AndroidNotification.newBuilder()
+                                .addExtras(extras)
+                                .setAlert(content)
+                                .setTitle(title)
+                                .build())
+                        .addPlatformNotification(IosNotification.newBuilder()
+                                .addExtras(extras)
+                                .setAlert(content)
+                                .addExtras(extras)
+								.setBadge(1)
+								.setSound("default")
+                                .build())
+                        .build())
+                .setOptions(Options.newBuilder()
+                        .setApnsProduction(false)//true-推送生产环境 false-推送开发环境(测试使用参数)
+                        .setTimeToLive(90)//消息在JPush服务器的失效时间(测试使用参数)
+                        .build())
+                .build();
+    }
+
+	public static void main(String [] args) throws  Exception{
+		Map extras = new HashMap();
+        String title ="标题" ;
+        String content="测试一下丨测试推送丨排除异常" ;
+		extras.put("233", "233");
+        String aliase = "93d543eb589647c5a96b69236a613cf3";
+        String time = "2017-12-08 10:33:30";
+        logger.error("time="+time.substring(0,7));
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String date = sdf.format(new Date());
+        logger.error("date="+date);
+        String x = "1234";
+        int y = x.indexOf("|");
+        logger.info(y+"233");
+		SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm");
+		String sqltime = "9:1";
+		Date d = sdf1.parse(sqltime);
+		String dz = sdf1.format(d);
+		logger.info("dz="+dz+",d"+d);
+		String enname1 = StringUtils.getPinYinHeadChar("我是谁", 2) + "gly";
+		String enname2 = StringUtils.getPinYinHeadChar("我是谁", 2) + "gly";
+		String enname3 = StringUtils.getPinYinHeadChar("我是谁", 1) + "gly";
+		String enname4 = StringUtils.getPinYinHeadChar("我是税", 1) + "gly";
+		logger.info("enname1="+enname1+","+"enname2="+enname2+","+"enname3="+enname3+","+"enname4="+enname4);
+     /*   JPushClientUtil.sendNotificationToAliasByTime(title, content, extras, aliase, time);
+		boolean b = JPushClientUtil.sendNotificationToAlias(title,content,extras,aliase);
+		System.err.println(b);*/
+		/*boolean e = JPushClientUtil.sendNotificationToAll(title,content,extras);
+		System.err.println(b+","+e);
+		boolean c = JPushClientUtil.sendNotificationTo_Android_or_IOS("android",title,content,extras);
+		System.err.println(b+","+c);
+
+		System.err.println(b+","+c+","+e);*/
+	}
+
+   /* public static void main(String[] args) {
+        Map<String, Object> map = new LinkedHashMap<String,Object>();
+        map.put("username","zhaokuo");
+        map.put("password", "123456");
+        map.put("email", "zhaokuo719@163.com");
+        map.put("sex", "男");
+        //第一种 用for循环的方式
+        for (Map.Entry<String, Object> m :map.entrySet())  {
+            System.out.println(m.getKey()+"\t"+m.getValue());
+        }
+        //利用迭代 (Iterator)
+        Set set=map.entrySet();
+        Iterator iterator=set.iterator();
+        while(iterator.hasNext()){
+            Map.Entry<String, Object> enter=(Map.Entry<String, Object>)
+                    iterator.next();
+            System.out.println(enter.getKey()+"\t"+enter.getValue());
+        }
+        //利用KeySet 迭代
+        Iterator it = map.keySet().iterator();
+        while(it.hasNext()){
+            String key;
+            String value;
+            key=it.next().toString();
+            value=(String) map.get(key);
+            System.out.println(key+"--"+value);
+        }
+        //利用EnterySet迭代
+        Iterator i=map.entrySet().iterator();
+        System.out.println( map.entrySet().size());
+        String key;
+        String value;
+        while(i.hasNext()){
+            Map.Entry entry = (Map.Entry)i.next();
+            key=entry.getKey().toString();
+            value=entry.getValue().toString();
+            System.out.println(key+"===="+value);
+        }
+        System.out.println("233---"+getKeyByValue(map, "zhaokuo"));
+    }*/
+    public static String getKeyByValue(Map map, Object value) {
+        String keys="";
+        Iterator it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry entry = (Map.Entry) it.next();
+            Object obj = entry.getValue();
+            if (obj != null && obj.equals(value)) {
+                keys=(String) entry.getKey();
+            }
+
+        }
+        return keys;
+    }
+
+
+}

+ 125 - 0
src/main/java/com/jeeplus/common/utils/WordToPic.java

@@ -0,0 +1,125 @@
+package com.jeeplus.common.utils;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import javax.imageio.ImageIO;
+import sun.swing.SwingUtilities2;
+
+public class WordToPic {
+
+    //
+    public static int getLength(String text) {
+        int length = 0;
+        for (int i = 0; i < text.length(); i++) {
+            if (new String(text.charAt(i) + "").getBytes().length > 1) {
+                length += 2;
+            } else {
+                length += 1;
+            }
+        }
+        return length / 2;
+    }
+
+    public static void TextToPic(String text, int width, int height,int fontSize,String filepath) {
+        try {
+            File file = new File(filepath);
+            Font font = new Font("微软雅黑", 0, fontSize);//sans
+            BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
+            Graphics2D g2 = bi.createGraphics();
+            g2.setBackground(new Color(0,188,212));
+            g2.clearRect(0, 0, width, height);
+            //btn2文本
+            g2.setColor(Color.white);
+            g2.setFont(font);
+            g2.drawString(text, (width - (text.length() * fontSize)) / 2 + 0,(height - fontSize) / 2 +45);
+            g2.dispose();
+            /*Graphics2D g2 = bi.createGraphics();
+            g2.setColor(new Color(255, 120, 89));
+            //g2.setBackground(new Color(56,110,162));
+            g2.clearRect(0, 0, width, height);
+            g2.setFont(font);
+            g2.setColor(Color.white);
+            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,0.3f));
+            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+            printString(g2, text, (width - (text.length() * fontSize)) / 2 + 0,(height - fontSize) / 2 +45, fontSize);
+            g2.dispose();*/
+            ImageIO.write(bi, "png", file);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void TextToAliyunPic(String text, int width, int height, int fontHeight,Color bground, ByteArrayOutputStream outputStream) {
+        try {
+            Font font = new Font("微软雅黑", 0, fontHeight);//sans
+            BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            Graphics2D gd = buffImg.createGraphics();
+            //设置透明  start
+            buffImg = gd.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
+            gd=buffImg.createGraphics();
+            //设置透明  end
+            gd.setFont(new Font("微软雅黑", Font.PLAIN, fontHeight)); //设置字体
+            gd.setColor(Color.black); //设置颜色
+            gd.drawString(text, width/2-fontHeight*text.length()/2,fontHeight);
+            ImageIO.write(buffImg, "png", outputStream);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static void printString(Graphics2D g2d, String str, int x, int y,int fontSize) {
+        FontMetrics metrics = SwingUtilities2.getFontMetrics(null,g2d.getFont());
+        for (char ca : str.toCharArray()) {
+            int px = metrics.stringWidth("" + ca);
+            g2d.drawString("" + ca, x + (fontSize - px) / 2, y);
+            x += fontSize;
+        }
+    }
+
+    public static String getDate() {
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
+        return formatter.format(new Date());
+    }
+
+    public static void main(String[] args)
+    {
+        BufferedImage imgMap = drawTranslucentStringPic(400, 80, 36,"欢迎访问我的博客");
+        File imgFile=new File("D://www.cxyapi.com.png");
+        try
+        {
+            ImageIO.write(imgMap, "PNG", imgFile);
+        } catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+        System.out.println("生成完成");
+    }
+
+
+    public static BufferedImage drawTranslucentStringPic(int width, int height, Integer fontHeight,String drawStr)
+    {
+        try
+        {
+            BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            Graphics2D gd = buffImg.createGraphics();
+            //设置透明  start
+            buffImg = gd.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
+            gd=buffImg.createGraphics();
+            //设置透明  end
+            gd.setFont(new Font("微软雅黑", Font.PLAIN, fontHeight)); //设置字体
+            gd.setColor(Color.ORANGE); //设置颜色
+           // gd.drawRect(0, 0, width - 1, height - 1); //画边框
+            gd.drawString(drawStr, width/2-fontHeight*drawStr.length()/2,fontHeight); //输出文字(中文横向居中)
+            return buffImg;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+}

+ 132 - 0
src/main/java/com/jeeplus/common/utils/WorkDayUtils.java

@@ -0,0 +1,132 @@
+package com.jeeplus.common.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class WorkDayUtils {
+	
+	public static void main(String[] args) {
+		try {
+			String strDateStart = "2013-08-01";
+			String strDateEnd = "2014-08-31";
+			
+			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+			Date date_start = sdf.parse(strDateStart);
+			Date date_end = sdf.parse(strDateEnd);
+			WorkDayUtils app = new WorkDayUtils();
+			Calendar cal_start = Calendar.getInstance();
+			Calendar cal_end = Calendar.getInstance();
+			cal_start.setTime(date_start);
+			cal_end.setTime(date_end);
+			System.out.println("开始日:" + cal_start.get(Calendar.YEAR) + "-" + (cal_start.get(Calendar.MONTH) + 1) 
+					+ "-" + cal_start.get(Calendar.DAY_OF_MONTH) + " " + app.getChineseWeek(cal_start));
+			System.out.println("结束日:" + cal_end.get(Calendar.YEAR) + "-" + (cal_end.get(Calendar.MONTH) + 1)
+					+ "-" + cal_end.get(Calendar.DAY_OF_MONTH) + " " + app.getChineseWeek(cal_end));
+			System.out.println("工作日:" + app.getWorkingDay(cal_start, cal_end));
+			System.out.println("休息日:" + app.getHolidays(cal_start, cal_end));
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 获取日期之间的天数
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public int getDaysBetween(java.util.Calendar d1, java.util.Calendar d2) {
+		if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
+			java.util.Calendar swap = d1;
+			d1 = d2;
+			d2 = swap;
+		}
+		int days = d2.get(java.util.Calendar.DAY_OF_YEAR)
+				- d1.get(java.util.Calendar.DAY_OF_YEAR);
+		int y2 = d2.get(java.util.Calendar.YEAR);
+		if (d1.get(java.util.Calendar.YEAR) != y2) {
+			d1 = (java.util.Calendar) d1.clone();
+			do {
+				days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);
+				d1.add(java.util.Calendar.YEAR, 1);
+			} while (d1.get(java.util.Calendar.YEAR) != y2);
+		}
+		return days;
+	}
+
+	/**
+	 * 获取工作日
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public int getWorkingDay(java.util.Calendar d1, java.util.Calendar d2) {
+		int result = -1;
+		if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
+			java.util.Calendar swap = d1;
+			d1 = d2;
+			d2 = swap;
+		}
+		// int betweendays = getDaysBetween(d1, d2);
+		// int charge_date = 0;
+		int charge_start_date = 0;// 开始日期的日期偏移量
+		int charge_end_date = 0;// 结束日期的日期偏移量
+		// 日期不在同一个日期内
+		int stmp;
+		int etmp;
+		stmp = 7 - d1.get(Calendar.DAY_OF_WEEK);
+		etmp = 7 - d2.get(Calendar.DAY_OF_WEEK);
+		if (stmp != 0 && stmp != 6) {// 开始日期为星期六和星期日时偏移量为0
+			charge_start_date = stmp - 1;
+		}
+		if (etmp != 0 && etmp != 6) {// 结束日期为星期六和星期日时偏移量为0
+			charge_end_date = etmp - 1;
+		}
+		// }
+		result = (getDaysBetween(this.getNextMonday(d1), this.getNextMonday(d2)) / 7)
+				* 5 + charge_start_date - charge_end_date;
+		// System.out.println("charge_start_date>" + charge_start_date);
+		// System.out.println("charge_end_date>" + charge_end_date);
+		// System.out.println("between day is-->" + betweendays);
+		return result;
+	}
+
+	/**
+	 * 获取中文日期
+	 * @param date
+	 * @return
+	 */
+	public String getChineseWeek(Calendar date) {
+		final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
+		int dayOfWeek = date.get(Calendar.DAY_OF_WEEK); 
+		// System.out.println(dayNames[dayOfWeek - 1]);
+		return dayNames[dayOfWeek - 1];
+	}
+
+	/**
+	 * 获得日期的下一个星期一的日期
+	 * @param date
+	 * @return
+	 */
+	public Calendar getNextMonday(Calendar date) {
+		Calendar result = null;
+		result = date;
+		do {
+			result = (Calendar) result.clone();
+			result.add(Calendar.DATE, 1);
+		} while (result.get(Calendar.DAY_OF_WEEK) != 2);
+		return result;
+	}
+
+	/**
+	 * 获取休息日
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public int getHolidays(Calendar d1, Calendar d2) {
+		return this.getDaysBetween(d1, d2) - this.getWorkingDay(d1, d2);
+	}
+	
+}

+ 994 - 0
src/main/java/com/jeeplus/common/utils/excel/ExportExcel.java

@@ -0,0 +1,994 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.utils.excel;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+import com.jeeplus.common.utils.SpringContextHolder;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.exampleexpend.service.ExampleExpendService;
+import com.jeeplus.modules.sys.entity.Dict;
+import com.jeeplus.modules.sys.entity.MainDict;
+import com.jeeplus.modules.sys.entity.MainDictDetail;
+import com.jeeplus.modules.workexample.entity.WorkExampleIndices;
+import com.jeeplus.modules.workjobgrade.entity.WorkJobGrade;
+import com.jeeplus.modules.workjobgrade.service.WorkJobGradeService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.DVConstraint;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.Encodes;
+import com.jeeplus.common.utils.Reflections;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.utils.DictUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 导出Excel文件(导出“XLSX”格式,支持大数据量导出   @see org.apache.poi.ss.SpreadsheetVersion)
+ * @author jeeplus
+ * @version 2013-04-21
+ */
+public class ExportExcel {
+
+	private static Logger log = LoggerFactory.getLogger(ExportExcel.class);
+
+    /**
+	 * 工作薄对象
+	 */
+	private SXSSFWorkbook wb;
+	
+	/**
+	 * 工作表对象
+	 */
+	private Sheet sheet;
+	
+	/**
+	 * 样式列表
+	 */
+	private Map<String, CellStyle> styles;
+	
+	/**
+	 * 当前行号
+	 */
+	private int rownum;
+	
+	/**
+	 * 注解列表(Object[]{ ExcelField, Field/Method })
+	 */
+	List<Object[]> annotationList = Lists.newArrayList();
+	
+	/**
+	 * 构造函数
+	 * @param title 表格标题,传“空值”,表示无标题
+	 * @param cls 实体对象,通过annotation.ExportField获取标题
+	 */
+	public ExportExcel(String title, Class<?> cls){
+		this(title, cls, 1);
+	}
+	
+	/**
+	 * 构造函数
+	 * @param title 表格标题,传“空值”,表示无标题
+	 * @param cls 实体对象,通过annotation.ExportField获取标题
+	 * @param type 导出类型(1:导出数据;2:导出模板)
+	 * @param groups 导入分组
+	 */
+	public ExportExcel(String title, Class<?> cls, int type, int... groups){
+		// Get annotation field 
+		Field[] fs = cls.getDeclaredFields();
+		for (Field f : fs){
+			ExcelField ef = f.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==type)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, f});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, f});
+				}
+			}
+		}
+		// Get annotation method
+		Method[] ms = cls.getDeclaredMethods();
+		for (Method m : ms){
+			ExcelField ef = m.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==type)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, m});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, m});
+				}
+			}
+		}
+		// Field sorting
+		Collections.sort(annotationList, new Comparator<Object[]>() {
+			public int compare(Object[] o1, Object[] o2) {
+				return new Integer(((ExcelField)o1[0]).sort()).compareTo(
+						new Integer(((ExcelField)o2[0]).sort()));
+			};
+		});
+		// Initialize
+        if(type==2){
+            initializeTemplate(title, annotationList);
+            return;
+        }
+		List<String> headerList = Lists.newArrayList();
+		for (Object[] os : annotationList){
+			String t = ((ExcelField)os[0]).title();
+			// 如果是导出,则去掉注释
+			if (type==1){
+				String[] ss = StringUtils.split(t, "**", 2);
+				if (ss.length==2){
+					t = ss[0];
+				}
+			}
+			headerList.add(t);
+		}
+		initialize(title, headerList);
+	}
+
+    private void initializeTemplate(String title, List<Object[]> annotationList) {
+        this.wb = new SXSSFWorkbook(500);
+        this.sheet = wb.createSheet("Export");
+        this.styles = createStyles(wb);
+
+        // Create title
+        if (StringUtils.isNotBlank(title)){
+            Row titleRow = sheet.createRow(rownum++);
+            titleRow.setHeightInPoints(30);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellStyle(styles.get("title"));
+            titleCell.setCellValue(title);
+            sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),
+                    titleRow.getRowNum(), titleRow.getRowNum(), annotationList.size()-1));
+        }
+        // Create header
+        if (annotationList == null){
+            throw new RuntimeException("headerList not null!");
+        }
+
+        List<String> headerList = Lists.newArrayList();
+        for (Object[] os : annotationList){
+            String t = ((ExcelField)os[0]).title();
+            // 如果是导出,则去掉注释
+            String[] ss = StringUtils.split(t, "**", 2);
+            if (ss.length==2){
+                t = ss[0];
+            }
+            headerList.add(t);
+        }
+
+        Row headerRow = sheet.createRow(rownum++);
+        headerRow.setHeightInPoints(16);
+        for (int i = 0; i < headerList.size(); i++) {
+            Cell cell = headerRow.createCell(i);
+            cell.setCellStyle(styles.get("header"));
+            String[] ss = StringUtils.split(headerList.get(i), "**", 2);
+            if (ss.length==2){
+                cell.setCellValue(ss[0]);
+                Comment comment = this.sheet.createDrawingPatriarch().createCellComment(
+                        new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
+                comment.setString(new XSSFRichTextString(ss[1]));
+                cell.setCellComment(comment);
+            }else{
+                cell.setCellValue(headerList.get(i));
+            }
+            sheet.autoSizeColumn(i);
+            Object[] objects = annotationList.get(i);
+            String dictType = ((ExcelField) objects[0]).dictType();
+            if(StringUtils.isNotBlank(dictType)){
+                List<Dict> dictList = DictUtils.getDictList(dictType);
+                if(dictList!=null&&dictList.size()>0) {
+                    String[] arr = new String[dictList.size()];
+                    for (int j = 0; j < dictList.size(); j++) {
+                        arr[j] = dictList.get(j).getLabel();
+                    }
+                    sheet.addValidationData(createDataValidation(arr, 2, 5000, i, i));
+                    continue;
+                }
+            }
+            String mainDictType = ((ExcelField) objects[0]).mainDictType();
+            if(StringUtils.isNotBlank(mainDictType)){
+                List<MainDictDetail> dictList = DictUtils.getMainDictList(mainDictType);
+                if(dictList!=null&&dictList.size()>0) {
+                    String[] arr = new String[dictList.size()];
+                    for (int j = 0; j < dictList.size(); j++) {
+                        arr[j] = dictList.get(j).getLabel();
+                    }
+                    sheet.addValidationData(createDataValidation(arr, 2, 5000, i, i));
+                    continue;
+                }
+            }
+
+            String valiName = ((ExcelField) objects[0]).valiName();
+            if(StringUtils.isNotBlank(valiName)){
+                String[] arr = null;
+                if(valiName.equals("WorkJobGrade")){
+                    WorkJobGradeService workJobGradeService = SpringContextHolder.getBean(WorkJobGradeService.class);
+                    WorkJobGrade workJobGrade = new WorkJobGrade();
+                    List<WorkJobGrade> list = workJobGradeService.findList(workJobGrade);
+                    arr = new String[list.size()];
+                    for (int j = 0; j < list.size(); j++) {
+                        arr[j] = list.get(j).getName();
+                    }
+                }else {
+                    List<Dict> dictList = DictUtils.getDictList(valiName);
+                    if(dictList!=null&&dictList.size()>0) {
+                        arr = new String[dictList.size()];
+                        for (int j = 0; j < dictList.size(); j++) {
+                            arr[j] = dictList.get(j).getLabel();
+                        }
+                    }else {
+                        List<MainDictDetail> mainDictList = DictUtils.getMainDictList(valiName);
+                        arr = new String[mainDictList.size()];
+                        for (int j = 0; j < mainDictList.size(); j++) {
+                            arr[j] = mainDictList.get(j).getLabel();
+                        }
+                    }
+                }
+                if(arr!=null&&arr.length>0) {
+                    sheet.addValidationData(createDataValidation(arr, 2, 5000, i, i));
+                }
+                continue;
+            }
+        }
+        for (int i = 0; i < headerList.size(); i++) {
+            int colWidth = sheet.getColumnWidth(i)*2;
+            sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);
+        }
+        log.debug("Initialize success.");
+    }
+
+    /**
+	 * 构造函数
+	 * @param title 表格标题,传“空值”,表示无标题
+	 * @param cls 实体对象,通过annotation.ExportField获取标题
+	 * @param type 导出类型(1:导出数据;2:导出模板)
+	 * @param groups 导入分组
+	 */
+	public ExportExcel(boolean b,String title, Class<?> cls, int type, int... groups){
+		// Get annotation field
+		Field[] fs = cls.getDeclaredFields();
+		for (Field f : fs){
+			ExcelField ef = f.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==type)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, f});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, f});
+				}
+			}
+		}
+		// Get annotation method
+		Method[] ms = cls.getDeclaredMethods();
+		for (Method m : ms){
+			ExcelField ef = m.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==type)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, m});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, m});
+				}
+			}
+		}
+		// Field sorting
+		Collections.sort(annotationList, new Comparator<Object[]>() {
+			public int compare(Object[] o1, Object[] o2) {
+				return new Integer(((ExcelField)o1[0]).sort()).compareTo(
+						new Integer(((ExcelField)o2[0]).sort()));
+			};
+		});
+		// Initialize
+        if(type==2){
+            int size = annotationList.size();
+            if (b){
+                for (int i = 1; i <= 3; i++) {
+                    annotationList.remove(size-i);
+                }
+            }
+            initializeTemplate(title, annotationList);
+            return;
+        }
+		List<String> headerList = Lists.newArrayList();
+		if (b){
+			if (annotationList.size()>3) {
+				for (int i = 0; i < annotationList.size() - 3; i++) {
+					Object[] os = annotationList.get(i);
+					String t = ((ExcelField) os[0]).title();
+					// 如果是导出,则去掉注释
+					if (type == 1) {
+						String[] ss = StringUtils.split(t, "**", 2);
+						if (ss.length == 2) {
+							t = ss[0];
+						}
+					}
+					headerList.add(t);
+				}
+			}else {
+				for (Object[] os : annotationList){
+					String t = ((ExcelField)os[0]).title();
+					// 如果是导出,则去掉注释
+					if (type==1){
+						String[] ss = StringUtils.split(t, "**", 2);
+						if (ss.length==2){
+							t = ss[0];
+						}
+					}
+					headerList.add(t);
+				}
+			}
+		}else {
+			for (Object[] os : annotationList){
+				String t = ((ExcelField)os[0]).title();
+				// 如果是导出,则去掉注释
+				if (type==1){
+					String[] ss = StringUtils.split(t, "**", 2);
+					if (ss.length==2){
+						t = ss[0];
+					}
+				}
+				headerList.add(t);
+			}
+		}
+		initialize(title, headerList);
+	}
+
+	/**
+	 * 构造函数
+	 * @param title 表格标题,传“空值”,表示无标题
+	 * @param headers 表头数组
+	 */
+	public ExportExcel(String title, String[] headers) {
+		initialize(title, Lists.newArrayList(headers));
+	}
+	
+	/**
+	 * 构造函数
+	 * @param title 表格标题,传“空值”,表示无标题
+	 * @param headerList 表头列表
+	 */
+	public ExportExcel(String title, List<String> headerList) {
+		initialize(title, headerList);
+	}
+	
+	/**
+	 * 初始化函数
+	 * @param title 表格标题,传“空值”,表示无标题
+	 * @param headerList 表头列表
+	 */
+	private void initialize(String title, List<String> headerList) {
+		this.wb = new SXSSFWorkbook(500);
+		this.sheet = wb.createSheet("Export");
+		this.styles = createStyles(wb);
+
+		// Create title
+		if (StringUtils.isNotBlank(title)){
+			Row titleRow = sheet.createRow(rownum++);
+			titleRow.setHeightInPoints(30);
+			Cell titleCell = titleRow.createCell(0);
+			titleCell.setCellStyle(styles.get("title"));
+			titleCell.setCellValue(title);
+			sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),
+					titleRow.getRowNum(), titleRow.getRowNum(), headerList.size()-1));
+		}
+		// Create header
+		if (headerList == null){
+			throw new RuntimeException("headerList not null!");
+		}
+		Row headerRow = sheet.createRow(rownum++);
+		headerRow.setHeightInPoints(16);
+		for (int i = 0; i < headerList.size(); i++) {
+			Cell cell = headerRow.createCell(i);
+			cell.setCellStyle(styles.get("header"));
+			String[] ss = StringUtils.split(headerList.get(i), "**", 2);
+			if (ss.length==2){
+				cell.setCellValue(ss[0]);
+				Comment comment = this.sheet.createDrawingPatriarch().createCellComment(
+						new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
+				comment.setString(new XSSFRichTextString(ss[1]));
+				cell.setCellComment(comment);
+			}else{
+				cell.setCellValue(headerList.get(i));
+			}
+			sheet.autoSizeColumn(i);
+		}
+		for (int i = 0; i < headerList.size(); i++) {  
+			int colWidth = sheet.getColumnWidth(i)*2;
+	        sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);  
+		}
+		log.debug("Initialize success.");
+	}
+
+    private DataValidation createDataValidation(String[] textList, int firstRow, int endRow, int firstCol, int endCol) {
+
+        DataValidationHelper helper = sheet.getDataValidationHelper();
+        //加载下拉列表内容
+        DataValidationConstraint constraint = helper.createExplicitListConstraint(textList);
+        //DVConstraint constraint = new DVConstraint();
+        constraint.setExplicitListValues(textList);
+
+        //设置数据有效性加载在哪个单元格上。四个参数分别是:起始行、终止行、起始列、终止列
+        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
+
+        //数据有效性对象
+        DataValidation data_validation = helper.createValidation(constraint, regions);
+        //DataValidation data_validation = new DataValidation(regions, constraint);
+        data_validation.createErrorBox("error","数据不符合规范");
+
+        return data_validation;
+    }
+
+	/**
+	 * 创建表格样式
+	 * @param wb 工作薄对象
+	 * @return 样式列表
+	 */
+	private Map<String, CellStyle> createStyles(Workbook wb) {
+		Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
+		
+		CellStyle style = wb.createCellStyle();
+		style.setAlignment(CellStyle.ALIGN_CENTER);
+		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
+		style.setBorderRight(CellStyle.BORDER_THIN);
+		style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setBorderLeft(CellStyle.BORDER_THIN);
+		style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setBorderTop(CellStyle.BORDER_THIN);
+		style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setBorderBottom(CellStyle.BORDER_THIN);
+		style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		Font titleFont = wb.createFont();
+		titleFont.setFontName("Arial");
+		titleFont.setFontHeightInPoints((short) 16);
+		titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
+		style.setFont(titleFont);
+		styles.put("title", style);
+
+		style = wb.createCellStyle();
+		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
+		style.setBorderRight(CellStyle.BORDER_THIN);
+		style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setBorderLeft(CellStyle.BORDER_THIN);
+		style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setBorderTop(CellStyle.BORDER_THIN);
+		style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setBorderBottom(CellStyle.BORDER_THIN);
+		style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		Font dataFont = wb.createFont();
+		dataFont.setFontName("Arial");
+		dataFont.setFontHeightInPoints((short) 11);
+		style.setFont(dataFont);
+		styles.put("data", style);
+		
+		style = wb.createCellStyle();
+		style.cloneStyleFrom(styles.get("data"));
+		style.setAlignment(CellStyle.ALIGN_LEFT);
+		styles.put("data1", style);
+
+		style = wb.createCellStyle();
+		style.cloneStyleFrom(styles.get("data"));
+		style.setAlignment(CellStyle.ALIGN_CENTER);
+		styles.put("data2", style);
+
+		style = wb.createCellStyle();
+		style.cloneStyleFrom(styles.get("data"));
+		style.setAlignment(CellStyle.ALIGN_RIGHT);
+		styles.put("data3", style);
+		
+		style = wb.createCellStyle();
+		style.cloneStyleFrom(styles.get("data"));
+//		style.setWrapText(true);
+		style.setAlignment(CellStyle.ALIGN_CENTER);
+		style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
+		style.setFillPattern(CellStyle.SOLID_FOREGROUND);
+		Font headerFont = wb.createFont();
+		headerFont.setFontName("Arial");
+		headerFont.setFontHeightInPoints((short) 10);
+		headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
+		headerFont.setColor(IndexedColors.WHITE.getIndex());
+		style.setFont(headerFont);
+		styles.put("header", style);
+		
+		return styles;
+	}
+
+	/**
+	 * 添加一行
+	 * @return 行对象
+	 */
+	public Row addRow(){
+		return sheet.createRow(rownum++);
+	}
+	
+
+	/**
+	 * 添加一个单元格
+	 * @param row 添加的行
+	 * @param column 添加列号
+	 * @param val 添加值
+	 * @return 单元格对象
+	 */
+	public Cell addCell(Row row, int column, Object val){
+		return this.addCell(row, column, val, 0, Class.class);
+	}
+	
+	/**
+	 * 添加一个单元格
+	 * @param row 添加的行
+	 * @param column 添加列号
+	 * @param val 添加值
+	 * @param align 对齐方式(1:靠左;2:居中;3:靠右)
+	 * @return 单元格对象
+	 */
+	public Cell addCell(Row row, int column, Object val, int align, Class<?> fieldType){
+		Cell cell = row.createCell(column);
+		CellStyle style = styles.get("data"+(align>=1&&align<=3?align:""));
+		try {
+			if (val == null){
+				cell.setCellValue("");
+			} else if (val instanceof String) {
+				cell.setCellValue((String) val);
+			} else if (val instanceof Integer) {
+				cell.setCellValue((Integer) val);
+			} else if (val instanceof Long) {
+				cell.setCellValue((Long) val);
+			} else if (val instanceof Double) {
+				cell.setCellValue((Double) val);
+			} else if (val instanceof Float) {
+				cell.setCellValue((Float) val);
+			} else if (val instanceof Date) {
+				DataFormat format = wb.createDataFormat();
+	            style.setDataFormat(format.getFormat("yyyy-MM-dd"));
+				cell.setCellValue((Date) val);
+			} else {
+				if (fieldType != Class.class){
+					cell.setCellValue((String)fieldType.getMethod("setValue", Object.class).invoke(null, val));
+				}else{
+					cell.setCellValue((String)Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), 
+						"fieldtype."+val.getClass().getSimpleName()+"Type")).getMethod("setValue", Object.class).invoke(null, val));
+				}
+			}
+		} catch (Exception ex) {
+			log.info("Set cell value ["+row.getRowNum()+","+column+"] error: " + ex.toString());
+			cell.setCellValue(val.toString());
+		}
+		cell.setCellStyle(style);
+		return cell;
+	}
+
+	/**
+	 * 添加数据(通过annotation.ExportField添加数据)
+	 * @return list 数据列表
+	 */
+	public <E> ExportExcel setDataList(List<E> list){
+		for (E e : list){
+			int colunm = 0;
+			Row row = this.addRow();
+			StringBuilder sb = new StringBuilder();
+			for (Object[] os : annotationList){
+				ExcelField ef = (ExcelField)os[0];
+				Object val = null;
+				// Get entity value
+				try{
+					if (StringUtils.isNotBlank(ef.value())){
+						val = Reflections.invokeGetter(e, ef.value());
+					}else{
+						if (os[1] instanceof Field){
+							val = Reflections.invokeGetter(e, ((Field)os[1]).getName());
+						}else if (os[1] instanceof Method){
+							val = Reflections.invokeMethod(e, ((Method)os[1]).getName(), new Class[] {}, new Object[] {});
+						}
+					}
+					// If is dict, get dict label
+					if (StringUtils.isNotBlank(ef.dictType())){
+						val = DictUtils.getDictLabel(val==null?"":val.toString(), ef.dictType(), "");
+					}else if (StringUtils.isNotBlank(ef.mainDictType())){
+						val = DictUtils.getMainDictLabel(val==null?"":val.toString(), ef.mainDictType(), "");
+					}
+				}catch(Exception ex) {
+					// Failure to ignore
+					log.info(ex.toString());
+					val = "";
+				}
+				this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
+				sb.append(val + ", ");
+			}
+			log.debug("Write success: ["+row.getRowNum()+"] "+sb.toString());
+		}
+		return this;
+	}
+
+	/**
+	 * 添加数据(通过annotation.ExportField添加数据)
+	 * @return list 数据列表
+	 */
+	public <E> ExportExcel setDataList(boolean b,List<E> list){
+		if (b){
+			for (E e : list) {
+				int colunm = 0;
+				Row row = this.addRow();
+				StringBuilder sb = new StringBuilder();
+				if (annotationList.size()>=3){
+					for (int i = 0 ;i < annotationList.size()-3 ; i++){
+						Object[] os = annotationList.get(i);
+						ExcelField ef = (ExcelField) os[0];
+						Object val = null;
+						// Get entity value
+						try {
+							if (StringUtils.isNotBlank(ef.value())) {
+								val = Reflections.invokeGetter(e, ef.value());
+							} else {
+								if (os[1] instanceof Field) {
+									val = Reflections.invokeGetter(e, ((Field) os[1]).getName());
+								} else if (os[1] instanceof Method) {
+									val = Reflections.invokeMethod(e, ((Method) os[1]).getName(), new Class[]{}, new Object[]{});
+								}
+							}
+							// If is dict, get dict label
+							if (StringUtils.isNotBlank(ef.dictType())) {
+								val = DictUtils.getDictLabel(val == null ? "" : val.toString(), ef.dictType(), "");
+							}else if (StringUtils.isNotBlank(ef.mainDictType())){
+								val = DictUtils.getMainDictLabel(val==null?"":val.toString(), ef.mainDictType(), "");
+							}
+						} catch (Exception ex) {
+							// Failure to ignore
+							log.info(ex.toString());
+							val = "";
+						}
+						this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
+						sb.append(val + ", ");
+					}
+					log.debug("Write success: [" + row.getRowNum() + "] " + sb.toString());
+				}else {
+					for (Object[] os : annotationList) {
+						ExcelField ef = (ExcelField) os[0];
+						Object val = null;
+						// Get entity value
+						try {
+							if (StringUtils.isNotBlank(ef.value())) {
+								val = Reflections.invokeGetter(e, ef.value());
+							} else {
+								if (os[1] instanceof Field) {
+									val = Reflections.invokeGetter(e, ((Field) os[1]).getName());
+								} else if (os[1] instanceof Method) {
+									val = Reflections.invokeMethod(e, ((Method) os[1]).getName(), new Class[]{}, new Object[]{});
+								}
+							}
+							// If is dict, get dict label
+							if (StringUtils.isNotBlank(ef.dictType())) {
+								val = DictUtils.getDictLabel(val == null ? "" : val.toString(), ef.dictType(), "");
+							}else if (StringUtils.isNotBlank(ef.mainDictType())){
+								val = DictUtils.getMainDictLabel(val==null?"":val.toString(), ef.mainDictType(), "");
+							}
+						} catch (Exception ex) {
+							// Failure to ignore
+							log.info(ex.toString());
+							val = "";
+						}
+						this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
+						sb.append(val + ", ");
+					}
+					log.debug("Write success: [" + row.getRowNum() + "] " + sb.toString());
+				}
+			}
+		}else {
+			for (E e : list) {
+				int colunm = 0;
+				Row row = this.addRow();
+				StringBuilder sb = new StringBuilder();
+				for (Object[] os : annotationList) {
+					ExcelField ef = (ExcelField) os[0];
+					Object val = null;
+					// Get entity value
+					try {
+						if (StringUtils.isNotBlank(ef.value())) {
+							val = Reflections.invokeGetter(e, ef.value());
+						} else {
+							if (os[1] instanceof Field) {
+								val = Reflections.invokeGetter(e, ((Field) os[1]).getName());
+							} else if (os[1] instanceof Method) {
+								val = Reflections.invokeMethod(e, ((Method) os[1]).getName(), new Class[]{}, new Object[]{});
+							}
+						}
+						// If is dict, get dict label
+						if (StringUtils.isNotBlank(ef.dictType())) {
+							val = DictUtils.getDictLabel(val == null ? "" : val.toString(), ef.dictType(), "");
+						}else if (StringUtils.isNotBlank(ef.mainDictType())){
+							val = DictUtils.getMainDictLabel(val==null?"":val.toString(), ef.mainDictType(), "");
+						}
+					} catch (Exception ex) {
+						// Failure to ignore
+						log.info(ex.toString());
+						val = "";
+					}
+					this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
+					sb.append(val + ", ");
+				}
+				log.debug("Write success: [" + row.getRowNum() + "] " + sb.toString());
+			}
+		}
+		return this;
+	}
+	
+	/**
+	 * 输出数据流
+	 * @param os 输出数据流
+	 */
+	public ExportExcel write(OutputStream os) throws IOException{
+		wb.write(os);
+		return this;
+	}
+	
+	/**
+	 * 输出到客户端
+	 * @param fileName 输出文件名
+	 */
+	public ExportExcel write(HttpServletResponse response, String fileName) throws IOException{
+		response.reset();
+        response.setContentType("application/octet-stream; charset=utf-8");
+		response.setHeader("Content-Disposition", "attachment; filename="+ new String(fileName.getBytes("utf-8"),"ISO-8859-1"));
+		//response.setHeader("Content-Disposition", "attachment; filename="+Encodes.urlEncode(fileName));
+		write(response.getOutputStream());
+		return this;
+	}
+
+	/**
+	 * 输出到客户端
+	 * @param fileName 输出文件名
+	 */
+	public ExportExcel write(HttpServletResponse response, String fileName,String agent) throws IOException{
+		response.reset();
+        response.setContentType("application/octet-stream; charset=utf-8");
+		if(agent != null && agent.toLowerCase().indexOf("firefox") > 0){
+			response.setHeader("Content-Disposition", "attachment; filename="+ new String(fileName.getBytes("utf-8"),"ISO-8859-1"));
+		}else {
+			response.setHeader("Content-Disposition", "attachment; filename="+Encodes.urlEncode(fileName));
+		}
+		write(response.getOutputStream());
+		return this;
+	}
+
+	/**
+	 * 输出到文件
+	 * @param name 输出文件名
+	 */
+	public ExportExcel writeFile(String name) throws FileNotFoundException, IOException{
+		FileOutputStream os = new FileOutputStream(name);
+		this.write(os);
+		return this;
+	}
+	
+	/**
+	 * 清理临时文件
+	 */
+	public ExportExcel dispose(){
+		wb.dispose();
+		return this;
+	}
+	
+//	/**
+//	 * 导出测试
+//	 */
+//	public static void main(String[] args) throws Throwable {
+//		
+//		List<String> headerList = Lists.newArrayList();
+//		for (int i = 1; i <= 10; i++) {
+//			headerList.add("表头"+i);
+//		}
+//		
+//		List<String> dataRowList = Lists.newArrayList();
+//		for (int i = 1; i <= headerList.size(); i++) {
+//			dataRowList.add("数据"+i);
+//		}
+//		
+//		List<List<String>> dataList = Lists.newArrayList();
+//		for (int i = 1; i <=1000000; i++) {
+//			dataList.add(dataRowList);
+//		}
+//
+//		ExportExcel ee = new ExportExcel("表格标题", headerList);
+//		
+//		for (int i = 0; i < dataList.size(); i++) {
+//			Row row = ee.addRow();
+//			for (int j = 0; j < dataList.get(i).size(); j++) {
+//				ee.addCell(row, j, dataList.get(i).get(j));
+//			}
+//		}
+//		
+//		ee.writeFile("target/export.xlsx");
+//
+//		ee.dispose();
+//		
+//		log.debug("Export success.");
+//		
+//	}
+
+	/**
+	 * 动态生成案例模板
+	 * @param title sheetName
+	 * @param indicesList 指标项
+	 * @param headerList 表头内容
+	 * @param type 是否单位赋值
+	 */
+	private void exampleTemplate(SXSSFWorkbook wb, String title, List<WorkExampleIndices> indicesList, List<String> headerList,String type) {
+		    this.sheet = wb.createSheet(title);
+			this.styles = createStyles(wb);
+			this.rownum=0;
+			// Create title
+			if (StringUtils.isNotBlank(title)){
+				Row titleRow = sheet.createRow(rownum++);
+				titleRow.setHeightInPoints(30);
+				Cell titleCell = titleRow.createCell(0);
+				titleCell.setCellStyle(styles.get("title"));
+				titleCell.setCellValue(title);
+				sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),
+						titleRow.getRowNum(), titleRow.getRowNum(), headerList.size()-1));
+			}
+			// Create header
+			if (headerList == null){
+				throw new RuntimeException("headerList not null!");
+			}
+			Row headerRow = sheet.createRow(rownum++);
+			headerRow.setHeightInPoints(20);
+			for (int i = 0; i < headerList.size(); i++) {
+				Cell cell = headerRow.createCell(i);
+				cell.setCellStyle(styles.get("header"));
+				String[] ss = StringUtils.split(headerList.get(i), "**", 2);
+				if (ss.length==2){
+					cell.setCellValue(ss[0]);
+					Comment comment = this.sheet.createDrawingPatriarch().createCellComment(
+							new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
+					comment.setString(new XSSFRichTextString(ss[1]));
+					cell.setCellComment(comment);
+				}else{
+					cell.setCellValue(headerList.get(i));
+				}
+				sheet.autoSizeColumn(i);
+			}
+			for(WorkExampleIndices workExampleIndices:indicesList){
+				Row contentRow=sheet.createRow(rownum++);
+				contentRow.setHeightInPoints(20);
+				for (int i = 0; i < headerList.size(); i++) {
+					Cell cell = contentRow.createCell(i);
+					cell.setCellStyle(styles.get("data"));
+					if(i==0){
+						cell.setCellValue(workExampleIndices.getName());
+					}
+					if(i==1){
+						if("2".equals(type)){
+							cell.setCellValue(DictUtils.getMainDictLabel(workExampleIndices.getItemUnit(),"unit_type",""));
+						}
+					}
+					sheet.autoSizeColumn(i);
+				}
+
+			}
+			for (int i = 0; i < headerList.size(); i++) {
+				int colWidth = sheet.getColumnWidth(i)*2;
+				sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);
+			}
+
+		log.debug("Initialize success.");
+	}
+	/**
+	 *
+	 * @param title sheetName
+	 * @param indicesList 指标项
+	 * @param headerList 表头内容
+	 * @param type 是否单位赋值
+	 */
+	public void createSheet(String title, List<WorkExampleIndices> indicesList, List<String> headerList,String type) {
+		exampleTemplate(wb,title,indicesList,headerList,type);
+
+	}
+	public ExportExcel(int i){
+		this.wb=new SXSSFWorkbook(i);
+		this.sheet = wb.createSheet("工程概况");
+		this.styles = createStyles(wb);
+		Row titleRow = sheet.createRow(rownum++);
+		titleRow.setHeightInPoints(40);
+		Cell titleCell = titleRow.createCell(0);
+		titleCell.setCellStyle(styles.get("title"));
+		titleCell.setCellValue("工程概况");
+		sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),
+				titleRow.getRowNum(), titleRow.getRowNum(), 3));
+		sheet.setColumnWidth(0,6000);
+		sheet.setColumnWidth(1,6000);
+		sheet.setColumnWidth(2,6000);
+		sheet.setColumnWidth(3,6000);
+		createRows(sheet,"工程名称","工程类型");
+		createRows(sheet,"工程地点","建设规模(m2)");
+		createRows(sheet,"结构形式","基础类型");
+		createRows(sheet,"规模(户数、床位数等)","结构安全等级");
+		createRows(sheet,"编制阶段","投资类型");
+		createRows(sheet,"计价类型","计价依据");
+		createRows(sheet,"招标基准信息价","计税模式");
+		createRows(sheet,"开工日期","竣工日期");
+		createRows(sheet,"地上建筑面积","地下建筑面积");
+		createRows(sheet,"人防建筑面积","车库建筑面积");
+		createRows(sheet,"地上层数","地下层数");
+		createRows(sheet,"地上层高","地下层高");
+		createRows(sheet,"总层数","檐高");
+		createRows(sheet,"内墙面装修","外墙面装修");
+		createRows(sheet,"天棚装修","楼地面装修");
+		createRows(sheet,"门","窗");
+		createRows(sheet,"说明","");
+
+	}
+	public void createRows(Sheet sheet,String str1,String str2){
+		Row contentRow = sheet.createRow(rownum++);
+		contentRow.setHeightInPoints(30);
+		for(int i=0;i<4;i++){
+			Cell cell = contentRow.createCell(i);
+			cell.setCellStyle(styles.get("data"));
+			if(i==0){
+				cell.setCellValue(str1);
+			}else if(i==2){
+				cell.setCellValue(str2);
+			}
+		}
+	}
+}

+ 637 - 0
src/main/java/com/jeeplus/common/utils/excel/ImportExcel.java

@@ -0,0 +1,637 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.utils.excel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+import com.jeeplus.modules.workjobgrade.entity.WorkJobGrade;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.Reflections;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Area;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.DictUtils;
+import com.jeeplus.modules.sys.utils.UserUtils;
+
+/**
+ * 导入Excel文件(支持“XLS”和“XLSX”格式)
+ * @author jeeplus
+ * @version 2013-03-10
+ */
+public class ImportExcel {
+
+	private static Logger log = LoggerFactory.getLogger(ImportExcel.class);
+
+	/**
+	 * 工作薄对象
+	 */
+	private Workbook wb;
+
+	/**
+	 * 工作表对象
+	 */
+	private Sheet sheet;
+
+	/**
+	 * 标题行号
+	 */
+	private int headerNum;
+
+	/**
+	 * 构造函数
+	 * @param path 导入文件,读取第一个工作表
+	 * @param headerNum 标题行号,数据行号=标题行号+1
+	 * @throws InvalidFormatException
+	 * @throws IOException
+	 */
+	public ImportExcel(String fileName, int headerNum)
+			throws InvalidFormatException, IOException {
+		this(new File(fileName), headerNum);
+	}
+	public int sheetCirculation() {
+		int sheetCount = -1;
+		sheetCount = this.wb.getNumberOfSheets();
+		return sheetCount;
+	}
+	/**
+	 * 构造函数
+	 * @param path 导入文件对象,读取第一个工作表
+	 * @param headerNum 标题行号,数据行号=标题行号+1
+	 * @throws InvalidFormatException
+	 * @throws IOException
+	 */
+	public ImportExcel(File file, int headerNum)
+			throws InvalidFormatException, IOException {
+		this(file, headerNum, 0);
+	}
+
+	/**
+	 * 构造函数
+	 * @param path 导入文件
+	 * @param headerNum 标题行号,数据行号=标题行号+1
+	 * @param sheetIndex 工作表编号
+	 * @throws InvalidFormatException
+	 * @throws IOException
+	 */
+	public ImportExcel(String fileName, int headerNum, int sheetIndex)
+			throws InvalidFormatException, IOException {
+		this(new File(fileName), headerNum, sheetIndex);
+	}
+
+	/**
+	 * 构造函数
+	 * @param path 导入文件对象
+	 * @param headerNum 标题行号,数据行号=标题行号+1
+	 * @param sheetIndex 工作表编号
+	 * @throws InvalidFormatException
+	 * @throws IOException
+	 */
+	public ImportExcel(File file, int headerNum, int sheetIndex)
+			throws InvalidFormatException, IOException {
+		this(file.getName(), new FileInputStream(file), headerNum, sheetIndex);
+	}
+
+	/**
+	 * 构造函数
+	 * @param file 导入文件对象
+	 * @param headerNum 标题行号,数据行号=标题行号+1
+	 * @param sheetIndex 工作表编号
+	 * @throws InvalidFormatException
+	 * @throws IOException
+	 */
+	public ImportExcel(MultipartFile multipartFile, int headerNum, int sheetIndex)
+			throws InvalidFormatException, IOException {
+		this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex);
+	}
+
+	/**
+	 * 构造函数
+	 * @param path 导入文件对象
+	 * @param headerNum 标题行号,数据行号=标题行号+1
+	 * @param sheetIndex 工作表编号
+	 * @throws InvalidFormatException
+	 * @throws IOException
+	 */
+	public ImportExcel(String fileName, InputStream is, int headerNum, int sheetIndex)
+			throws InvalidFormatException, IOException {
+		if (StringUtils.isBlank(fileName)){
+			throw new RuntimeException("导入文档为空!");
+		}else if(fileName.toLowerCase().endsWith("xls")){
+			this.wb = new HSSFWorkbook(is);
+        }else if(fileName.toLowerCase().endsWith("xlsx")){
+        	this.wb = new XSSFWorkbook(is);
+        }else{
+        	throw new RuntimeException("文档格式不正确!");
+        }
+		if (this.wb.getNumberOfSheets()<sheetIndex){
+			throw new RuntimeException("文档中没有工作表!");
+		}
+		this.sheet = this.wb.getSheetAt(sheetIndex);
+		this.headerNum = headerNum;
+		log.debug("Initialize success.");
+	}
+
+	/**
+	 * 获取行对象
+	 * @param rownum
+	 * @return
+	 */
+	public Row getRow(int rownum){
+		return this.sheet.getRow(rownum);
+	}
+	/**
+	 * header内容
+	 * @param
+	 * @return
+	 */
+	public String getHeaderStr(){
+		return this.sheet.getSheetName();
+	}
+	/**
+	 * 获取数据行号
+	 * @return
+	 */
+	public int getDataRowNum(){
+		return headerNum+1;
+	}
+
+	/**
+	 * 获取最后一个数据行号
+	 * @return
+	 */
+	public int getLastDataRowNum(){
+		return this.sheet.getLastRowNum()+headerNum;
+	}
+
+	/**
+	 * 获取最后一个列号
+	 * @return
+	 */
+	public int getLastCellNum(){
+		return this.getRow(headerNum).getLastCellNum();
+	}
+
+	/**
+	 * 获取单元格值
+	 * @param row 获取的行
+	 * @param column 获取单元格列号
+	 * @return 单元格值
+	 */
+	public Object getCellValue(Row row, int column) {
+		Object val = "";
+		try {
+			Cell cell = row.getCell(column);
+
+			if (cell != null) {
+				if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
+					// val = cell.getNumericCellValue();
+					// 当excel 中的数据为数值或日期是需要特殊处理
+					if (HSSFDateUtil.isCellDateFormatted(cell)) {
+						double d = cell.getNumericCellValue();
+						Date date = HSSFDateUtil.getJavaDate(d);
+						SimpleDateFormat dformat = new SimpleDateFormat(
+								"yyyy-MM-dd");
+						val = dformat.format(date);
+					} else {
+						NumberFormat nf = NumberFormat.getInstance();
+						nf.setGroupingUsed(false);// true时的格式:1,234,567,890
+						val = nf.format(cell.getNumericCellValue());// 数值类型的数据为double,所以需要转换一下
+                        if(((String) val).contains(",")){
+                            val = nf.parse(val.toString()).doubleValue();
+                        }
+					}
+				} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
+					val = replaceBlank(cell.getStringCellValue());
+				} else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
+					//val = cell.getCellFormula();
+					try {
+						val = String.valueOf(cell.getNumericCellValue());
+						if(String.valueOf(cell.getNumericCellValue()).indexOf("E")==-1){
+							val= String.valueOf(cell.getNumericCellValue());
+						}else {
+							NumberFormat formatter=NumberFormat.getNumberInstance();
+							formatter.setMinimumFractionDigits(4);
+							val=formatter.format(cell.getNumericCellValue());
+                            if(((String) val).contains(",")){
+                              val= val.toString().replaceAll(",","");
+                            }
+						}
+
+						 } catch (IllegalStateException e) {
+						val = String.valueOf(cell.getRichStringCellValue());
+						 }
+				} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
+					val = cell.getBooleanCellValue();
+				} else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
+					val = cell.getErrorCellValue();
+				}
+			}
+		} catch (Exception e) {
+			return val;
+		}
+		return val;
+	}
+
+	/**
+	 * 获取导入数据列表
+	 * @param cls 导入对象类型
+	 * @param groups 导入分组
+	 */
+	public <E> List<E> getDataList(Class<E> cls, int... groups) throws InstantiationException, IllegalAccessException{
+		List<Object[]> annotationList = Lists.newArrayList();
+		// Get annotation field
+		Field[] fs = cls.getDeclaredFields();
+		for (Field f : fs){
+			ExcelField ef = f.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==2)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, f});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, f});
+				}
+			}
+		}
+		// Get annotation method
+		Method[] ms = cls.getDeclaredMethods();
+		for (Method m : ms){
+			ExcelField ef = m.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==2)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, m});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, m});
+				}
+			}
+		}
+		// Field sorting
+		Collections.sort(annotationList, new Comparator<Object[]>() {
+			public int compare(Object[] o1, Object[] o2) {
+				return new Integer(((ExcelField)o1[0]).sort()).compareTo(
+						new Integer(((ExcelField)o2[0]).sort()));
+			};
+		});
+		//log.debug("Import column count:"+annotationList.size());
+		// Get excel data
+		List<E> dataList = Lists.newArrayList();
+		for (int i = this.getDataRowNum(); i < this.getLastDataRowNum(); i++) {
+			E e = (E)cls.newInstance();
+			int column = 0;
+			Row row = this.getRow(i);
+			StringBuilder sb = new StringBuilder();
+			for (Object[] os : annotationList){
+                ExcelField ef = (ExcelField)os[0];
+                Object val = null;
+                if (ef.colNum()!=0) {
+                    val = this.getCellValue(row, ef.colNum());
+                }else {
+                    val = this.getCellValue(row, column++);
+                }
+				if (val != null){
+
+					// If is dict type, get dict value
+					if (StringUtils.isNotBlank(ef.dictType())){
+						val = DictUtils.getDictValue(val.toString(), ef.dictType(), "");
+						//log.debug("Dictionary type value: ["+i+","+colunm+"] " + val);
+					}
+					if (StringUtils.isNotBlank(ef.mainDictType())){
+						val = DictUtils.getMainDictValue(val.toString(), ef.mainDictType(), "");
+						//log.debug("Dictionary type value: ["+i+","+colunm+"] " + val);
+					}
+					// Get param type and type cast
+					Class<?> valType = Class.class;
+					if (os[1] instanceof Field){
+						valType = ((Field)os[1]).getType();
+					}else if (os[1] instanceof Method){
+						Method method = ((Method)os[1]);
+						if ("get".equals(method.getName().substring(0, 3))){
+							valType = method.getReturnType();
+						}else if("set".equals(method.getName().substring(0, 3))){
+							valType = ((Method)os[1]).getParameterTypes()[0];
+						}
+					}
+					//log.debug("Import value type: ["+i+","+column+"] " + valType);
+					try {
+						//如果导入的java对象,需要在这里自己进行变换。
+						if (valType == String.class){
+							String s = String.valueOf(val.toString());
+							if(StringUtils.endsWith(s, ".0")){
+								val = StringUtils.substringBefore(s, ".0");
+							}else{
+								val = String.valueOf(val.toString());
+							}
+						}else if (valType == Integer.class){
+							val = Double.valueOf(val.toString()).intValue();
+						}else if (valType == Long.class){
+							val = Double.valueOf(val.toString()).longValue();
+						}else if (valType == Double.class){
+                            if(val instanceof String){
+                                val = ((String) val).replaceAll(",","");
+                            }
+							val = Double.valueOf(val.toString());
+						}else if (valType == Float.class){
+							val = Float.valueOf(val.toString());
+						}else if (valType == Date.class){
+							SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+							val=sdf.parse(val.toString());
+						}else if (valType == User.class){
+							val = UserUtils.getByUserName(val.toString());
+						}else if (valType == Office.class){
+							val = UserUtils.getByOfficeName(val.toString());
+						}else if (valType == Area.class){
+							val = UserUtils.getByAreaName(val.toString());
+						}else if (valType == WorkJobGrade.class){
+							val = UserUtils.getByWorkJobGradeName(val.toString());
+						}else{
+							if (ef.fieldType() != Class.class){
+								val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString());
+							}else{
+								val = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(),
+										"fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString());
+							}
+						}
+					} catch (Exception ex) {
+						log.info("Get cell value ["+i+","+column+"] error: " + ex.toString());
+						val = null;
+					}
+					// set entity value
+					if (os[1] instanceof Field){
+						Reflections.invokeSetter(e, ((Field)os[1]).getName(), val);
+					}else if (os[1] instanceof Method){
+						String mthodName = ((Method)os[1]).getName();
+						if ("get".equals(mthodName.substring(0, 3))){
+							mthodName = "set"+StringUtils.substringAfter(mthodName, "get");
+						}
+						try {
+                            Reflections.invokeMethod(e, mthodName, new Class[]{valType}, new Object[]{val});
+                        }catch (Exception e3){
+						    log.error("解析Excel失败。",e3);
+                        }
+					}
+				}
+				sb.append(val+", ");
+			}
+			dataList.add(e);
+			log.debug("Read success: ["+i+"] "+sb.toString());
+		}
+		return dataList;
+	}
+
+	/**
+	 * 客户的报表数据
+	 * @param cls
+	 * @param groups
+	 * @param <E>
+	 * @return
+	 * @throws InstantiationException
+	 * @throws IllegalAccessException
+	 *//*
+	public <E> Map<Object,Object> getClientDataList(Class<E> cls, int... groups) throws InstantiationException, IllegalAccessException{
+		HashMap<Object, Object> map = Maps.newHashMap();
+		List<Object[]> annotationList = Lists.newArrayList();
+		// Get annotation field
+		Field[] fs = cls.getDeclaredFields();
+		for (Field f : fs){
+			ExcelField ef = f.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==2)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, f});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, f});
+				}
+			}
+		}
+		// Get annotation method
+		Method[] ms = cls.getDeclaredMethods();
+		for (Method m : ms){
+			ExcelField ef = m.getAnnotation(ExcelField.class);
+			if (ef != null && (ef.type()==0 || ef.type()==2)){
+				if (groups!=null && groups.length>0){
+					boolean inGroup = false;
+					for (int g : groups){
+						if (inGroup){
+							break;
+						}
+						for (int efg : ef.groups()){
+							if (g == efg){
+								inGroup = true;
+								annotationList.add(new Object[]{ef, m});
+								break;
+							}
+						}
+					}
+				}else{
+					annotationList.add(new Object[]{ef, m});
+				}
+			}
+		}
+		// Field sorting
+		Collections.sort(annotationList, new Comparator<Object[]>() {
+			public int compare(Object[] o1, Object[] o2) {
+				return new Integer(((ExcelField)o1[0]).sort()).compareTo(
+						new Integer(((ExcelField)o2[0]).sort()));
+			};
+		});
+		//log.debug("Import column count:"+annotationList.size());
+		// Get excel data
+		List<E> dataList = Lists.newArrayList();
+		List<String> errList = Lists.newArrayList();
+		for (int i = this.getDataRowNum(); i < this.getLastDataRowNum(); i++) {
+			E e = (E)cls.newInstance();
+			int column = 0;
+			Row row = this.getRow(i);
+			StringBuilder sb = new StringBuilder();
+			String errMsg = "";
+			for (Object[] os : annotationList){
+				Object val = this.getCellValue(row, column++);
+				if (val != null){
+					ExcelField ef = (ExcelField)os[0];
+					// If is dict type, get dict value
+					if (StringUtils.isNotBlank(ef.dictType())){
+						val = DictUtils.getDictValue(val.toString(), ef.dictType(), "");
+						//log.debug("Dictionary type value: ["+i+","+colunm+"] " + val);
+					}
+					// Get param type and type cast
+					Class<?> valType = Class.class;
+					if (os[1] instanceof Field){
+						valType = ((Field)os[1]).getType();
+					}else if (os[1] instanceof Method){
+						Method method = ((Method)os[1]);
+						if ("get".equals(method.getName().substring(0, 3))){
+							valType = method.getReturnType();
+						}else if("set".equals(method.getName().substring(0, 3))){
+							valType = ((Method)os[1]).getParameterTypes()[0];
+						}
+					}
+					//log.debug("Import value type: ["+i+","+column+"] " + valType);
+					try {
+						//如果导入的java对象,需要在这里自己进行变换。
+						if (valType == String.class){
+							String s = String.valueOf(val.toString());
+							if(StringUtils.endsWith(s, ".0")){
+								val = StringUtils.substringBefore(s, ".0");
+							}else{
+								val = String.valueOf(val.toString());
+							}
+						}else if (valType == Integer.class){
+							val = Double.valueOf(val.toString()).intValue();
+						}else if (valType == Long.class){
+							val = Double.valueOf(val.toString()).longValue();
+						}else if (valType == Double.class){
+							val = Double.valueOf(val.toString());
+						}else if (valType == Float.class){
+							val = Float.valueOf(val.toString());
+						}else if (valType == Date.class){
+							SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+							val=sdf.parse(val.toString());
+						}else if (valType == User.class){
+							val = UserUtils.getByUserName(val.toString());
+						}else if (valType == Office.class){
+							val = UserUtils.getByOfficeName(val.toString());
+						}else if (valType == Area.class){
+							val = UserUtils.getByAreaName(val.toString());
+						}else{
+							if (ef.fieldType() != Class.class){
+								val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString());
+							}else{
+								val = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(),
+										"fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString());
+							}
+						}
+					} catch (Exception ex) {
+						log.info("Get cell value ["+i+","+column+"] error: " + ex.toString());
+						val = null;
+					}
+					if(column == 1 || column == 2 || column == 3
+							|| column == 4 || column == 5 || column == 6 || column == 7
+							|| column == 8 || column == 9 || column == 10){
+						if(val == null || val == ""){
+							errMsg += "第+i+条,第"+column+"列数据不能为空";
+						}
+					}
+					// set entity value
+					if (os[1] instanceof Field){
+						if(Strings.isNullOrEmpty(errMsg)){
+							Reflections.invokeSetter(e, ((Field)os[1]).getName(), val);
+						}
+
+					}else if (os[1] instanceof Method){
+						String mthodName = ((Method)os[1]).getName();
+						if ("get".equals(mthodName.substring(0, 3))){
+							mthodName = "set"+StringUtils.substringAfter(mthodName, "get");
+						}
+						if(Strings.isNullOrEmpty(errMsg)){
+							Reflections.invokeMethod(e, mthodName, new Class[] {valType}, new Object[] {val});
+						}
+					}
+				}
+				sb.append(val+", ");
+			}
+			if(!"".equals(errMsg)){
+				errList.add(errMsg);
+			}else{
+				dataList.add(e);
+			}
+			log.debug("Read success: ["+i+"] "+sb.toString());
+		}
+		map.put("dataList",dataList);
+		map.put("errList",errList);
+		return map;
+	}*/
+
+//	/**
+//	 * 导入测试
+//	 */
+//	public static void main(String[] args) throws Throwable {
+//
+//		ImportExcel ei = new ImportExcel("target/export.xlsx", 1);
+//
+//		for (int i = ei.getDataRowNum(); i < ei.getLastDataRowNum(); i++) {
+//			Row row = ei.getRow(i);
+//			for (int j = 0; j < ei.getLastCellNum(); j++) {
+//				Object val = ei.getCellValue(row, j);
+//				System.out.print(val+", ");
+//			}
+//			System.out.print("\n");
+//		}
+//
+//	}
+    public static String replaceBlank(String str) {
+        String dest = "";
+        if (str!=null) {
+            Pattern p = Pattern.compile("\t|\r|\n");
+            Matcher m = p.matcher(str);
+            dest = m.replaceAll("");
+        }
+        return dest;
+    }
+
+ /*   public static void main(String[] args) {
+        replaceBlank("桩基框架-剪力墙结构\n" +
+                "(主体部分)空间钢桁架结构(屋顶部分)");
+    }*/
+}

+ 260 - 0
src/main/java/com/jeeplus/common/web/Servlets.java

@@ -0,0 +1,260 @@
+/**
+ * Copyright (c) 2005-2012 springside.org.cn
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ */
+package com.jeeplus.common.web;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.Validate;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import com.google.common.net.HttpHeaders;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.utils.Encodes;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.security.SystemAuthorizingRealm.Principal;
+import com.jeeplus.modules.sys.utils.UserUtils;
+
+/**
+ * Http与Servlet工具类.
+ * @author calvin/jeeplus
+ * @version 2014-8-19
+ */
+public class Servlets {
+
+	// -- 常用数值定义 --//
+	public static final long ONE_YEAR_SECONDS = 60 * 60 * 24 * 365;
+	
+	// 静态文件后缀
+	private final static String[] staticFiles = StringUtils.split(Global.getConfig("web.staticFile"), ",");
+	
+	// 动态映射URL后缀
+	private final static String urlSuffix = Global.getUrlSuffix();
+
+	/**
+	 * 设置客户端缓存过期时间 的Header.
+	 */
+	public static void setExpiresHeader(HttpServletResponse response, long expiresSeconds) {
+		// Http 1.0 header, set a fix expires date.
+		response.setDateHeader(HttpHeaders.EXPIRES, System.currentTimeMillis() + expiresSeconds * 1000);
+		// Http 1.1 header, set a time after now.
+		response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=" + expiresSeconds);
+	}
+
+	/**
+	 * 设置禁止客户端缓存的Header.
+	 */
+	public static void setNoCacheHeader(HttpServletResponse response) {
+		// Http 1.0 header
+		response.setDateHeader(HttpHeaders.EXPIRES, 1L);
+		response.addHeader(HttpHeaders.PRAGMA, "no-cache");
+		// Http 1.1 header
+		response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0");
+	}
+
+	/**
+	 * 设置LastModified Header.
+	 */
+	public static void setLastModifiedHeader(HttpServletResponse response, long lastModifiedDate) {
+		response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModifiedDate);
+	}
+
+	/**
+	 * 设置Etag Header.
+	 */
+	public static void setEtag(HttpServletResponse response, String etag) {
+		response.setHeader(HttpHeaders.ETAG, etag);
+	}
+
+	/**
+	 * 根据浏览器If-Modified-Since Header, 计算文件是否已被修改.
+	 * 
+	 * 如果无修改, checkIfModify返回false ,设置304 not modify status.
+	 * 
+	 * @param lastModified 内容的最后修改时间.
+	 */
+	public static boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response,
+			long lastModified) {
+		long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
+		if ((ifModifiedSince != -1) && (lastModified < ifModifiedSince + 1000)) {
+			response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * 根据浏览器 If-None-Match Header, 计算Etag是否已无效.
+	 * 
+	 * 如果Etag有效, checkIfNoneMatch返回false, 设置304 not modify status.
+	 * 
+	 * @param etag 内容的ETag.
+	 */
+	public static boolean checkIfNoneMatchEtag(HttpServletRequest request, HttpServletResponse response, String etag) {
+		String headerValue = request.getHeader(HttpHeaders.IF_NONE_MATCH);
+		if (headerValue != null) {
+			boolean conditionSatisfied = false;
+			if (!"*".equals(headerValue)) {
+				StringTokenizer commaTokenizer = new StringTokenizer(headerValue, ",");
+
+				while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) {
+					String currentToken = commaTokenizer.nextToken();
+					if (currentToken.trim().equals(etag)) {
+						conditionSatisfied = true;
+					}
+				}
+			} else {
+				conditionSatisfied = true;
+			}
+
+			if (conditionSatisfied) {
+				response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+				response.setHeader(HttpHeaders.ETAG, etag);
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * 设置让浏览器弹出下载对话框的Header.
+	 * 
+	 * @param fileName 下载后的文件名.
+	 */
+	public static void setFileDownloadHeader(HttpServletResponse response, String fileName) {
+		try {
+			// 中文文件名支持
+			String encodedfileName = new String(fileName.getBytes(), "ISO8859-1");
+			response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedfileName + "\"");
+		} catch (UnsupportedEncodingException e) {
+			e.getMessage();
+		}
+	}
+
+	/**
+	 * 取得带相同前缀的Request Parameters, copy from spring WebUtils.
+	 * 
+	 * 返回的结果的Parameter名已去除前缀.
+	 */
+	@SuppressWarnings("rawtypes")
+	public static Map<String, Object> getParametersStartingWith(ServletRequest request, String prefix) {
+		Validate.notNull(request, "Request must not be null");
+		Enumeration paramNames = request.getParameterNames();
+		Map<String, Object> params = new TreeMap<String, Object>();
+		String pre = prefix;
+		if (pre == null) {
+			pre = "";
+		}
+		while (paramNames != null && paramNames.hasMoreElements()) {
+			String paramName = (String) paramNames.nextElement();
+			if ("".equals(pre) || paramName.startsWith(pre)) {
+				String unprefixed = paramName.substring(pre.length());
+				String[] values = request.getParameterValues(paramName);
+				if (values == null || values.length == 0) {
+					values = new String[]{};
+					// Do nothing, no values found at all.
+				} else if (values.length > 1) {
+					params.put(unprefixed, values);
+				} else {
+					params.put(unprefixed, values[0]);
+				}
+			}
+		}
+		return params;
+	}
+
+	/**
+	 * 组合Parameters生成Query String的Parameter部分,并在paramter name上加上prefix.
+	 * 
+	 */
+	public static String encodeParameterStringWithPrefix(Map<String, Object> params, String prefix) {
+		StringBuilder queryStringBuilder = new StringBuilder();
+
+		String pre = prefix;
+		if (pre == null) {
+			pre = "";
+		}
+		Iterator<Entry<String, Object>> it = params.entrySet().iterator();
+		while (it.hasNext()) {
+			Entry<String, Object> entry = it.next();
+			queryStringBuilder.append(pre).append(entry.getKey()).append("=").append(entry.getValue());
+			if (it.hasNext()) {
+				queryStringBuilder.append("&");
+			}
+		}
+		return queryStringBuilder.toString();
+	}
+
+	/**
+	 * 客户端对Http Basic验证的 Header进行编码.
+	 */
+	public static String encodeHttpBasic(String userName, String password) {
+		String encode = userName + ":" + password;
+		return "Basic " + Encodes.encodeBase64(encode.getBytes());
+	}
+	
+	/**
+	 * 是否是Ajax异步请求
+	 * @param request
+	 */
+	public static boolean isAjaxRequest(HttpServletRequest request){
+		
+		String accept = request.getHeader("accept");
+		String xRequestedWith = request.getHeader("X-Requested-With");
+		Principal principal = UserUtils.getPrincipal();
+
+		// 如果是异步请求或是手机端,则直接返回信息
+		return ((accept != null && accept.indexOf("application/json") != -1 
+			|| (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
+			|| (principal != null && principal.isMobileLogin())));
+	}
+	
+	/**
+	 * 获取当前请求对象
+	 * @return
+	 */
+	public static HttpServletRequest getRequest(){
+		try{
+			return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
+		}catch(Exception e){
+			return null;
+		}
+	}
+
+	/**
+     * 判断访问URI是否是静态文件请求
+	 * @throws Exception 
+     */
+    public static boolean isStaticFile(String uri){
+		if (staticFiles == null){
+			try {
+				throw new Exception("检测到“app.properties”中没有配置“web.staticFile”属性。配置示例:\n#静态文件后缀\n"
+					+"web.staticFile=.css,.js,.png,.jpg,.gif,.jpeg,.bmp,.ico,.swf,.psd,.htc,.crx,.xpi,.exe,.ipa,.apk");
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+//		if ((StringUtils.startsWith(uri, "/static/") || StringUtils.endsWithAny(uri, sfs)) 
+//				&& !StringUtils.endsWithAny(uri, ".jsp") && !StringUtils.endsWithAny(uri, ".java")){
+//			return true;
+//		}
+		if (StringUtils.endsWithAny(uri, staticFiles) && !StringUtils.endsWithAny(uri, urlSuffix)
+				&& !StringUtils.endsWithAny(uri, ".jsp") && !StringUtils.endsWithAny(uri, ".java")){
+			return true;
+		}
+		return false;
+    }
+}

+ 260 - 0
src/main/java/com/jeeplus/common/websocket/onchat/ChatServer_bak.java

@@ -0,0 +1,260 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.websocket.onchat;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
+import org.java_websocket.WebSocket;
+import org.java_websocket.WebSocketImpl;
+import org.java_websocket.framing.Framedata;
+import org.java_websocket.handshake.ClientHandshake;
+import org.java_websocket.server.WebSocketServer;
+
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.SpringContextHolder;
+import com.jeeplus.common.websocket.utils.Constant;
+import com.jeeplus.modules.iim.entity.ChatHistory;
+import com.jeeplus.modules.iim.entity.LayGroupUser;
+import com.jeeplus.modules.iim.service.ChatHistoryService;
+import com.jeeplus.modules.iim.service.LayGroupService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+
+import java.util.List;
+
+public class ChatServer_bak extends WebSocketServer{
+
+	
+	public ChatServer_bak(int port) throws UnknownHostException {
+		super(new InetSocketAddress(port));
+	}
+
+	public ChatServer_bak(InetSocketAddress address) {
+		super(address);
+	}
+
+	/**
+	 * 触发连接事件
+	 */
+	@Override
+	public void onOpen( WebSocket conn, ClientHandshake handshake ) {
+//		Collection<String> onlineUsers = ChatServerPool.getOnlineUser();
+//		AjaxJson j = new AjaxJson();
+//		j.put("data", onlineUsers);
+//		ChatServerPool.sendMessageToUser(conn, "_online_all_status_"+j.getJsonStr());//首次登陆系统时,获取用户的在线状态
+//		System.out.println("有新连接加入!当前在线人数为"+j.toString());
+	}
+
+	/**
+	 * 触发关闭事件
+	 */
+	@Override
+	public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
+		userLeave(conn);
+		Collection<String> onlineUsers = ChatServerPool.getOnlineUser();
+		AjaxJson j = new AjaxJson();
+		j.put("data", onlineUsers);
+		ChatServerPool.sendMessage("_online_all_status_"+j.getJsonStr());//通知所有用户更新在线信息
+	}
+
+	/**
+	 * 客户端发送消息到服务器时触发事件
+	 */
+	@Override
+	public void onMessage(WebSocket conn, String message){
+		message = message.toString();
+		ChatHistoryService chatHistoryService = SpringContextHolder.getBean("chatHistoryService");
+		LayGroupService layGroupService = SpringContextHolder.getBean("layGroupService");
+		if(null != message && message.startsWith(Constant._online_user_)){//用户上线
+			System.out.println("用户上线");
+			String userId = message.replaceFirst(Constant._online_user_, "");
+			this.userjoin(userId,conn);
+			
+			//通知所有用户更新在线信息
+			Collection<String> onlineUsers = ChatServerPool.getOnlineUser();
+			AjaxJson j = new AjaxJson();
+			j.put("data", onlineUsers);
+			ChatServerPool.sendMessage("_online_all_status_"+j.getJsonStr());//通知所有用户更新在线信息
+
+			//读取离线信息
+			ChatHistory chat = new ChatHistory();
+			chat.setUserid2(userId);
+			chat.setStatus("0");
+			List<ChatHistory> list =chatHistoryService.findList(chat);
+			for(ChatHistory c : list){
+				String userid1 = c.getUserid1();
+				String sender = c.getUserid1();
+				if("group".equals(c.getType())){
+					sender=c.getUserid1().split(Constant._msg_)[0];
+					userid1=c.getUserid1().split(Constant._msg_)[1];
+				}
+				ChatServerPool.sendMessageToUser(conn,  sender+Constant._msg_+c.getUserid2()+Constant._msg_+c.getMsg()+Constant._msg_+UserUtils.getByLoginName(userid1).getPhoto()+Constant._msg_+c.getType()+Constant._msg_+UserUtils.getByLoginName(userid1).getName()+Constant._msg_+c.getCreateDate().getTime());//向所某用户发送消息
+				c.setStatus("1");//标记为已读
+				chatHistoryService.save(c);
+			}
+			
+			
+		}if(null != message && message.startsWith(Constant._leave_user_)){//用户离线
+			System.out.println("用户离线");
+			this.userLeave(conn);
+			Collection<String> onlineUsers = ChatServerPool.getOnlineUser();
+			AjaxJson j = new AjaxJson();
+			j.put("data", onlineUsers);
+			ChatServerPool.sendMessage("_online_all_status_"+j.getJsonStr());//通知所有用户更新在线信息
+		}if(null != message && message.contains(Constant._msg_)){//发送消息
+			System.out.println("用户消息");
+			String []arr = message.split(Constant._msg_);
+			String fromUser = arr[0];
+			String toUser = arr[1];//如果是私聊就是用户id,如果是群聊就是群组id
+			String msg = arr[2];
+			String avatar=arr[3];
+			String type=arr[4];
+			String fromUsername= arr[5];
+			String datatime = arr[6];
+			
+			
+			//保存聊天记录
+			ChatHistory chat = new ChatHistory();
+			
+			if("group".equals(type)){//如果是群聊
+				
+				List<LayGroupUser> layGroupUserlist = new ArrayList();
+				//群主
+				LayGroupUser owner = new LayGroupUser();
+				owner.setUser( layGroupService.get(toUser).getCreateBy());
+				layGroupUserlist.add(owner);
+				//群成员
+				List<LayGroupUser> zlist = layGroupService.get(toUser).getLayGroupUserList();
+				layGroupUserlist.addAll(zlist);
+				
+				for(LayGroupUser lgUser:layGroupUserlist){
+					if(fromUser.equals(lgUser.getUser().getLoginName())){
+						continue;//群聊消息不发给自己。
+					}
+					WebSocket toUserConn = null;//ChatServerPool.getWebSocketByUser(lgUser.getUser().getLoginName());
+					//群聊时信息先发送给群聊id(即toUser),在后台转发给所有非发送者的人的话,toUser就变成发送者。
+					String groupId = toUser;
+					//保存聊天记录
+					chat.setUserid1(groupId+Constant._msg_+fromUser);//群聊时保存群聊id和发送者id
+					chat.setUserid2(lgUser.getUser().getLoginName());//群中所有信息获得者人员
+					chat.setMsg(msg);
+					chat.setCreateDate(new Date());
+					chat.setType("group");  
+					if(toUserConn != null){
+						message = groupId+Constant._msg_+lgUser.getUser().getLoginName()+Constant._msg_+msg+Constant._msg_+avatar+Constant._msg_+type+Constant._msg_+fromUsername+Constant._msg_+datatime;
+						ChatServerPool.sendMessageToUser(toUserConn,message);//向所某用户发送消息
+						chat.setStatus("1");//设置为已读
+					}else{
+						//ChatServerPool.sendMessageToUser(conn, toUser+"_sys_对方现在离线,他将在上线后收到你的消息!");//同时向本人发送消息
+						chat.setStatus("0");//设置为未读
+					}
+				}
+				
+			}else{//如果是私聊
+				chat.setUserid1(fromUser);
+				chat.setUserid2(toUser);
+				chat.setMsg(msg);
+				chat.setType("friend");
+				chat.setCreateDate(new Date());
+				WebSocket toUserConn = null;//ChatServerPool.getWebSocketByUser(toUser);
+				if(toUserConn != null){
+					ChatServerPool.sendMessageToUser(toUserConn,message);//向所某用户发送消息
+					chat.setStatus("1");//设置为已读
+				}else{
+					ChatServerPool.sendMessageToUser(conn, toUser+"_sys_对方现在离线,他将在上线后收到你的消息!");//同时向本人发送消息
+					chat.setStatus("0");//设置为未读
+				}
+			}
+		
+			
+			chatHistoryService.save(chat);
+			
+		}
+	}
+	
+	@Override
+	public void onMessage(WebSocket conn, ByteBuffer buffer){
+		System.out.println("执行了发送消息的动作2");
+		 Charset charset = null;
+	        CharsetDecoder decoder = null;
+	        CharBuffer charBuffer = null;
+		try {
+			 charset = Charset.forName("UTF-8");
+	            decoder = charset.newDecoder();
+	            // charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空
+	            charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
+	            //return charBuffer.toString();
+		System.out.println( charBuffer.toString());
+		} catch (Exception ex) {
+		ex.printStackTrace();
+		}
+	}
+
+	public void onFragment( WebSocket conn, Framedata fragment ) {
+	}
+
+	/**
+	 * 触发异常事件
+	 */
+	@Override
+	public void onError( WebSocket conn, Exception ex ) {
+		ex.printStackTrace();
+		if( conn != null ) {
+			//some errors like port binding failed may not be assignable to a specific websocket
+		}
+	}
+
+	
+	/**
+	 * 用户加入处理
+	 * @param user
+	 */
+	public void userjoin(String user, WebSocket conn){
+//		AjaxJson j = new AjaxJson();
+//		j.put("type", "user_join");
+//		j.put("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
+//		MsgServerPool.sendMessage(j.getJsonStr());				//把当前用户加入到所有在线用户列表中
+//		String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"上线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
+//		MsgServerPool.sendMessage(joinMsg);						//向所有在线用户推送当前用户上线的消息
+//		j = new AjaxJson();
+//		j.put("type", "get_online_user");
+		ChatServerPool.addUser(user,conn);							//向连接池添加当前的连接对象
+//		j.put("list", MsgServerPool.getOnlineUser());
+//		MsgServerPool.sendMessageToUser(conn, j.getJsonStr());	//向当前连接发送当前在线用户的列表
+	}
+	
+	/**
+	 * 用户下线处理
+	 * @param conn
+	 */
+	public void userLeave(WebSocket conn){
+		String user = ChatServerPool.getUserByKey(conn);
+		boolean b = ChatServerPool.removeUser(conn);				//在连接池中移除连接
+//		if(b){
+//			AjaxJson j = new AjaxJson();
+//			j.put("type", "user_leave");
+//			j.put("user", "<a onclick=\"toUserMsg('"+user+"');\">"+user+"</a>");
+//			MsgServerPool.sendMessage(j.getJsonStr());			//把当前用户从所有在线用户列表中删除
+//			String joinMsg = "{\"from\":\"[系统]\",\"content\":\""+user+"下线了\",\"timestamp\":"+new Date().getTime()+",\"type\":\"message\"}";
+//			MsgServerPool.sendMessage(joinMsg);					//向在线用户发送当前用户退出的消息
+//		}
+	}
+	public static void main( String[] args ) throws InterruptedException , IOException {
+		WebSocketImpl.DEBUG = false;
+		int port = 8667; //端口
+		ChatServer_bak s = new ChatServer_bak(port);
+		s.start();
+		//System.out.println( "服务器的端口" + s.getPort() );
+	}
+
+}
+

+ 89 - 0
src/main/java/com/jeeplus/modules/API/iim/ImContactController.java

@@ -0,0 +1,89 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.API.iim;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.IdGen;
+import com.jeeplus.common.utils.SmackUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.iim.entity.*;
+import com.jeeplus.modules.iim.service.LayGroupService;
+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.service.OfficeService;
+import com.jeeplus.modules.sys.service.SystemService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.sysuseroffice.entity.Useroffice;
+import com.jeeplus.modules.sysuseroffice.service.UserofficeService;
+import org.codehaus.jackson.map.ObjectMapper;
+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.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+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.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 联系人Controller
+ * 
+ * @author jeeplus(seven修改)
+ * @version 2016-6-23
+ */
+//@Controller
+//@RequestMapping(value = "${frontPath}/iim/contact")
+public class ImContactController extends BaseController {
+
+//	@ResponseBody
+//	@RequestMapping(value = { "uploadImage", "uploadFile" })
+	public String uploadImage(HttpServletResponse response,MultipartHttpServletRequest multiRequest)
+			throws IllegalStateException, IOException {
+		String filepath = "";
+		String content = null;
+		LayFileJsonData data = new LayFileJsonData();
+		String contentType = "";
+		// 判断文件是否为空
+        Iterator<String> fileNames = multiRequest.getFileNames();
+        while(fileNames.hasNext()) {
+            //取得上传文件
+            MultipartFile file = multiRequest.getFile(fileNames.next());
+            if (!file.isEmpty()) {
+                contentType = file.getContentType();
+                // 文件保存路径
+                String realPath ="messages/"+ DateUtils.formatDate(new Date())+"/"+ UserUtils.getPrincipal() + "/";
+                OSSClientUtil ossUtil = new OSSClientUtil();
+                String newName = System.currentTimeMillis()+"-"+file.getOriginalFilename();
+
+                ossUtil.uploadFile2OSS(file.getInputStream(),realPath,newName);
+                filepath = Global.getAliDownloadUrl() + "/" + realPath + newName;
+
+                data.setName(file.getOriginalFilename());
+                data.setSrc(filepath);
+            }
+        }
+
+		ObjectMapper mapper = new ObjectMapper();
+		HashMap<String, Object> map = new HashMap<String, Object>();
+		map.put("code", "0");
+		map.put("data", data);
+
+		content = mapper.writeValueAsString(map);
+ 		return content;
+	}
+
+}

+ 222 - 0
src/main/java/com/jeeplus/modules/API/maillist/GroupController.java

@@ -0,0 +1,222 @@
+package com.jeeplus.modules.API.maillist;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.jeeplus.modules.utils.ErrorCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.IdGen;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.iim.dao.LayGroupDao;
+import com.jeeplus.modules.iim.dao.LayGroupUserDao;
+import com.jeeplus.modules.iim.entity.LayGroup;
+import com.jeeplus.modules.iim.entity.LayGroupUser;
+import com.jeeplus.modules.iim.service.LayGroupService;
+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;
+/**
+ * 我的群组Controller
+ * @author zmy
+ * @version 2017-04-17
+ */
+@Controller
+@RequestMapping(value = "${frontPath}/maillist/groups")
+public class GroupController extends BaseController{
+	@Autowired
+	private LayGroupDao layGroupDao;
+	@Autowired
+	private LayGroupService layGroupService;
+	@Autowired
+	private UserDao userDao;
+	@Autowired
+	private LayGroupUserDao layGroupUserDao;
+	/**
+	 * 我创建的群组
+	 */
+	@ResponseBody
+	@RequestMapping(value = "getMailListMyGroupList", method=RequestMethod.GET)
+	public AjaxJson findMyGroups(String id,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		AjaxJson j=new AjaxJson();
+		LayGroup laygroup=new LayGroup();
+		User user=new User();
+		user.setId(id);
+		laygroup.setCreateBy(user);
+		List<LayGroup> groupList=layGroupDao.findList(laygroup);
+		List<Map<String,Object>> mapList = Lists.newArrayList();
+		List<Map<String,Object>> mapList2 = Lists.newArrayList();
+		Map<String,Object> map2 = Maps.newHashMap();
+		map2.put("groupcount", groupList.size());
+		for(int i = 0; i < groupList.size(); i++){
+			LayGroup g = groupList.get(i);
+			Map<String,Object> map = Maps.newHashMap();
+			map.put("groupName",g.getGroupname());
+			map.put("avatar", g.getAvatar());
+			map.put("groupId", g.getId());
+			LayGroupUser lgu = new LayGroupUser();
+			lgu.setGroup(g);
+			List<LayGroupUser> lguList= layGroupUserDao.findList(lgu);
+			map.put("userCount", lguList.size());
+			mapList.add(map);						
+		}
+		map2.put("groupInfo", mapList);
+		mapList2.add(map2);
+		j.put("data", mapList2);
+		j.setErrorCode(ErrorCode.code_1004);
+		return j;
+	}
+	/**
+	 * 我加入的群组
+	 */
+	@ResponseBody
+	@RequestMapping(value = "getMailListAllGroupList", method=RequestMethod.GET)
+	public AjaxJson findAllGroups(String id,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		AjaxJson j=new AjaxJson();
+		User user=new User();
+		LayGroup laygroup=new LayGroup();
+		user.setId(id);	
+		laygroup.setCreateBy(user);
+		List<LayGroup> list=layGroupDao.findList(laygroup);
+		List<LayGroup> joinlist = layGroupService.findGroupList(user);
+		List<LayGroup> alllist=new ArrayList<LayGroup>();
+		alllist.addAll(list);
+		alllist.addAll(joinlist);				
+		List<Map<String,Object>> mapList2 = Lists.newArrayList();
+		Map<String,Object> map2 = Maps.newHashMap();
+		map2.put("groupcount", alllist.size());
+		List<Map<String,Object>> mapList = Lists.newArrayList();
+		for(int i = 0; i < alllist.size(); i++){
+			LayGroup g = alllist.get(i);
+			Map<String,Object> map = Maps.newHashMap();
+			map.put("groupName",g.getGroupname());
+			map.put("avatar", g.getAvatar());
+			map.put("groupId", g.getId());
+			LayGroupUser lgu = new LayGroupUser();
+			lgu.setGroup(g);
+			List<LayGroupUser> lguList= layGroupUserDao.findList(lgu);
+			map.put("userCount", lguList.size());
+			mapList.add(map);
+		}		
+		map2.put("groupInfo", mapList);
+		mapList2.add(map2);
+		j.put("data", mapList2);
+		j.setErrorCode(ErrorCode.code_1004);
+		return j;
+	}	
+	/**
+	 * 添加群组成员
+	 */
+	@ResponseBody
+	@RequestMapping(value="addMailListUser",method=RequestMethod.GET)
+	public AjaxJson addMailListUser(String ids,String groupId,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		AjaxJson j=new AjaxJson();
+		String idArry[]=ids.split(",");			
+		for(String id : idArry){		
+		User user=userDao.get(id);
+		LayGroup laygroup=layGroupService.get(groupId);
+		LayGroupUser lguser = new LayGroupUser();
+		lguser.setUser(user);
+		lguser.setGroup(laygroup);
+		 	if(layGroupUserDao.findList(lguser).size() == 0 && !user.getId().equals(laygroup.getCreateBy().getId())){
+		 		lguser.setId(IdGen.uuid());
+		 		lguser.preInsert();
+		 		layGroupUserDao.insert(lguser);	
+		 	}		 	
+		}	
+		j.setMsg("添加成员成功");
+		j.setErrorCode(ErrorCode.code_1004);
+		return j;
+	}
+	/**
+	 * 删除群组成员
+	 */
+	@ResponseBody
+	@RequestMapping(value="delMailListUser",method=RequestMethod.GET)
+	public AjaxJson delMailListUser(String lguserIds,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		AjaxJson j=new AjaxJson();
+		String idArry[]=lguserIds.split(",");
+		for(String id : idArry){
+			LayGroupUser lguser = new LayGroupUser();	
+			lguser.setId(id);
+			layGroupUserDao.delete(lguser);
+		}
+		j.setMsg("删除成员成功");
+		j.setErrorCode(ErrorCode.code_1004);
+		return j;
+	}
+	/**
+	 * 聊天信息
+	 */
+	@ResponseBody
+	@RequestMapping(value="getMailListMembersList",method=RequestMethod.GET)
+	public AjaxJson membersList(String groupId,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		 AjaxJson j=new AjaxJson();
+		 List<Map<String,Object>> mapList = Lists.newArrayList();
+		 List<Map<String,Object>> mapList1 = Lists.newArrayList();
+		 LayGroup layg= new LayGroup();
+		 layg.setId(groupId);
+		 LayGroupUser lgu = new LayGroupUser();
+		 lgu.setGroup(layg);
+		 Map<String,Object> map = Maps.newHashMap();
+		 List<LayGroupUser> lguList= layGroupUserDao.findList(lgu);
+		 for(LayGroupUser lu:lguList){
+				User u = userDao.get(lu.getUser());
+				Map<String,Object> map1 = Maps.newHashMap();
+				map1.put("name", u.getName());
+				map1.put("photo",u.getPhoto());	
+				mapList1.add(map1);
+		 }	
+		 map.put("groupMembers", mapList1);
+		 map.put("groupName", layGroupDao.get(groupId).getGroupname());
+		 mapList.add(map);
+		 j.put("data",mapList);
+		 j.setErrorCode(ErrorCode.code_1004);
+		 return j;
+	}	
+	/**
+	 * 修改群名
+	 */
+	@ResponseBody
+	@RequestMapping(value="saveMailListGroupName",method=RequestMethod.GET)
+	public AjaxJson saveGroupName(String groupId,String groupName,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		AjaxJson j=new AjaxJson();
+		LayGroup lay = layGroupDao.get(groupId);
+		lay.setGroupname(groupName);
+		layGroupDao.update(lay);
+		j.setMsg("修改成功");
+		j.setErrorCode(ErrorCode.code_1004);
+		return j;
+	}
+	/**
+	 * 退出群组
+	 */
+	@ResponseBody
+	@RequestMapping(value="delMailListGroup",method=RequestMethod.GET)
+	public AjaxJson delGroup(String id,String groupId,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes){
+		AjaxJson j=new AjaxJson();
+		User user =userDao.get(id);
+		LayGroup group = layGroupDao.get(groupId);
+		LayGroupUser layGroupUser =new LayGroupUser();
+		layGroupUser.setUser(user);
+		layGroupUser.setGroup(group);
+		layGroupUserDao.delete(layGroupUserDao.findList(layGroupUser).get(0));
+		j.setMsg("退出成功");
+		j.setErrorCode(ErrorCode.code_1004);
+		return j;
+	}
+}
+

File diff suppressed because it is too large
+ 1173 - 0
src/main/java/com/jeeplus/modules/API/oa/AttendanceController.java


+ 37 - 0
src/main/java/com/jeeplus/modules/API/userinfo/ManageInfoController.java

@@ -0,0 +1,37 @@
+package com.jeeplus.modules.API.userinfo;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.sys.dao.UserDao;
+/**
+ * 信息管理Controller
+ * @author zmy
+ * @version 2017-05-03
+ */
+
+@Controller
+@RequestMapping(value = "${frontPath}/userInfo/manageInfo")
+public class  ManageInfoController extends BaseController{
+	@Autowired
+	private UserDao userDao;
+	
+	
+	@ResponseBody
+	@RequestMapping(value = "getUserInfoManageInfoMap", method=RequestMethod.GET)
+	public AjaxJson manageInfo (String id,String officeId,HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes)
+	{ 
+		AjaxJson j=new AjaxJson();		
+		j.put("data",userDao.get(id));		
+		return j;
+	}
+}

+ 258 - 0
src/main/java/com/jeeplus/modules/API/works/manageCalendar/manageCalendarController.java

@@ -0,0 +1,258 @@
+package com.jeeplus.modules.API.works.manageCalendar;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.modules.iim.entity.MyCalendar;
+import com.jeeplus.modules.oa.service.ManageCalendarService;
+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.utils.ErrorCode;
+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.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.text.ParseException;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Created by Meng on 2017/6/20.
+ */
+@Controller
+@RequestMapping(value = "${frontPath}/work/manageCalendar")
+public class manageCalendarController {
+
+    @Autowired
+    ManageCalendarService manageCalendarService;
+
+    /**
+     * 本月所有拥有报告的日期
+     *
+     * @return
+     * @throws java.text.ParseException
+     */
+    @ResponseBody
+    @RequestMapping(value = "getManageCalendarByMonth", method = RequestMethod.GET)
+    public AjaxJson getManageCalendarByMonth(HttpServletRequest request) throws ParseException {
+        AjaxJson json = new AjaxJson();
+        String userId = request.getParameter("userId");
+        String officeId = request.getParameter("officeId");
+        String date = request.getParameter("date");
+        User user;
+        if(UserUtils.getUser()!=null){
+            user =UserUtils.getUser();
+        }else {
+            user =UserUtils.get(userId);
+        }
+        if(!UserUtils.isManager()){
+            json.setMsg("当前用户在本公司非管理员,您无权查看管理日志");
+            json.setErrorCode(ErrorCode.code_1010);
+            json.setSuccess(false);
+            return json;
+        }
+        List list =  manageCalendarService.getManageCalendarByMonth(date);
+        json.put("data",list);
+        json.setErrorCode(ErrorCode.code_1004);
+        return json;
+    }
+
+    /**
+     * 指定日期所有报告
+     *
+     * @return
+     * @throws java.text.ParseException
+     */
+    @ResponseBody
+    @RequestMapping(value = "getManageCalendarByDate", method = RequestMethod.GET)
+    public AjaxJson getManageCalendarByDate(HttpServletRequest request) throws ParseException {
+        AjaxJson json = new AjaxJson();
+        String userId = request.getParameter("userId");
+
+        String date = request.getParameter("date");
+        User user = UserUtils.getUser();
+        if(user == null || user.getId() ==null){
+            user = UserUtils.get(userId);
+        }else{
+        }
+        try{
+            if(!UserUtils.isManager()){
+                json.setMsg("当前用户在本公司非管理员,您无权查看管理日志");
+                json.setErrorCode(ErrorCode.code_1010);
+                json.setSuccess(false);
+                return json;
+            }
+        }catch (Exception e){
+            json.setMsg("当前用户在本公司非管理员,您无权查看管理日志");
+            json.setErrorCode(ErrorCode.code_1010);
+            json.setSuccess(false);
+            return json;
+        }
+        List list =  manageCalendarService.getReportUserAppList(date);
+        json.put("data",list);
+        json.setErrorCode(ErrorCode.code_1004);
+        return json;
+    }
+
+    /**
+     * 指定日期所有用户
+     *
+     * @return
+     * @throws java.text.ParseException
+     */
+    @ResponseBody
+    @RequestMapping(value = "getUsersByDate", method = RequestMethod.GET)
+    public AjaxJson getUsersByDate(HttpServletRequest request) throws ParseException {
+        AjaxJson json = new AjaxJson();
+        String userId = request.getParameter("userId");
+        String count = request.getParameter("count");
+        String date = request.getParameter("date");
+        User user = UserUtils.getUser();
+        if(user == null || user.getId() ==null){
+            user = UserUtils.get(userId);
+        }else{
+        }
+        try{
+            if(!UserUtils.isManager()){
+                json.setMsg("当前用户在本公司非管理员,您无权查看管理日志");
+                json.setErrorCode(ErrorCode.code_1010);
+                json.setSuccess(false);
+                return json;
+            }
+        }catch (Exception e){
+            json.setMsg("当前用户在本公司非管理员,您无权查看管理日志");
+            json.setErrorCode(ErrorCode.code_1010);
+            json.setSuccess(false);
+            return json;
+        }
+
+        List list =  manageCalendarService.getReportUserAppList(date);
+        if(count.equals("1")){
+            Map map = (Map)list.get(0);
+            Map map1 = (Map)map.get("workReports");
+            List<Map> mapList1 =  (List)map1.get("workReport");
+            List list1 = new ArrayList();
+            json.put("data",mapList1);
+        }else if(count.equals("2")){
+            Map map = (Map)list.get(1);
+            Map map1 = (Map)map.get("workOutSignIns");
+            List<Map> mapList1 =  (List)map1.get("workOutSignIn");
+            json.put("data",mapList1);
+        }else if(count.equals("3")){
+            Map map = (Map)list.get(2);
+            List list1 = new ArrayList();
+            Map map1 = (Map)map.get("attendances");
+            List<Map> mapList1 =  (List)map1.get("late");
+            List<Map> mapList2 =  (List)map1.get("onDuty");
+            List<Map> mapList3 =  (List)map1.get("leaveEarly");
+            List<Map> mapList4 =  (List)map1.get("offDut");
+            if(mapList1!=null && mapList1.size()!=0){
+                for (Map m:mapList1){
+                    list1.add(m);
+                }
+            }
+            if(mapList2!=null && mapList2.size()!=0){
+                for (Map m:mapList2){
+                    list1.add(m);
+                }
+            }
+            if(mapList3!=null && mapList3.size()!=0){
+                for (Map m:mapList3){
+                    list1.add(m);
+                }
+            }
+            if(mapList4!=null && mapList4.size()!=0){
+                for (Map m:mapList4){
+                    list1.add(m);
+                }
+            }
+            json.put("data",list1);
+        }else if(count.equals("4")){
+            Map map = (Map)list.get(3);
+            List list1 = new ArrayList();
+            Map map1 = (Map)map.get("audits");
+            List<Map> mapList1 =  (List)map1.get("workSealFrom");
+            List<Map> mapList2 =  (List)map1.get("leave");
+            List<Map> mapList3 =  (List)map1.get("oaEvection");
+            List<Map> mapList4 =  (List)map1.get("workOvertimeForm");
+            if(mapList1!=null && mapList1.size()!=0){
+                for (Map m:mapList1){
+                    list1.add(m);
+                }
+            }
+            if(mapList2!=null && mapList2.size()!=0){
+                for (Map m:mapList2){
+                    list1.add(m);
+                }
+            }
+            if(mapList3!=null && mapList3.size()!=0){
+                for (Map m:mapList3){
+                    list1.add(m);
+                }
+            }
+            if(mapList4!=null && mapList4.size()!=0){
+                for (Map m:mapList4){
+                    list1.add(m);
+                }
+            }
+            json.put("data",list1);
+        }else if(count.equals("31")){
+            Map map = (Map)list.get(2);
+            Map map1 = (Map)map.get("attendances");
+            List<Map> mapList =  (List)map1.get("late");
+            json.put("data",mapList);
+        }else if(count.equals("32")){
+            Map map = (Map)list.get(2);
+            Map map1 = (Map)map.get("attendances");
+            List<Map> mapList =  (List)map1.get("onDuty");
+            json.put("data",mapList);
+        }else if(count.equals("33")){
+            Map map = (Map)list.get(2);
+            Map map1 = (Map)map.get("attendances");
+            List<Map> mapList = (List)map1.get("leaveEarly");
+            json.put("data",mapList);
+        }else if(count.equals("34")){
+            Map map = (Map)list.get(2);
+            Map map1 = (Map)map.get("attendances");
+            List<Map> mapList = (List)map1.get("offDut");
+            json.put("data",mapList);
+        }else if(count.equals("41")){
+            Map map = (Map)list.get(3);
+            Map map1 = (Map)map.get("audits");
+            List<Map> mapList = (List)map1.get("workSealFrom");
+            json.put("data",mapList);
+        }else if(count.equals("42")){
+            Map map = (Map)list.get(3);
+            Map map1 = (Map)map.get("audits");
+            List<Map> mapList = (List)map1.get("leave");
+            json.put("data",mapList);
+        }else if(count.equals("43")){
+            Map map = (Map)list.get(3);
+            Map map1 = (Map)map.get("audits");
+            List<Map> mapList = (List)map1.get("oaEvection");
+            json.put("data",mapList);
+        }else if(count.equals("44")){
+            Map map = (Map)list.get(3);
+            Map map1 = (Map)map.get("audits");
+            List<Map> mapList = (List)map1.get("workOvertimeForm");
+            json.put("data",mapList);
+        }else if(count.equals("45")){
+            Map map = (Map)list.get(3);
+            Map map1 = (Map)map.get("audits");
+            List<Map> mapList = (List)map1.get("workGoOut");
+            json.put("data",mapList);
+        }
+        json.setErrorCode(ErrorCode.code_1004);
+        return json;
+    }
+
+}

+ 265 - 0
src/main/java/com/jeeplus/modules/API/works/oaallccontroller/OaAController.java

@@ -0,0 +1,265 @@
+package com.jeeplus.modules.API.works.oaallccontroller;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.common.websocket.onchat.ChatServerPool;
+import com.jeeplus.modules.oaall.entity.OaAll;
+import com.jeeplus.modules.oaall.service.OaAllService;
+import com.jeeplus.modules.oabuy.entity.OaBuy;
+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.dao.UserDao;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.utils.ErrorCode;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
+import org.java_websocket.WebSocket;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLDecoder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * 流程
+ */
+@RequestMapping(value = "${frontPath}/oaall/oaall")
+@Controller
+public class OaAController extends BaseController {
+    @Autowired
+    private OaAllService oaAllService;
+    @Autowired
+    private UserDao userDao;
+
+    @Autowired
+    private ApprovalCopyService approvalCopyService;
+
+    @Autowired
+    private PushinfoService pushinfoService;
+
+    /**
+     * 启动采购申请
+     *
+     * @param request
+     * @param response
+     */
+    @Transactional
+    @ResponseBody
+    @RequestMapping(value = "saveOaAll", method = RequestMethod.POST)
+    public AjaxJson oaAll(HttpServletRequest request, HttpServletResponse response) throws ParseException {
+        AjaxJson json = new AjaxJson();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        try {
+            Map<String, Object> variables = Maps.newHashMap();
+            HashMap<String, String> requestMap = findRequestMap(request);
+
+            String applyContent = URLDecoder.decode(requestMap.get("applyContent")==null?"":requestMap.get("applyContent"), "UTF-8");
+            String approveDetail = URLDecoder.decode(requestMap.get("approveDetail")==null?"":requestMap.get("approveDetail"), "UTF-8");
+            String id = URLDecoder.decode(requestMap.get("userId")==null?"":requestMap.get("userId"), "UTF-8");
+            String approverId = URLDecoder.decode(requestMap.get("approverId")==null?"":requestMap.get("approverId"), "UTF-8");
+            String CCId = URLDecoder.decode(requestMap.get("CCId")==null?"":requestMap.get("CCId"), "UTF-8");
+            String delFlag="0"; //审核流程状态标记 0 待审核 1 审核完成
+            User user = new User(); //记录请假人的
+            OaAll oaAll = new OaAll();
+            String type = "1";
+            String alias = "1";
+            List<String> assigneeList=new ArrayList<String>(); //分配任务的人员
+            if(approverId!=null && !approverId.equals("")) {
+                if (approverId.contains(UserUtils.getUser().getId())){
+                    json.setMsg("通用审批申请失败,审批人不能为本人");
+                    json.setErrorCode(ErrorCode.code_1010);
+                    json.setSuccess(false);
+                    return json;
+                }
+                String[] approverIds = approverId.split(",");
+                for (int i =0 ;i<approverIds.length;i++){
+                    assigneeList.add(approverIds[i]);
+                    /*String key = "auditUserId"+ (i+1);
+                    variables.put(key, approverIds[i]);*/
+                }
+                type = approverIds.length+"";
+                alias = approverIds[0];
+            }
+            variables.put("assigneeList", assigneeList);
+            variables.put("count",assigneeList.size());
+            User CC = new User();
+            CC.setId(CCId);
+            user.setId(id);
+            oaAll.setUser(user);
+            oaAll.setApplyContent(applyContent);
+            oaAll.setApproveDetail(approveDetail);
+            oaAll.setCompanyId(UserUtils.getSelectCompany()==null?"":UserUtils.getSelectCompany().getId());
+            oaAll.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+            oaAll.setCreateBy(user);
+            oaAll.setUpdateBy(user);
+            oaAll.setDelFlag(delFlag);
+            oaAll.setStatus("1");
+            oaAllService.save(oaAll, variables);
+            ApprovalCopy approvalCopy = new ApprovalCopy();
+            approvalCopy.setCCId(CCId==null?"":CCId);
+            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", "allApprove");
+
+            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){
+                json.setSuccess(true);
+                json.setErrorCode(ErrorCode.code_1004);
+                json.setMsg("通用审批申请已经提交");
+                json.put("id", oaAll.getId());
+            }else {
+                json.setMsg("通用审批申请推送失败");
+                json.setErrorCode(ErrorCode.code_2006);
+                json.setSuccess(false);
+            }
+        } catch (Exception e) {
+            logger.error("启动通用审批流程失败:", e);
+            json.setSuccess(false);
+            json.setErrorCode(ErrorCode.code_2004);
+            json.setMsg("启动通用审批流程失败");
+        }
+        return json;
+    }
+
+    /**
+     * 保存附件
+     */
+    @Transactional
+    @ResponseBody
+    @RequestMapping(value = "saveFile",method=RequestMethod.POST)
+    public AjaxJson saveFile(MultipartHttpServletRequest multiRequest,HttpServletRequest servletRequest) throws Exception{
+        AjaxJson j=new AjaxJson();
+        try {
+            String id = multiRequest.getParameter("id");
+            OaAll oaAll =  oaAllService.getById(id);
+            OSSClientUtil ossUtil =new OSSClientUtil();
+
+            Iterator<String> fileNames = multiRequest.getFileNames();
+            String thisFiles = oaAll.getFiles();
+            String filePaths= "";
+            System.out.println("-----------开始------------------");
+            while(fileNames.hasNext()){
+
+                //取得上传文件
+                MultipartFile file = multiRequest.getFile(fileNames.next());
+                if(file != null){
+                    //取得当前上传文件的文件名称
+                    //String filePath= ossUtil.uploadFile2OSS(file, "oaAll");
+                    OSSClientUtil ossClientUtil = new OSSClientUtil();
+                    String filePath= oaAllService.uploadFile(ossClientUtil,file,oaAll,"67");
+                    filePaths = filePath;
+                }
+            }
+            /*if(thisFiles==null || thisFiles.equals("")){
+                if(filePaths.contains(",")){
+                    oaAll.setFiles(filePaths.substring(1, filePaths.length() - 1));
+                }else {
+                    oaAll.setFiles(filePaths);
+                }
+            }else{
+                filePaths = thisFiles+","+filePaths;
+                oaAll.setFiles(filePaths);
+            }*/
+            System.out.println("-----------结束------------------");
+            oaAllService.saveFile(oaAll);
+            j.put("filePath",filePaths);
+            j.setSuccess(true);
+            j.setErrorCode(ErrorCode.code_1004);
+            j.setMsg("上传成功!");
+        }catch (Exception e){
+            j.put("filePath","");
+            j.setSuccess(false);
+            j.setMsg("上传失败!");
+            j.setErrorCode(ErrorCode.code_2004);
+        }finally {
+            return j;
+        }
+    }
+
+    /**
+     * 获取详情
+     * @param
+     * @return
+     */
+    @RequestMapping(value = "getOaAllById", method=RequestMethod.GET)
+    @ResponseBody
+    public AjaxJson getOaAllById(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        AjaxJson j = new AjaxJson();
+        String id = request.getParameter("id");
+        String type = request.getParameter("type");
+        Map map = oaAllService.getLeaveById(id,type);
+        if( map==null){
+            j.setSuccess(false);
+            j.setMsg("获取通用审批详情失败");
+            j.setErrorCode(ErrorCode.code_2005);
+            j.put("data",map);
+        }
+        else{
+            j.put("data", map);
+            j.setMsg("获取通用审批详情成功");
+            j.setErrorCode(ErrorCode.code_1004);
+        }
+        return j;
+    }
+}

+ 309 - 0
src/main/java/com/jeeplus/modules/API/works/oabuycontroller/OaBController.java

@@ -0,0 +1,309 @@
+package com.jeeplus.modules.API.works.oabuycontroller;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.utils.JPushClientUtil;
+import com.jeeplus.common.utils.JsonUtil;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.buydetails.entity.BuyDetails;
+import com.jeeplus.modules.oabuy.entity.OaBuy;
+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.dao.UserDao;
+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.utils.ErrorCode;
+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.workovertimeform.entity.WorkOvertimeForm;
+import com.jeeplus.modules.workovertimeform.service.WorkOvertimeFormService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLDecoder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * 流程
+ */
+@RequestMapping(value = "${frontPath}/oabuy/oabuy")
+@Controller
+public class OaBController extends BaseController {
+    @Autowired
+    private OaBuyService oaBuyService;
+    @Autowired
+    private UserDao userDao;
+    @Autowired
+    private WorkClientAttachmentDao workClientAttachmentService;
+    @Autowired
+    private WorkattachmentService workattachmentService;
+
+    @Autowired
+    private ApprovalCopyService approvalCopyService;
+
+    @Autowired
+    private PushinfoService pushinfoService;
+
+    /**
+     * 启动采购申请
+     *
+     * @param request
+     * @param response
+     */
+    @Transactional
+    @ResponseBody
+    @RequestMapping(value = "saveOaBuy", method = RequestMethod.POST)
+    public AjaxJson oaBuy(HttpServletRequest request, HttpServletResponse response) throws ParseException {
+        AjaxJson json = new AjaxJson();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            Map<String, Object> variables = Maps.newHashMap();
+            HashMap<String, String> requestMap = findRequestMap(request);
+
+            String applyContent = URLDecoder.decode(requestMap.get("applyContent")==null?"":requestMap.get("applyContent"), "UTF-8");
+            String buySort = URLDecoder.decode(requestMap.get("buySort")==null?"":requestMap.get("buySort"), "UTF-8");
+            String id = URLDecoder.decode(requestMap.get("userId")==null?"":requestMap.get("userId"), "UTF-8");
+            String totalPrice = URLDecoder.decode(requestMap.get("totalPrice")==null?"":requestMap.get("totalPrice"), "UTF-8");
+            String deliverDate = URLDecoder.decode(requestMap.get("deliverDate")==null?"":requestMap.get("deliverDate"), "UTF-8");
+            String payStyle = URLDecoder.decode(requestMap.get("payStyle")==null?"":requestMap.get("payStyle"), "UTF-8");
+            String CCId = URLDecoder.decode(requestMap.get("CCId")==null?"":requestMap.get("CCId"), "UTF-8");
+            String approverId = URLDecoder.decode(requestMap.get("approverId")==null?"":requestMap.get("approverId"), "UTF-8");
+            String buyDetailsList = URLDecoder.decode(requestMap.get("buyDetailsList")==null?"":requestMap.get("buyDetailsList"), "UTF-8");
+            String remark = URLDecoder.decode(requestMap.get("remarks")==null?"":requestMap.get("remarks"), "UTF-8");
+            String delFlag="0"; //审核流程状态标记 0 待审核 1 审核完成
+            User user = new User(); //记录请假人的
+            OaBuy oaBuy = new OaBuy();
+            String type = "1";
+            String alias = "1";
+            List<String> assigneeList=new ArrayList<String>(); //分配任务的人员
+            if(approverId!=null && !approverId.equals("")) {
+                if (approverId.contains(UserUtils.getUser().getId())){
+                    json.setMsg("采购申请失败,审批人不能为本人");
+                    json.setErrorCode(ErrorCode.code_1010);
+                    json.setSuccess(false);
+                    return json;
+                }
+                String[] approverIds = approverId.split(",");
+                for (int i =0 ;i<approverIds.length;i++){
+                    assigneeList.add(approverIds[i]);
+                    /*String key = "auditUserId"+ (i+1);
+                    variables.put(key, approverIds[i]);*/
+                }
+                type = approverIds.length+"";
+                alias = approverIds[0];
+            }
+            variables.put("assigneeList", assigneeList);
+            variables.put("count",assigneeList.size());
+            User CC = new User();
+            CC.setId(CCId);
+            user.setId(id);
+            oaBuy.setUser(user);
+            oaBuy.setApplyContent(applyContent);
+            oaBuy.setBuySort(buySort);
+            if(StringUtils.isNotBlank(deliverDate)){
+                oaBuy.setDeliverDate(sdf.parse(deliverDate));
+            }
+            List<BuyDetails> buyDetailsList2 = new ArrayList<BuyDetails>();
+            if(StringUtils.isNotBlank(buyDetailsList)){
+                List<BuyDetails> detailsList = JsonUtil.json_to_list(buyDetailsList, BuyDetails.class);
+                if(detailsList!=null && detailsList.size()>0){
+                    for (int i = 0; i < detailsList.size(); i++) {
+                        BuyDetails buyDetails = detailsList.get(i);
+                        buyDetails.setId("");
+                        buyDetailsList2.add(buyDetails);
+                    }
+                }
+
+            }
+            oaBuy.setBuyDetailsList(buyDetailsList2);
+            oaBuy.setTotalPrice(totalPrice);
+            oaBuy.setPayStyle(payStyle);
+            oaBuy.setRemarks(remark);
+            oaBuy.setCompanyId(UserUtils.getSelectCompany()==null?"":UserUtils.getSelectCompany().getId());
+            oaBuy.setOfficeId(UserUtils.getSelectOffice()==null?"":UserUtils.getSelectOffice().getId());
+            oaBuy.setCreateBy(user);
+            oaBuy.setUpdateBy(user);
+            oaBuy.setDelFlag(delFlag);
+            oaBuy.setStatus("1");
+            oaBuyService.save(oaBuy, variables);
+            ApprovalCopy approvalCopy = new ApprovalCopy();
+            approvalCopy.setCCId(CCId==null?"":CCId);
+            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){
+                json.setSuccess(true);
+                json.setErrorCode(ErrorCode.code_1004);
+                json.setMsg("采购申请已经提交");
+                json.put("id", oaBuy.getId());
+            }else {
+                json.setMsg("采购申请推送失败");
+                json.setErrorCode(ErrorCode.code_2006);
+                json.setSuccess(false);
+            }
+        } catch (Exception e) {
+            logger.error("启动采购流程失败:", e);
+            json.setSuccess(false);
+            json.setErrorCode(ErrorCode.code_2004);
+            json.setMsg("启动采购流程失败");
+        }
+        return json;
+    }
+
+    /**
+     * 保存附件
+     */
+    @Transactional
+    @ResponseBody
+    @RequestMapping(value = "saveFile",method=RequestMethod.POST)
+    public AjaxJson saveFile(MultipartHttpServletRequest multiRequest,HttpServletRequest servletRequest) throws Exception{
+        AjaxJson j=new AjaxJson();
+        try {
+            String id = multiRequest.getParameter("id");
+            OaBuy oaBuy =  oaBuyService.getById(id);
+            OSSClientUtil ossUtil =new OSSClientUtil();
+
+            Iterator<String> fileNames = multiRequest.getFileNames();
+            System.out.println("-----------开始------------------");
+           /* while(fileNames.hasNext()){
+                MultipartFile file = multiRequest.getFile(fileNames.next());
+                if(file != null && !file.isEmpty() &&file.getSize()>0){
+                    String fileName = file.getOriginalFilename();
+                    String fileType = fileName.substring(fileName.lastIndexOf("."));
+                    String url = ossUtil.uploadFile2OSS(file, "oaBuy");
+                    WorkClientAttachment workattachment = new WorkClientAttachment();
+                    workattachment.setUrl(url);
+                    workattachment.setType(fileType);
+                    workattachment.setAttachmentName(fileName);
+                    workattachment.setAttachmentUser(UserUtils.getUser().getId());
+                    workattachment.setAttachmentId(oaBuy.getId());
+                    workattachment.setAttachmentFlag("69");
+                    workClientAttachmentService.insert(workattachment);
+                }
+            }
+            List<Workattachment> attachmentList = workattachmentService.getListByAttachmentIdAndFlag(id, "69");
+            String filePath = ",";
+            if(attachmentList!=null && attachmentList.size()>0){
+                for (int i = 0; i < attachmentList.size(); i++) {
+                    if(StringUtils.isNotBlank(attachmentList.get(i).getUrl())){
+                        filePath += attachmentList.get(i).getUrl();
+                    }
+                }
+            }
+            if(filePath.length()>2){
+                filePath = filePath.substring(1);
+            }*/
+            String thisFiles = oaBuy.getFiles();
+            String filePaths= "";
+            while(fileNames.hasNext()){
+
+                //取得上传文件
+                MultipartFile file = multiRequest.getFile(fileNames.next());
+                if(file != null){
+                    //取得当前上传文件的文件名称
+                    //String filePath= ossUtil.uploadFile2OSS(file, "oaBuy");
+                    OSSClientUtil ossClientUtil = new OSSClientUtil();
+                    String filePath= oaBuyService.uploadFile(ossClientUtil,file,oaBuy,"69");
+                    filePaths = filePath;
+                }
+            }
+            System.out.println("-----------结束------------------");
+            j.put("filePath",filePaths);
+            j.setSuccess(true);
+            j.setErrorCode(ErrorCode.code_1004);
+            j.setMsg("上传成功!");
+        }catch (Exception e){
+            j.put("filePath","");
+            j.setSuccess(false);
+            j.setMsg("上传失败!");
+            j.setErrorCode(ErrorCode.code_2004);
+        }finally {
+            return j;
+        }
+    }
+
+    /**
+     * 获取详情
+     * @param
+     * @return
+     */
+    @RequestMapping(value = "getOaBuyById", method=RequestMethod.GET)
+    @ResponseBody
+    public AjaxJson getOaBuyById(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        AjaxJson j = new AjaxJson();
+        String id = request.getParameter("id");
+        String type = request.getParameter("type");
+        Map map = oaBuyService.getBuyById(id,type);
+        if( map==null){
+            j.setSuccess(false);
+            j.setMsg("获取采购详情失败");
+            j.setErrorCode(ErrorCode.code_2005);
+            j.put("data",map);
+        }
+        else{
+            j.put("data", map);
+            j.setMsg("获取采购详情成功");
+            j.setErrorCode(ErrorCode.code_1004);
+        }
+
+        return j;
+    }
+}

+ 231 - 0
src/main/java/com/jeeplus/modules/API/works/pushInfo/pushInfoCortroller.java

@@ -0,0 +1,231 @@
+package com.jeeplus.modules.API.works.pushInfo;
+
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.appversion.service.AppversionsService;
+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.sysuseroffice.entity.Useroffice;
+import com.jeeplus.modules.utils.ErrorCode;
+import com.jeeplus.modules.workcompanyinfo.service.CompanyinfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+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
+@RequestMapping(value = "${frontPath}/pushInfo")
+public class pushInfoCortroller extends BaseController {
+
+	@Autowired
+	private PushinfoService pushinfoService;
+    @Autowired
+    private AppversionsService appversionsService;
+    @Autowired
+    private CompanyinfoService companyinfoService;
+
+	@ResponseBody
+	@RequestMapping(value = "pushInfoList", method = RequestMethod.GET)
+	public AjaxJson pushInfoList(HttpServletRequest request, HttpServletResponse response) {
+		AjaxJson json = new AjaxJson();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        HashMap requestMap = findRequestMap(request);
+        String requestType = (String)requestMap.get("type");
+        String mobile  = (String)requestMap.get("mobile");
+        String companyId  = (String)requestMap.get("companyId");
+        String pageNo  = (String)requestMap.get("pageNo");
+        try {
+            Pushinfo pushinfo = new Pushinfo();
+            User user = UserUtils.getUser();
+            pushinfo.setDelFlag("0");
+            if (requestType!=null && requestType.equals("1")){
+                pushinfo.setParentType("all");
+                pushinfo.setPushUserId("allpushusers");
+            }else {
+                pushinfo.setPushUserId(user.getId());
+                pushinfo.setParentType("single");
+            }
+            if (mobile!=null){
+                if (mobile.equals("ios")){
+                    pushinfo.setMobile("ios");
+                }else if (mobile.equals("android")){
+                    pushinfo.setMobile("android");
+                }
+            }
+            if (companyId!=null){
+                pushinfo.setCompanyId(companyId);
+            }
+            Page<Pushinfo> page = pushinfoService.findPushList(new Page<Pushinfo>(request, response), pushinfo);
+            List<Pushinfo> list = page.getList();
+            List<Map> mapList = new ArrayList<>();
+            if(list==null){
+                json.setSuccess(false);
+                json.setErrorCode(ErrorCode.code_2005);
+                json.setMsg("获取列表失败");
+                json.put("data", mapList);
+            }else {
+                json.put("maxNum", page.getCount());
+                if(Integer.parseInt(pageNo)<=page.getTotalPage()) {
+                    for (Pushinfo p : list) {
+                        Map map = new HashMap();
+                        String type = p.getType();
+                        String createDate = sdf.format(p.getCreateDate()).substring(5, 10);
+                        String url = p.getAddcontent() == null ? "" : p.getAddcontent();
+                        map.put("type", p.getType() == null ? "" : p.getType());
+                        map.put("title", p.getTitle() == null ? "" : p.getTitle());
+                        map.put("content", p.getContent() == null ? "" : p.getContent());
+                        map.put("contents", p.getRemarks() == null ? "" : p.getRemarks());
+                        map.put("remarks", p.getStatus() == null ? "" : p.getStatus());
+                        map.put("id", p.getPushId() == null ? "" : p.getPushId());
+                        map.put("createDate", createDate == null ? "" : createDate);
+                        map.put("parentType", p.getParentType() == null ? "" : p.getParentType());
+                        String state = "";
+                        String procDefKey = "";
+                        String img = "";
+                        if (type.equals("2001") && p.getRemarks() != null) {
+                            url = "";
+                            if (StringUtils.isNotBlank(p.getAddcontent()) && (p.getAddcontent().contains("&gt;") || p.getAddcontent().contains("<p>"))) {
+                                state = "1";
+                            } else {
+                                state = "2";
+                            }
+                            //img = p.getAddcontent() == null || p.getAddcontent().equals("") ? "" : p.getAddcontent();
+                        } else if (type.contains("400") && p.getAddcontent() != null) {
+                            procDefKey = p.getAddcontent();
+                        } else if (type.equals("2002")){  //加入企业申请
+                            procDefKey = p.getAddcontent();
+                            Pushinfo pushinfo1 = new Pushinfo();
+                            pushinfo1.setPushId(p.getPushId());
+                            List<Pushinfo> pushinfos = pushinfoService.getByPushId(pushinfo1);
+                            try {
+                                Useroffice companyinfo  = companyinfoService.get(p.getPushId());
+                                if (pushinfos!=null && pushinfos.size()!=0) {
+                                    Pushinfo push = pushinfos.get(0);
+                                    if (StringUtils.isNotBlank(push.getStatus())&& push.getStatus().equals("1")){
+                                        map.put("selectStatus", "1");
+                                        map.put("officeName", companyinfo.getCreateBy().getOffice().getName());
+                                        map.put("comment", companyinfo.getRemarks());
+                                        map.put("actStuatus", companyinfo.getStatus());
+                                    }else {
+                                        map.put("selectStatus", "0");
+                                    }
+                                }else {
+                                    logger.error("获取推送列表失败");
+                                    json.setSuccess(false);
+                                    json.setErrorCode(ErrorCode.code_2004);
+                                    json.setMsg("获取推送列表失败,当前申请不存在");
+                                }
+                            }catch (Exception e){
+                                map = new HashMap();
+                            }
+                        }
+                        map.put("url",url );
+                        if (map!=null) {
+                            map.put("state", state);
+                            map.put("img", img);
+                            map.put("procDefKey", procDefKey);
+                            mapList.add(map);
+                        }
+                    }
+                    json.put("data", mapList);
+                }else {
+                    json.put("data", new ArrayList<>());
+                }
+                json.setErrorCode(ErrorCode.code_1004);
+            }
+        }catch (Exception e){
+            json.setSuccess(false);
+            json.setErrorCode(ErrorCode.code_2004);
+            json.setMsg("获取推送列表失败");
+        }
+		return json;
+	}
+
+    @ResponseBody
+    @RequestMapping(value = "pushCompanyInfoList", method = RequestMethod.GET)
+    public AjaxJson pushCompanyInfoList(String mobile,HttpServletRequest request, HttpServletResponse response) {
+        AjaxJson json = new AjaxJson();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        try {
+            if (mobile==null || mobile.equals("")){
+                json.setSuccess(false);
+                json.setErrorCode(ErrorCode.code_2003);
+                json.setMsg("获取失败:参数mobile不能为空");
+                return json;
+            }
+            User user = UserUtils.getUser();
+            List<Office> officeList = UserUtils.getAllCompany(user);
+            List<Map> mapList = new ArrayList<>();
+            if (officeList!=null && officeList.size()!=0){
+                for (Office office :officeList) {
+                    Pushinfo pushinfo = new Pushinfo();
+                    String companyId = office.getId();
+                    if (!companyId.equals("1")) {
+                        pushinfo.setCompanyId(companyId);
+                        pushinfo.setDelFlag("0");
+                        pushinfo.setPushUserId(user.getId());
+                        pushinfo.setParentType("single");
+                        pushinfo.setMobile(mobile);
+                        List<Pushinfo> list = pushinfoService.findList(pushinfo);
+                        if (list != null && list.size() != 0) {
+                            Pushinfo p = list.get(0);
+                            Map map = new HashMap();
+                            String type = p.getType();
+                            String createDate = sdf.format(p.getCreateDate()).substring(5, 10);
+                            map.put("type", p.getType() == null ? "" : p.getType());
+                            map.put("title", p.getTitle() == null ? "" : p.getTitle());
+                            map.put("content", p.getContent() == null ? "" : p.getContent());
+                            map.put("contents", p.getRemarks() == null ? "" : p.getRemarks());
+                            map.put("remarks", p.getStatus() == null ? "" : p.getStatus());
+                            map.put("id", p.getPushId() == null ? "" : p.getPushId());
+                            map.put("createDate", createDate == null ? "" : createDate);
+                            map.put("parentType", p.getParentType() == null ? "" : p.getParentType());
+                            map.put("companyId", p.getCompanyId());
+                            String state = "";
+                            String procDefKey = "";
+                            String img = "";
+                            if (type.equals("2001") && p.getRemarks() != null) {
+                                if (p.getRemarks().contains("&gt;")) {
+                                    state = "1";
+                                } else {
+                                    state = "2";
+                                }
+                                img = p.getAddcontent() == null || p.getAddcontent().equals("") ? "" : p.getAddcontent();
+                            } else if (type.contains("400") && p.getAddcontent() != null) {
+                                procDefKey = p.getAddcontent();
+                            }
+                            map.put("state", state);
+                            map.put("img", img);
+                            map.put("procDefKey", procDefKey);
+                            map.put("officeName", office.getName());
+                            map.put("officeLoge", office.getLogo() == null || office.getLogo().equals("") ? "" : office.getLogo());
+                            mapList.add(map);
+                        }
+                    }
+                }
+            }
+            json.put("data", mapList);
+            json.setErrorCode(ErrorCode.code_1004);
+        }catch (Exception e){
+            json.setSuccess(false);
+            json.setErrorCode(ErrorCode.code_2004);
+            json.setMsg("获取公司推送列表失败");
+        }
+        return json;
+    }
+
+}

+ 20 - 0
src/main/java/com/jeeplus/modules/act/dao/ActDao.java

@@ -0,0 +1,20 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.act.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.act.entity.Act;
+
+/**
+ * 审批DAO接口
+ * @author jeeplus
+ * @version 2014-05-16
+ */
+@MyBatisDao
+public interface ActDao extends CrudDao<Act> {
+
+	public int updateProcInsIdByBusinessId(Act act);
+	
+}

+ 48 - 0
src/main/java/com/jeeplus/modules/act/rest/GenericResponseWrapper.java

@@ -0,0 +1,48 @@
+package com.jeeplus.modules.act.rest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+public class GenericResponseWrapper extends HttpServletResponseWrapper {
+    private ByteArrayOutputStream output;
+    private int contentLength;
+    private String contentType;
+
+    public GenericResponseWrapper(HttpServletResponse response) {
+        super(response);
+        output = new ByteArrayOutputStream();
+    }
+
+    public byte[] getData() {
+        return output.toByteArray();
+    }
+
+    public ServletOutputStream getOutputStream() {
+        return new FilterServletOutputStream(output);
+    }
+
+    public PrintWriter getWriter() {
+        return new PrintWriter(getOutputStream(), true);
+    }
+
+    public void setContentLength(int length) {
+        this.contentLength = length;
+        super.setContentLength(length);
+    }
+
+    public int getContentLength() {
+        return contentLength;
+    }
+
+    public void setContentType(String type) {
+        this.contentType = type;
+        super.setContentType(type);
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+} 

File diff suppressed because it is too large
+ 1089 - 0
src/main/java/com/jeeplus/modules/act/service/ActTaskService.java


+ 222 - 0
src/main/java/com/jeeplus/modules/act/web/ActProcessController.java

@@ -0,0 +1,222 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.act.web;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.stream.XMLStreamException;
+
+import com.jeeplus.modules.act.service.ActivityXmlService;
+import com.jeeplus.modules.workactivity.entity.Activity;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.act.service.ActProcessService;
+
+/**
+ * 流程定义相关Controller
+ * @author jeeplus
+ * @version 2013-11-03
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/act/process")
+public class ActProcessController extends BaseController {
+
+	@Autowired
+	private ActProcessService actProcessService;
+
+	@Autowired
+	private HistoryService historyService;
+
+	@Autowired
+	private ActivityXmlService activityService;
+	/**
+	 * 流程定义列表
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = {"list", ""})
+	public String processList(String category, HttpServletRequest request, HttpServletResponse response, Model model) {
+		/*
+		 * 保存两个对象,一个是ProcessDefinition(流程定义),一个是Deployment(流程部署)
+		 */
+		Page<Object[]> page = actProcessService.processList(new Page<Object[]>(request, response), category);
+		model.addAttribute("page", page);
+		model.addAttribute("category", category);
+		return "modules/act/actProcessList";
+	}
+
+	/**
+	 * 运行中的实例列表
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "running")
+	public String runningList(String procInsId, String procDefKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<ProcessInstance> page = actProcessService.runningList(new Page<ProcessInstance>(request, response), procInsId, procDefKey);
+		model.addAttribute("page", page);
+		model.addAttribute("procInsId", procInsId);
+		model.addAttribute("procDefKey", procDefKey);
+		return "modules/act/actProcessRunningList";
+	}
+
+	/**
+	 * 已结束的实例
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "historyList")
+	public String historyList(String procInsId, String procDefKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<HistoricProcessInstance> page = actProcessService.historyList(new Page<HistoricProcessInstance>(request, response), procInsId, procDefKey);
+		model.addAttribute("page", page);
+		model.addAttribute("procInsId", procInsId);
+		model.addAttribute("procDefKey", procDefKey);
+		return "modules/act/actProcessHistoryList";
+	}
+
+
+	/**
+	 * 读取资源,通过部署ID
+	 * @param processDefinitionId  流程定义ID
+	 * @param processInstanceId 流程实例ID
+	 * @param resourceType 资源类型(xml|image)
+	 * @param response
+	 * @throws Exception
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "resource/read")
+	public void resourceRead(String procDefId, String proInsId, String resType, HttpServletResponse response) throws Exception {
+		InputStream resourceAsStream = actProcessService.resourceRead(procDefId, proInsId, resType);
+		byte[] b = new byte[1024];
+		int len = -1;
+		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
+			response.getOutputStream().write(b, 0, len);
+		}
+	}
+
+	/**
+	 * 部署流程
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "/deploy", method=RequestMethod.GET)
+	public String deploy(Model model) {
+		return "modules/act/actProcessDeploy";
+	}
+
+	/**
+	 * 部署流程 - 保存
+	 * @param file
+	 * @return
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "/deploy", method=RequestMethod.POST)
+	public String deploy(@Value("#{APP_PROP['activiti.export.diagram.path']}") String exportDir,
+						 String category, MultipartFile file, RedirectAttributes redirectAttributes) {
+
+		String fileName = file.getOriginalFilename();
+
+		if (StringUtils.isBlank(fileName)){
+			redirectAttributes.addFlashAttribute("message", "请选择要部署的流程文件");
+		}else{
+			String message = actProcessService.deploy(exportDir, category, file);
+			redirectAttributes.addFlashAttribute("message", message);
+		}
+
+		return "redirect:" + adminPath + "/act/process";
+	}
+
+	/**
+	 * 设置流程分类
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "updateCategory")
+	public String updateCategory(String procDefId, String category, RedirectAttributes redirectAttributes) {
+		actProcessService.updateCategory(procDefId, category);
+		return "redirect:" + adminPath + "/act/process";
+	}
+
+	/**
+	 * 挂起、激活流程实例
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "update/{state}")
+	public String updateState(@PathVariable("state") String state, String procDefId, RedirectAttributes redirectAttributes) {
+		String message = actProcessService.updateState(state, procDefId);
+		redirectAttributes.addFlashAttribute("message", message);
+		return "redirect:" + adminPath + "/act/process";
+	}
+
+	/**
+	 * 将部署的流程转换为模型
+	 * @param procDefId
+	 * @param redirectAttributes
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 * @throws XMLStreamException
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "convert/toModel")
+	public String convertToModel(String procDefId, RedirectAttributes redirectAttributes) throws UnsupportedEncodingException, XMLStreamException {
+		org.activiti.engine.repository.Model modelData = actProcessService.convertToModel(procDefId);
+		redirectAttributes.addFlashAttribute("message", "转换模型成功,模型ID="+modelData.getId());
+		return "redirect:" + adminPath + "/act/model";
+	}
+
+	/**
+	 * 导出图片文件到硬盘
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "export/diagrams")
+	@ResponseBody
+	public List<String> exportDiagrams(@Value("#{APP_PROP['activiti.export.diagram.path']}") String exportDir) throws IOException {
+		List<String> files = actProcessService.exportDiagrams(exportDir);
+		return files;
+	}
+
+	/**
+	 * 删除部署的流程,级联删除流程实例
+	 * @param deploymentId 流程部署ID
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "delete")
+	public String delete(String deploymentId) {
+		actProcessService.deleteDeployment(deploymentId);
+		return "redirect:" + adminPath + "/act/process";
+	}
+
+	/**
+	 * 删除流程实例
+	 * @param procInsId 流程实例ID
+	 * @param reason 删除原因
+	 */
+	@RequiresPermissions("act:process:edit")
+	@RequestMapping(value = "deleteProcIns")
+	public String deleteProcIns(String procInsId, String reason, RedirectAttributes redirectAttributes) {
+		if (StringUtils.isBlank(reason)){
+			addMessage(redirectAttributes, "请填写作废原因");
+		}else{
+			actProcessService.deleteProcIns(procInsId, reason);
+			addMessage(redirectAttributes, "作废成功,流程实例ID=" + procInsId);
+		}
+		return "redirect:" + adminPath + "/act/process/running/";
+	}
+
+}

+ 54 - 0
src/main/java/com/jeeplus/modules/casecategory/service/CaseCategoryService.java

@@ -0,0 +1,54 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.casecategory.service;
+
+import java.util.List;
+
+import com.jeeplus.common.service.TreeService;
+import com.jeeplus.common.utils.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.modules.casecategory.entity.CaseCategory;
+import com.jeeplus.modules.casecategory.dao.CaseCategoryDao;
+
+/**
+ * 案例分类Service
+ * @author liuw
+ * @version 2018-01-24
+ */
+@Service
+@Transactional(readOnly = true)
+public class CaseCategoryService extends TreeService<CaseCategoryDao, CaseCategory> {
+
+	public CaseCategory get(String id) {
+		return super.get(id);
+	}
+	
+	public List<CaseCategory> findList(CaseCategory caseCategory) {
+		if (StringUtils.isNotBlank(caseCategory.getParentIds())){
+			caseCategory.setParentIds(","+caseCategory.getParentIds()+",");
+		}
+		return super.findList(caseCategory);
+	}
+	
+	public Page<CaseCategory> findPage(Page<CaseCategory> page, CaseCategory caseCategory) {
+		return super.findPage(page, caseCategory);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(CaseCategory caseCategory) {
+		super.save(caseCategory);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(CaseCategory caseCategory) {
+		super.delete(caseCategory);
+	}
+	
+	
+	
+	
+}

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

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.caseexecuteinfo.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.caseexecuteinfo.entity.CaseExecuteInfo;
+import com.jeeplus.modules.caseexecuteinfo.dao.CaseExecuteInfoDao;
+
+/**
+ * 案例-施工单位Service
+ * @author fgy
+ * @version 2018-01-24
+ */
+@Service
+@Transactional(readOnly = true)
+public class CaseExecuteInfoService extends CrudService<CaseExecuteInfoDao, CaseExecuteInfo> {
+
+	public CaseExecuteInfo get(String id) {
+		return super.get(id);
+	}
+	
+	public List<CaseExecuteInfo> findList(CaseExecuteInfo caseExecuteInfo) {
+		return super.findList(caseExecuteInfo);
+	}
+	
+	public Page<CaseExecuteInfo> findPage(Page<CaseExecuteInfo> page, CaseExecuteInfo caseExecuteInfo) {
+		return super.findPage(page, caseExecuteInfo);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(CaseExecuteInfo caseExecuteInfo) {
+		super.save(caseExecuteInfo);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(CaseExecuteInfo caseExecuteInfo) {
+		super.delete(caseExecuteInfo);
+	}
+	
+	
+	
+	
+}

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

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.casenorm.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.casenorm.entity.CaseNorm;
+import com.jeeplus.modules.casenorm.dao.CaseNormDao;
+
+/**
+ * 案例-造价及材料指标Service
+ * @author fgy
+ * @version 2018-01-24
+ */
+@Service
+@Transactional(readOnly = true)
+public class CaseNormService extends CrudService<CaseNormDao, CaseNorm> {
+
+	public CaseNorm get(String id) {
+		return super.get(id);
+	}
+	
+	public List<CaseNorm> findList(CaseNorm caseNorm) {
+		return super.findList(caseNorm);
+	}
+	
+	public Page<CaseNorm> findPage(Page<CaseNorm> page, CaseNorm caseNorm) {
+		return super.findPage(page, caseNorm);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(CaseNorm caseNorm) {
+		super.save(caseNorm);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(CaseNorm caseNorm) {
+		super.delete(caseNorm);
+	}
+	
+	
+	
+	
+}

+ 97 - 0
src/main/java/com/jeeplus/modules/casepeoplenorm/entity/CasePeopleNorm.java

@@ -0,0 +1,97 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.casepeoplenorm.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 人工消耗量指标Entity
+ * @author liuw
+ * @version 2018-02-07
+ */
+public class CasePeopleNorm extends DataEntity<CasePeopleNorm> {
+	
+	private static final long serialVersionUID = 1L;
+	private String name;		// 名称
+	private String type;		// 型号
+	private String unitContent;		// 单位消耗量
+	private String unit;		// 单位
+	private String allPrice;		// 合价
+	private String proportion;		// 比重
+	private String caseId;		// 案例id
+	
+	public CasePeopleNorm() {
+		super();
+	}
+
+	public CasePeopleNorm(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="型号", align=2, sort=8)
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	@ExcelField(title="单位消耗量", align=2, sort=9)
+	public String getUnitContent() {
+		return unitContent;
+	}
+
+	public void setUnitContent(String unitContent) {
+		this.unitContent = unitContent;
+	}
+	
+	@ExcelField(title="单位", align=2, sort=10)
+	public String getUnit() {
+		return unit;
+	}
+
+	public void setUnit(String unit) {
+		this.unit = unit;
+	}
+	
+	@ExcelField(title="合价", align=2, sort=11)
+	public String getAllPrice() {
+		return allPrice;
+	}
+
+	public void setAllPrice(String allPrice) {
+		this.allPrice = allPrice;
+	}
+	
+	@ExcelField(title="比重", align=2, sort=12)
+	public String getProportion() {
+		return proportion;
+	}
+
+	public void setProportion(String proportion) {
+		this.proportion = proportion;
+	}
+	
+	@ExcelField(title="案例id", align=2, sort=13)
+	public String getCaseId() {
+		return caseId;
+	}
+
+	public void setCaseId(String caseId) {
+		this.caseId = caseId;
+	}
+	
+}

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

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.casepeoplenorm.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.casepeoplenorm.entity.CasePeopleNorm;
+import com.jeeplus.modules.casepeoplenorm.dao.CasePeopleNormDao;
+
+/**
+ * 人工消耗量指标Service
+ * @author liuw
+ * @version 2018-02-07
+ */
+@Service
+@Transactional(readOnly = true)
+public class CasePeopleNormService extends CrudService<CasePeopleNormDao, CasePeopleNorm> {
+
+	public CasePeopleNorm get(String id) {
+		return super.get(id);
+	}
+	
+	public List<CasePeopleNorm> findList(CasePeopleNorm casePeopleNorm) {
+		return super.findList(casePeopleNorm);
+	}
+	
+	public Page<CasePeopleNorm> findPage(Page<CasePeopleNorm> page, CasePeopleNorm casePeopleNorm) {
+		return super.findPage(page, casePeopleNorm);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(CasePeopleNorm casePeopleNorm) {
+		super.save(casePeopleNorm);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(CasePeopleNorm casePeopleNorm) {
+		super.delete(casePeopleNorm);
+	}
+	
+	
+	
+	
+}

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

@@ -0,0 +1,196 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.contractclient.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.contractclient.entity.WorkContractClient;
+import com.jeeplus.modules.contractclient.service.WorkContractClientService;
+
+/**
+ * 合同涉及客户列表Controller
+ * @author lw
+ * @version 2018-06-05
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/contractclient/workContractClient")
+public class WorkContractClientController extends BaseController {
+
+	@Autowired
+	private WorkContractClientService workContractClientService;
+	
+	@ModelAttribute
+	public WorkContractClient get(@RequestParam(required=false) String id) {
+		WorkContractClient entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = workContractClientService.get(id);
+		}
+		if (entity == null){
+			entity = new WorkContractClient();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 合同涉及客户列表列表页面
+	 */
+	@RequiresPermissions("contractclient:workContractClient:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(WorkContractClient workContractClient, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<WorkContractClient> page = workContractClientService.findPage(new Page<WorkContractClient>(request, response), workContractClient); 
+		model.addAttribute("page", page);
+		return "modules/contractclient/workContractClientList";
+	}
+
+	/**
+	 * 查看,增加,编辑合同涉及客户列表表单页面
+	 */
+	@RequiresPermissions(value={"contractclient:workContractClient:view","contractclient:workContractClient:add","contractclient:workContractClient:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(WorkContractClient workContractClient, Model model) {
+		model.addAttribute("workContractClient", workContractClient);
+		return "modules/contractclient/workContractClientForm";
+	}
+
+	/**
+	 * 保存合同涉及客户列表
+	 */
+	@RequiresPermissions(value={"contractclient:workContractClient:add","contractclient:workContractClient:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(WorkContractClient workContractClient, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, workContractClient)){
+			return form(workContractClient, model);
+		}
+		if(!workContractClient.getIsNewRecord()){//编辑表单保存
+			WorkContractClient t = workContractClientService.get(workContractClient.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(workContractClient, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			workContractClientService.save(t);//保存
+		}else{//新增表单保存
+			workContractClientService.save(workContractClient);//保存
+		}
+		addMessage(redirectAttributes, "保存合同涉及客户列表成功");
+		return "redirect:"+Global.getAdminPath()+"/contractclient/workContractClient/?repage";
+	}
+	
+	/**
+	 * 删除合同涉及客户列表
+	 */
+	@RequiresPermissions("contractclient:workContractClient:del")
+	@RequestMapping(value = "delete")
+	public String delete(WorkContractClient workContractClient, RedirectAttributes redirectAttributes) {
+		workContractClientService.delete(workContractClient);
+		addMessage(redirectAttributes, "删除合同涉及客户列表成功");
+		return "redirect:"+Global.getAdminPath()+"/contractclient/workContractClient/?repage";
+	}
+	
+	/**
+	 * 批量删除合同涉及客户列表
+	 */
+	@RequiresPermissions("contractclient:workContractClient:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			workContractClientService.delete(workContractClientService.get(id));
+		}
+		addMessage(redirectAttributes, "删除合同涉及客户列表成功");
+		return "redirect:"+Global.getAdminPath()+"/contractclient/workContractClient/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("contractclient:workContractClient:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(WorkContractClient workContractClient, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "合同涉及客户列表"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<WorkContractClient> page = workContractClientService.findPage(new Page<WorkContractClient>(request, response, -1), workContractClient);
+    		new ExportExcel("合同涉及客户列表", WorkContractClient.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出合同涉及客户列表记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/contractclient/workContractClient/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("contractclient:workContractClient: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<WorkContractClient> list = ei.getDataList(WorkContractClient.class);
+			for (WorkContractClient workContractClient : list){
+				try{
+					workContractClientService.save(workContractClient);
+					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()+"/contractclient/workContractClient/?repage";
+    }
+	
+	/**
+	 * 下载导入合同涉及客户列表数据模板
+	 */
+	@RequiresPermissions("contractclient:workContractClient:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "合同涉及客户列表数据导入模板.xlsx";
+    		List<WorkContractClient> list = Lists.newArrayList(); 
+    		new ExportExcel("合同涉及客户列表数据", WorkContractClient.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/contractclient/workContractClient/?repage";
+    }
+	
+	
+	
+
+}

+ 60 - 0
src/main/java/com/jeeplus/modules/esignature/kinggridserver/KingGridServer.java

@@ -0,0 +1,60 @@
+package com.jeeplus.modules.esignature.kinggridserver;
+
+import com.jeeplus.modules.esignature.utils.HttpRequest;
+import com.jeeplus.modules.esignature.utils.MD5;
+
+public class KingGridServer {
+	/**
+	 * 信签服务器地址
+	 */
+	//public static final String SERVER_URL = "http://192.168.0.55:8081/tosignserver";
+	public static final String SERVER_URL = "http://171.34.78.70:8081/tosignserver";
+	/**
+	 * 信签服务器对接应用ID
+	 */
+	public static final String APP_ID = "king";
+	/**
+	 * 信签服务器对接应用密钥
+	 */
+	public static final String APP_SECURITY = "e3f55030d473095d";
+	
+	/**
+	 * 测试签署用户编码
+	 */
+	//public static final String SIGNER_CODE= "lidongzhang";
+	public static final String SIGNER_CODE= "fgy201804101542";
+
+	/**
+	 * 模板创建合同使用的模板编码
+	 */
+	public static final String CONTRACT_TPL_CODE= "testTemplate";
+
+	/**
+	 * 生成信签请求操作对象
+	 * @param url
+	 * @return
+	 */
+	public static HttpRequest createHttpRequest(String url){
+		String requestUrl;
+		if(SERVER_URL.endsWith("/")){
+			requestUrl =  SERVER_URL.substring(0, SERVER_URL.length()-1)+url;
+		}else{
+			requestUrl = SERVER_URL+url;
+		}
+		HttpRequest httpRequest = new HttpRequest(requestUrl);
+		
+		/**
+		 * 如果是云服务,需要添加应用id到header
+		 * 如果是私有云,可以不用设置
+		 */
+		httpRequest.addHeader("app_id", APP_ID);
+		String  time = System.currentTimeMillis()+"";
+		httpRequest.addHeader("time", time);
+		httpRequest.addHeader("sign", MD5.toMD5(APP_ID+"."+time+'.'+APP_SECURITY));
+		
+		return httpRequest;
+		
+	}
+	
+	
+}

+ 171 - 0
src/main/java/com/jeeplus/modules/esignature/web/EsignatureController.java

@@ -0,0 +1,171 @@
+package com.jeeplus.modules.esignature.web;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeeplus.common.utils.FileUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.esignature.kinggridserver.KingGridServer;
+import com.jeeplus.modules.esignature.service.signer.SignerService;
+import com.jeeplus.modules.esignature.utils.HttpRequest;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+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 java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+
+/**
+ * 电子签章Controller
+ * @author fgy
+ * @version 2018-04-10
+ */
+@SuppressWarnings("all")
+@Controller
+@RequestMapping(value = "${adminPath}/esignature/esignature")
+public class EsignatureController extends BaseController{
+
+    @RequiresPermissions("esignature:esignature:demoView")
+    @RequestMapping("demoView")
+    public String demoView(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes){
+
+        return "modules/workcontractinfo/demoView";
+    }
+
+    /**
+     * 创建个人用户
+     * @return
+     */
+    @RequestMapping("createSigner")
+    @ResponseBody
+    public String createSigner(HttpServletRequest request, Model model){
+        String result = "";
+        JSONObject jsonObject = new JSONObject();
+        String signer_code = request.getParameter("signer_code");
+        String signer_name = request.getParameter("signer_name");
+        String signer_idcode = request.getParameter("singer_idcode");
+        try {
+            jsonObject = SignerService.createSigner(signer_code, signer_name, signer_idcode);
+            result = jsonObject.toJSONString();
+        }catch (IOException e){
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    /**
+     * 创建企业用户
+     */
+    @RequestMapping("createCompanySigner")
+    public JSONObject createCompanySigner(HttpServletRequest request, Model model){
+        JSONObject jsonObject = new JSONObject();
+
+        return jsonObject;
+    }
+
+    /**
+     * 签章
+     */
+    @RequestMapping("sign")
+    @ResponseBody
+    public String sign(HttpServletRequest req, Model model, MultipartFile doc_file){
+        String result = "";
+        String contractId = req.getParameter("contractId");
+        String contractName = req.getParameter("contractName");
+        String bizId = req.getParameter("bizId");
+        String signerCode = req.getParameter("signerCode");
+        if(doc_file!=null && !doc_file.isEmpty() &&doc_file.getSize()>0){
+            HttpRequest request = KingGridServer.createHttpRequest("/api/cnt/sign");
+            InputStream is = null;
+            String realPath = req.getSession().getServletContext().getRealPath("esignature_upload/"+System.currentTimeMillis());
+            try{
+                new File(realPath).mkdirs();
+                String fullName = realPath + "/" +doc_file.getOriginalFilename();
+                File f = new File(fullName);
+                FileUtils.copyInputStreamToFile(doc_file.getInputStream(),f);
+
+                is = new FileInputStream(new File(fullName));
+                request.addInputStream("docx_file", fullName, is);
+                request.addParam("contract_name", contractName);
+                request.addParam("contract_id", contractId);
+                request.addParam("biz_id", StringUtils.isBlank(bizId)?UUID.randomUUID().toString().replaceAll("-", ""):bizId);
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                //设置业务时间参数
+                request.addParam("biz_time", sdf.format(new Date()));
+                //设置签署人的编码
+                request.addParam("signer_info", "[{code:\""+signerCode+"\",seal_code:\"\" , fontsize:50,offsetX:200,y:400,x:200}]" );
+
+
+                request.send();
+
+                result = request.resultToString();
+                System.out.println(result);
+            }catch (IOException e){
+                e.printStackTrace();
+            }
+            finally{
+                if(is!=null){
+                    try {
+                        is.close();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+                boolean b = FileUtils.deleteDirectory(realPath);
+            }
+        }
+
+        return result;
+    }
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 27 - 0
src/main/java/com/jeeplus/modules/exampleexpend/dao/ExampleExpendDao.java

@@ -0,0 +1,27 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.exampleexpend.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.exampleeconomics.entity.ExampleEconomics;
+import com.jeeplus.modules.exampleexpend.entity.ExampleExpend;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 主要工料价格及消耗量指标DAO接口
+ * @author ssrh
+ * @version 2018-08-29
+ */
+@MyBatisDao
+public interface ExampleExpendDao extends CrudDao<ExampleExpend> {
+    int deleteByEId(String eId);
+
+    List<ExampleExpend> getCount(@Param("companyId")String companyId, @Param("areaId")String areaId, @Param("dictId")String dictId,@Param("indexId")String indexId);
+
+    int delteByIndexId(@Param("eId")String eId,@Param("indexId")String indexId);
+    ExampleExpend findExpend(ExampleExpend exampleExpend);
+}

+ 26 - 0
src/main/java/com/jeeplus/modules/exampleproject/dao/ExampleProjectDao.java

@@ -0,0 +1,26 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.exampleproject.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.exampleexpend.entity.ExampleExpend;
+import com.jeeplus.modules.exampleproject.entity.ExampleProject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 主要工程量指标DAO接口
+ * @author ssrh
+ * @version 2018-08-29
+ */
+@MyBatisDao
+public interface ExampleProjectDao extends CrudDao<ExampleProject> {
+
+    int deleteByEId(String eId);
+    List<ExampleProject> getCount(@Param("companyId")String companyId, @Param("areaId")String areaId, @Param("dictId")String dictId,@Param("indexId") String indexId);
+    int delteByIndexId(@Param("eId")String eId,@Param("indexId")String indexId);
+    ExampleProject findProject(ExampleProject exampleProject);
+}

+ 268 - 0
src/main/java/com/jeeplus/modules/hr/service/UserInfoService.java

@@ -0,0 +1,268 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.hr.service;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.oss.OSSClientUtil;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.hr.dao.UserInfoDao;
+import com.jeeplus.modules.hr.entity.UserInfo;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Certificate;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.service.CertificateService;
+import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.service.UserService;
+import com.jeeplus.modules.sys.service.WorkattachmentService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.sysuseroffice.dao.UserofficeDao;
+import com.jeeplus.modules.sysuseroffice.entity.Useroffice;
+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.util.ArrayList;
+import java.util.List;
+
+/**
+ * 人员基本信息Service
+ * @author fgy
+ * @version 2017-12-06
+ */
+@SuppressWarnings("all")
+@Service
+@Transactional(readOnly = true)
+public class UserInfoService extends CrudService<UserInfoDao, UserInfo> {
+
+	@Autowired
+	private UserInfoDao userInfoDao;
+	@Autowired
+	private UserofficeDao userofficeDao;
+	@Autowired
+	private UserDao userDao;
+	@Autowired
+	private UserService userService;
+	@Autowired
+	private OfficeService officeService;
+	@Autowired
+	private WorkattachmentService workattachmentService;
+	@Autowired
+	private CertificateService certificateService;
+
+	public UserInfo get(String id) {
+		UserInfo userInfo = super.get(id);
+		if(userInfo!=null){
+			if(StringUtils.isNotBlank(userInfo.getUserId())){
+				User user = UserUtils.get(userInfo.getUserId());
+				Workattachment jobResume = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userInfo.getUserId(), UserUtils.getSelectCompany().getId(), "62");
+				Workattachment userEvaluation = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userInfo.getUserId(), UserUtils.getSelectCompany().getId(), "0");
+				Workattachment satisfaction = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userInfo.getUserId(), UserUtils.getSelectCompany().getId(), "63");
+				Workattachment certificate = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userInfo.getUserId(),UserUtils.getSelectCompany().getId(),"64");
+				if(jobResume!=null){
+					user.setJobResume(jobResume);
+					if(StringUtils.isNotBlank(jobResume.getAttachmentUser())){
+						jobResume.setAttachmentUser(UserUtils.get(jobResume.getAttachmentUser()).getName());
+					}
+				}
+				if(userEvaluation!=null){
+					user.setWorkattachment(userEvaluation);
+					if(StringUtils.isNotBlank(userEvaluation.getAttachmentUser())){
+						userEvaluation.setAttachmentUser(UserUtils.get(userEvaluation.getAttachmentUser()).getName());
+					}
+				}
+				if(satisfaction!=null){
+					user.setSatisfaction(satisfaction);
+					if(StringUtils.isNotBlank(satisfaction.getAttachmentUser())){
+						satisfaction.setAttachmentUser(UserUtils.get(satisfaction.getAttachmentUser()).getName());
+					}
+				}
+				if(StringUtils.isBlank(userInfo.getGender())){
+					userInfo.setGender(user.getSex());
+				}
+				if(StringUtils.isBlank(userInfo.getName())){
+					userInfo.setName(user.getName());
+				}
+				if(StringUtils.isBlank(userInfo.getMobilePhone())){
+					userInfo.setMobilePhone(user.getMobile());
+				}
+				userInfo.setUser(user);
+			}
+			List<Certificate> certificateList = certificateService.getListByUserInfoId(id);
+			if(certificateList!=null && certificateList.size()>0){
+				for(Certificate c : certificateList){
+					Workattachment w = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(c.getId(),UserUtils.getSelectCompany().getId(),"64");
+					c.setCertificate(w);
+				}
+			}
+			userInfo.setCertificateList(certificateList);
+		}
+
+
+
+		return userInfo;
+	}
+	
+	public List<UserInfo> findList(UserInfo userInfo) {
+		ArrayList<UserInfo> userInfoList = Lists.newArrayList();
+		User user = UserUtils.getUser();
+
+		if(user.isAdmin()){
+
+		}else {
+			userInfo.setCompanyId(UserUtils.getSelectCompany().getId());
+		}
+		ArrayList<UserInfo> list = userInfoDao.findUserInfoList(userInfo);
+
+		if(list != null && list.size()>0){
+			for(int i=0;i<list.size();i++){
+				UserInfo ui = list.get(i);
+				if(ui.getUserOffice()!=null){
+					Useroffice useroffice = ui.getUserOffice();
+					if(StringUtils.isNotBlank(useroffice.getUserId())){
+						User u = UserUtils.get(useroffice.getUserId());
+						String userId = useroffice.getUserId();
+						String companyId = useroffice.getCompanyId();
+						String officeId = useroffice.getOfficeId();
+						if(StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(companyId)){
+							ui = userInfoDao.get(ui.getId());
+							if(ui == null){
+								ui = new UserInfo();
+							}
+						}
+						ui.setUserId(userId);
+						ui.setCompanyId(companyId);
+						ui.setOfficeId(officeId);
+						ui.setCompany(officeService.get(companyId));
+						ui.setOffice(officeService.get(officeId));
+						ui.setUser(u);
+						ui.setUserOffice(useroffice);
+					}
+				}
+				userInfoList.add(ui);
+			}
+		}
+		return userInfoList;
+	}
+
+	public Page<UserInfo> findPage(Page<UserInfo> page, UserInfo userInfo) {
+		userInfo.setPage(page);
+		page.setList(findList(userInfo));
+		return page;
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(UserInfo userInfo) {
+		super.save(userInfo);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(UserInfo userInfo) {
+		super.delete(userInfo);
+	}
+
+	//保存人员简历(62)信息
+	@Transactional(readOnly = false)
+    public void saveJobResume(UserInfo ui, MultipartFile file) {
+		if(file!=null && !file.isEmpty() && file.getSize()>0){
+			String userId = ui.getUserId();
+			String fileName = file.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".")+ 1);
+			Workattachment w = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userId,UserUtils.getSelectCompany().getId(),"62");
+			if(w != null){
+				workattachmentService.deleteFileFromAliyun(w,w==null?"":w.getUrl());
+				workattachmentService.delete(w);
+			}
+			OSSClientUtil ossUtil = new OSSClientUtil();
+			String aliyunPath = ossUtil.uploadFile2OSS(file, "jobResume");
+			Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(aliyunPath);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentId(userId);
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentName(fileName);
+			workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+			workattachment.setAttachmentFlag("62");
+			workattachmentService.save(workattachment);
+
+		}
+    }
+
+	//保存评价表(0)和客户满意表(63)
+	@Transactional(readOnly = false)
+	public void saveEvaluationAndSatisfaction(UserInfo ui, MultipartFile this_upload_files, MultipartFile next_upload_files) {
+		if(this_upload_files!=null && !this_upload_files.isEmpty() && this_upload_files.getSize()>0){
+			String userId = ui.getUserId();
+			String fileName = this_upload_files.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".")+ 1);
+			Workattachment w = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userId,UserUtils.getSelectCompany().getId(),"0");
+			if(w != null){
+				workattachmentService.deleteFileFromAliyun(w,w==null?"":w.getUrl());
+				workattachmentService.delete(w);
+			}
+			OSSClientUtil ossUtil = new OSSClientUtil();
+			String aliyunPath = ossUtil.uploadFile2OSS(this_upload_files, "userEvaluation");
+			Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(aliyunPath);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentId(userId);
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentName(fileName);
+			workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+			workattachment.setAttachmentFlag("0");
+			workattachmentService.save(workattachment);
+		}
+		if(next_upload_files!=null && !next_upload_files.isEmpty() && next_upload_files.getSize()>0){
+			String userId = ui.getUserId();
+			String fileName = next_upload_files.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".")+ 1);
+			Workattachment w = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(userId,UserUtils.getSelectCompany().getId(),"63");
+			if(w != null){
+				workattachmentService.deleteFileFromAliyun(w,w==null?"":w.getUrl());
+				workattachmentService.delete(w);
+			}
+			OSSClientUtil ossUtil = new OSSClientUtil();
+			String aliyunPath = ossUtil.uploadFile2OSS(next_upload_files, "satisfaction");
+			Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(aliyunPath);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentId(userId);
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentName(fileName);
+			workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+			workattachment.setAttachmentFlag("63");
+			workattachmentService.save(workattachment);
+		}
+
+	}
+	//保存人员证书信息
+	@Transactional(readOnly = false)
+	public void saveCertificate(Certificate certificate, MultipartFile this_upload_files) {
+		certificateService.save(certificate);
+		if(this_upload_files!=null && !this_upload_files.isEmpty() && this_upload_files.getSize()>0){
+			String userId = certificate.getUserId();
+			String fileName = this_upload_files.getOriginalFilename();
+			String fileType = fileName.substring(fileName.lastIndexOf(".")+ 1);
+			Workattachment w = workattachmentService.getByAttachmentIdAndCompanyIdAndFlag(certificate.getId(),UserUtils.getSelectCompany().getId(),"64");
+			if(w != null){
+				workattachmentService.deleteFileFromAliyun(w,w==null?"":w.getUrl());
+				workattachmentService.delete(w);
+			}
+			OSSClientUtil ossUtil = new OSSClientUtil();
+			String aliyunPath = ossUtil.uploadFile2OSS(this_upload_files, "certificate");
+			Workattachment workattachment = new Workattachment();
+			workattachment.setUrl(aliyunPath);
+			workattachment.setType(fileType);
+			workattachment.setAttachmentId(certificate.getId());
+			workattachment.setAttachmentUser(UserUtils.getUser().getId());
+			workattachment.setAttachmentName(fileName);
+			workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
+			workattachment.setAttachmentFlag("64");
+			workattachmentService.save(workattachment);
+		}
+	}
+}

+ 60 - 0
src/main/java/com/jeeplus/modules/iim/entity/LayGroup.java

@@ -0,0 +1,60 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.iim.entity;
+
+import org.hibernate.validator.constraints.Length;
+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 lgf
+ * @version 2016-08-07
+ */
+public class LayGroup extends DataEntity<LayGroup> {
+	
+	private static final long serialVersionUID = 1L;
+	private String groupname;		// 群组名
+	private String avatar;		// 群头像
+	private List<LayGroupUser> layGroupUserList = Lists.newArrayList();		// 子表列表
+	
+	public LayGroup() {
+		super();
+	}
+
+	public LayGroup(String id){
+		super(id);
+	}
+
+	@Length(min=0, max=64, message="群组名长度必须介于 0 和 64 之间")
+	@ExcelField(title="群组名", align=2, sort=1)
+	public String getGroupname() {
+		return groupname;
+	}
+
+	public void setGroupname(String groupname) {
+		this.groupname = groupname;
+	}
+	
+	@Length(min=0, max=256, message="群头像长度必须介于 0 和 256 之间")
+	@ExcelField(title="群头像", align=2, sort=2)
+	public String getAvatar() {
+		return avatar;
+	}
+
+	public void setAvatar(String avatar) {
+		this.avatar = avatar;
+	}
+	
+	public List<LayGroupUser> getLayGroupUserList() {
+		return layGroupUserList;
+	}
+
+	public void setLayGroupUserList(List<LayGroupUser> layGroupUserList) {
+		this.layGroupUserList = layGroupUserList;
+	}
+}

+ 56 - 0
src/main/java/com/jeeplus/modules/iim/service/MailBoxService.java

@@ -0,0 +1,56 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.iim.service;
+
+import java.util.List;
+
+import com.jeeplus.common.utils.StringUtils;
+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.iim.dao.MailBoxDao;
+import com.jeeplus.modules.iim.entity.MailBox;
+import com.jeeplus.modules.iim.entity.MailPage;
+
+/**
+ * 收件箱Service
+ * @author jeeplus
+ * @version 2015-11-13
+ */
+@Service
+@Transactional(readOnly = true)
+public class MailBoxService extends CrudService<MailBoxDao, MailBox> {
+
+	@Autowired
+	private MailBoxDao mailBoxDao;
+	public MailBox get(String id) {
+		return super.get(id);
+	}
+	
+	public List<MailBox> findList(MailBox mailBox) {
+		return super.findList(mailBox);
+	}
+	
+	public Page<MailBox> findPage(MailPage<MailBox> page, MailBox mailBox) {
+		return super.findPage(page, mailBox);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(MailBox mailBox) {
+		super.save(mailBox);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(MailBox mailBox) {
+		super.delete(mailBox);
+	}
+	
+	public int getCount(MailBox mailBox) {
+		return mailBoxDao.getCount(mailBox);
+	}
+	
+}

+ 118 - 0
src/main/java/com/jeeplus/modules/leaveapply/entity/LeaveCount.java

@@ -0,0 +1,118 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.leaveapply.entity;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.leavetype.entity.LeaveType;
+
+/**
+ * 请假申请Entity
+ * @author ssrh
+ * @version 2018-09-26
+ */
+public class LeaveCount extends DataEntity<LeaveCount> {
+	
+	private static final long serialVersionUID = 1L;
+	private String staffId;		// 人员档案Id
+	private String leaveTypeId;		// 请假类型Id
+	private String counts;		// 累计次数
+	private String sums;		// 累计天数
+	private Date resetDate;		// 上次重置时间
+	private String resetState;
+	private LeaveType leaveType;
+	private String upDays;
+	private String year;
+
+	public String getUpDays() {
+		return upDays;
+	}
+
+	public void setUpDays(String upDays) {
+		this.upDays = upDays;
+	}
+
+	public String getYear() {
+		return year;
+	}
+
+	public void setYear(String year) {
+		this.year = year;
+	}
+
+	public LeaveType getLeaveType() {
+		return leaveType;
+	}
+
+	public void setLeaveType(LeaveType leaveType) {
+		this.leaveType = leaveType;
+	}
+
+	public String getResetState() {
+
+		return resetState;
+	}
+
+	public void setResetState(String resetState) {
+		this.resetState = resetState;
+	}
+
+	public LeaveCount() {
+		super();
+	}
+
+	public LeaveCount(String id){
+		super(id);
+	}
+
+	@ExcelField(title="人员档案Id", align=2, sort=7)
+	public String getStaffId() {
+		return staffId;
+	}
+
+	public void setStaffId(String staffId) {
+		this.staffId = staffId;
+	}
+	
+	@ExcelField(title="请假类型Id", align=2, sort=8)
+	public String getLeaveTypeId() {
+		return leaveTypeId;
+	}
+
+	public void setLeaveTypeId(String leaveTypeId) {
+		this.leaveTypeId = leaveTypeId;
+	}
+	
+	@ExcelField(title="累计次数", align=2, sort=9)
+	public String getCounts() {
+		return counts;
+	}
+
+	public void setCounts(String counts) {
+		this.counts = counts;
+	}
+	
+	@ExcelField(title="累计天数", align=2, sort=10)
+	public String getSums() {
+		return sums;
+	}
+
+	public void setSums(String sums) {
+		this.sums = sums;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="上次重置时间", align=2, sort=11)
+	public Date getResetDate() {
+		return resetDate;
+	}
+
+	public void setResetDate(Date resetDate) {
+		this.resetDate = resetDate;
+	}
+	
+}

File diff suppressed because it is too large
+ 2946 - 0
src/main/java/com/jeeplus/modules/leaveapply/service/LeaveApplyService.java


+ 57 - 0
src/main/java/com/jeeplus/modules/leaveapply/service/LeaveTaskService.java

@@ -0,0 +1,57 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.leaveapply.service;
+
+import com.jeeplus.modules.workregularapply.service.WorkRegularApplyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ *
+ * @author ssrh
+ * @version 2018-07-17
+ */
+@Service
+@Lazy(false)
+@Transactional(readOnly = true)
+public class LeaveTaskService {
+    @Autowired
+    private LeaveApplyService leaveApplyService;
+    private Logger logger = LoggerFactory.getLogger(LeaveTaskService.class);
+    private static final ExecutorService threadPool = Executors.newFixedThreadPool(10);
+
+    /* @Scheduled(cron= "0 0 2 * * ?")*/
+     /*@Scheduled(cron= "0 0/1 * * * ?")*/
+    public void notifyTask2() {
+        logger.info("-----------凌晨2点发请假管理重置任务开始------------------");
+        threadPool.execute(new Runnable() {
+            @Override
+            public void run() {
+                leaveApplyService.resetTask();
+            }
+        });
+        logger.info("-----------凌晨2点发请假管理重置任务结束------------------");
+    }
+
+  /* @Scheduled(cron= "0 0 3 * * ?")*/
+    /*@Scheduled(cron= "0 0/3 * * * ?")*/
+    public void notifyTask() {
+        logger.info("-----------凌晨3点销假任务开始------------------");
+        threadPool.execute(new Runnable() {
+            @Override
+            public void run() {
+                leaveApplyService.backTask();
+            }
+        });
+        logger.info("-----------凌晨3点销假任务结束------------------");
+    }
+}

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

@@ -0,0 +1,196 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.leaveapply.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.leaveapply.entity.LeaveCount;
+import com.jeeplus.modules.leaveapply.service.LeaveCountService;
+
+/**
+ * 请假申请Controller
+ * @author ssrh
+ * @version 2018-09-26
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/leaveapply/leaveCount")
+public class LeaveCountController extends BaseController {
+
+	@Autowired
+	private LeaveCountService leaveCountService;
+	
+	@ModelAttribute
+	public LeaveCount get(@RequestParam(required=false) String id) {
+		LeaveCount entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = leaveCountService.get(id);
+		}
+		if (entity == null){
+			entity = new LeaveCount();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 请假申请列表页面
+	 */
+	@RequiresPermissions("leaveapply:leaveCount:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(LeaveCount leaveCount, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<LeaveCount> page = leaveCountService.findPage(new Page<LeaveCount>(request, response), leaveCount); 
+		model.addAttribute("page", page);
+		return "modules/leaveapply/leaveCountList";
+	}
+
+	/**
+	 * 查看,增加,编辑请假申请表单页面
+	 */
+	@RequiresPermissions(value={"leaveapply:leaveCount:view","leaveapply:leaveCount:add","leaveapply:leaveCount:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(LeaveCount leaveCount, Model model) {
+		model.addAttribute("leaveCount", leaveCount);
+		return "modules/leaveapply/leaveCountForm";
+	}
+
+	/**
+	 * 保存请假申请
+	 */
+	@RequiresPermissions(value={"leaveapply:leaveCount:add","leaveapply:leaveCount:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(LeaveCount leaveCount, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, leaveCount)){
+			return form(leaveCount, model);
+		}
+		if(!leaveCount.getIsNewRecord()){//编辑表单保存
+			LeaveCount t = leaveCountService.get(leaveCount.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(leaveCount, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			leaveCountService.save(t);//保存
+		}else{//新增表单保存
+			leaveCountService.save(leaveCount);//保存
+		}
+		addMessage(redirectAttributes, "保存请假申请成功");
+		return "redirect:"+Global.getAdminPath()+"/leaveapply/leaveCount/?repage";
+	}
+	
+	/**
+	 * 删除请假申请
+	 */
+	@RequiresPermissions("leaveapply:leaveCount:del")
+	@RequestMapping(value = "delete")
+	public String delete(LeaveCount leaveCount, RedirectAttributes redirectAttributes) {
+		leaveCountService.delete(leaveCount);
+		addMessage(redirectAttributes, "删除请假申请成功");
+		return "redirect:"+Global.getAdminPath()+"/leaveapply/leaveCount/?repage";
+	}
+	
+	/**
+	 * 批量删除请假申请
+	 */
+	@RequiresPermissions("leaveapply:leaveCount:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			leaveCountService.delete(leaveCountService.get(id));
+		}
+		addMessage(redirectAttributes, "删除请假申请成功");
+		return "redirect:"+Global.getAdminPath()+"/leaveapply/leaveCount/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("leaveapply:leaveCount:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(LeaveCount leaveCount, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "请假申请"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<LeaveCount> page = leaveCountService.findPage(new Page<LeaveCount>(request, response, -1), leaveCount);
+    		new ExportExcel("请假申请", LeaveCount.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出请假申请记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/leaveapply/leaveCount/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("leaveapply:leaveCount: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<LeaveCount> list = ei.getDataList(LeaveCount.class);
+			for (LeaveCount leaveCount : list){
+				try{
+					leaveCountService.save(leaveCount);
+					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()+"/leaveapply/leaveCount/?repage";
+    }
+	
+	/**
+	 * 下载导入请假申请数据模板
+	 */
+	@RequiresPermissions("leaveapply:leaveCount:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "请假申请数据导入模板.xlsx";
+    		List<LeaveCount> list = Lists.newArrayList(); 
+    		new ExportExcel("请假申请数据", LeaveCount.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/leaveapply/leaveCount/?repage";
+    }
+	
+	
+	
+
+}

+ 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;
+	}
+}

+ 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();
+				}
+			}
+		}
+	}
+}

+ 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;
+	}
+	
+	
+}

+ 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);
+    };
+}

+ 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";
+	}
+
+}

+ 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;
+	}
+}

+ 187 - 0
src/main/java/com/jeeplus/modules/project/entity/Projectgeneral.java

@@ -0,0 +1,187 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.project.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 项目概况Entity
+ * @author 姚儒彬
+ * @version 2017-10-11
+ */
+public class Projectgeneral extends DataEntity<Projectgeneral> {
+	
+	private static final long serialVersionUID = 1L;
+	private String demandDepartment;		// 需求部门
+	private String projectType;		// 工程类型(0机电、1房建、2市政、3交通、4政府采购、5其他)
+	private String constructionSite;		// 建设地点
+	private String supervisionUnit;		// 监督单位
+	private String serviceClassification;		// 服务分类
+	private String fundAttribute;		// 资金属性
+	private String assetNature;		// 资产性质
+	private String tenderScope;		// 招标范围
+	private String onlineBidding;		// 是否网上招投标(0否,1是)
+	private String evaluationExpert;		// 是否录入评标专家(0否,1是)
+	private String priceCeiling;		// 最高限价(0否,1是)
+	private String bidPriceOrBidControlPrice;		// 标底或招标控制价(0否,1是)
+	private String bidPriceOrBidControlPriceMoney;		// 标底或招标控制价(元)
+	private String bidEvaluationOfficer;		// 评标委员会负责人
+	private String bidEvaluationStaff;		// 与评标活动有关工作人员
+	private String projectId;		// 项目主键
+	
+	public Projectgeneral() {
+		super();
+	}
+
+	public Projectgeneral(String id){
+		super(id);
+	}
+
+	@ExcelField(title="需求部门", align=2, sort=7)
+	public String getDemandDepartment() {
+		return demandDepartment;
+	}
+
+	public void setDemandDepartment(String demandDepartment) {
+		this.demandDepartment = demandDepartment;
+	}
+	
+	@ExcelField(title="工程类型(0机电、1房建、2市政、3交通、4政府采购、5其他)", dictType="", align=2, sort=8)
+	public String getProjectType() {
+		return projectType;
+	}
+
+	public void setProjectType(String projectType) {
+		this.projectType = projectType;
+	}
+	
+	@ExcelField(title="建设地点", align=2, sort=9)
+	public String getConstructionSite() {
+		return constructionSite;
+	}
+
+	public void setConstructionSite(String constructionSite) {
+		this.constructionSite = constructionSite;
+	}
+	
+	@ExcelField(title="监督单位", align=2, sort=10)
+	public String getSupervisionUnit() {
+		return supervisionUnit;
+	}
+
+	public void setSupervisionUnit(String supervisionUnit) {
+		this.supervisionUnit = supervisionUnit;
+	}
+	
+	@ExcelField(title="服务分类", align=2, sort=11)
+	public String getServiceClassification() {
+		return serviceClassification;
+	}
+
+	public void setServiceClassification(String serviceClassification) {
+		this.serviceClassification = serviceClassification;
+	}
+	
+	@ExcelField(title="资金属性", align=2, sort=12)
+	public String getFundAttribute() {
+		return fundAttribute;
+	}
+
+	public void setFundAttribute(String fundAttribute) {
+		this.fundAttribute = fundAttribute;
+	}
+	
+	@ExcelField(title="资产性质", align=2, sort=13)
+	public String getAssetNature() {
+		return assetNature;
+	}
+
+	public void setAssetNature(String assetNature) {
+		this.assetNature = assetNature;
+	}
+	
+	@ExcelField(title="招标范围", align=2, sort=14)
+	public String getTenderScope() {
+		return tenderScope;
+	}
+
+	public void setTenderScope(String tenderScope) {
+		this.tenderScope = tenderScope;
+	}
+	
+	@ExcelField(title="是否网上招投标(0否,1是)", dictType="", align=2, sort=15)
+	public String getOnlineBidding() {
+		return onlineBidding;
+	}
+
+	public void setOnlineBidding(String onlineBidding) {
+		this.onlineBidding = onlineBidding;
+	}
+	
+	@ExcelField(title="是否录入评标专家(0否,1是)", dictType="", align=2, sort=16)
+	public String getEvaluationExpert() {
+		return evaluationExpert;
+	}
+
+	public void setEvaluationExpert(String evaluationExpert) {
+		this.evaluationExpert = evaluationExpert;
+	}
+	
+	@ExcelField(title="最高限价(0否,1是)", dictType="", align=2, sort=17)
+	public String getPriceCeiling() {
+		return priceCeiling;
+	}
+
+	public void setPriceCeiling(String priceCeiling) {
+		this.priceCeiling = priceCeiling;
+	}
+	
+	@ExcelField(title="标底或招标控制价(0否,1是)", dictType="", align=2, sort=18)
+	public String getBidPriceOrBidControlPrice() {
+		return bidPriceOrBidControlPrice;
+	}
+
+	public void setBidPriceOrBidControlPrice(String bidPriceOrBidControlPrice) {
+		this.bidPriceOrBidControlPrice = bidPriceOrBidControlPrice;
+	}
+	
+	@ExcelField(title="标底或招标控制价(元)", align=2, sort=19)
+	public String getBidPriceOrBidControlPriceMoney() {
+		return bidPriceOrBidControlPriceMoney;
+	}
+
+	public void setBidPriceOrBidControlPriceMoney(String bidPriceOrBidControlPriceMoney) {
+		this.bidPriceOrBidControlPriceMoney = bidPriceOrBidControlPriceMoney;
+	}
+	
+	@ExcelField(title="评标委员会负责人", align=2, sort=20)
+	public String getBidEvaluationOfficer() {
+		return bidEvaluationOfficer;
+	}
+
+	public void setBidEvaluationOfficer(String bidEvaluationOfficer) {
+		this.bidEvaluationOfficer = bidEvaluationOfficer;
+	}
+	
+	@ExcelField(title="与评标活动有关工作人员", align=2, sort=21)
+	public String getBidEvaluationStaff() {
+		return bidEvaluationStaff;
+	}
+
+	public void setBidEvaluationStaff(String bidEvaluationStaff) {
+		this.bidEvaluationStaff = bidEvaluationStaff;
+	}
+	
+	@ExcelField(title="项目主键", align=2, sort=22)
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+	
+}

+ 67 - 0
src/main/java/com/jeeplus/modules/project/entity/Workprojectgroup.java

@@ -0,0 +1,67 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.project.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 项目组信息表Entity
+ * @author yangfan
+ * @version 2017-10-11
+ */
+public class Workprojectgroup extends DataEntity<Workprojectgroup> {
+	
+	private static final long serialVersionUID = 1L;
+	private String leader;		// 项目组负责人
+	private String memberIds;		// 项目组成员
+	private String listPreparation;		// 清单编制
+	private String projectId;		// 项目主键
+	
+	public Workprojectgroup() {
+		super();
+	}
+
+	public Workprojectgroup(String id){
+		super(id);
+	}
+
+	@ExcelField(title="项目组负责人", align=2, sort=7)
+	public String getLeader() {
+		return leader;
+	}
+
+	public void setLeader(String leader) {
+		this.leader = leader;
+	}
+	
+	@ExcelField(title="项目组成员", align=2, sort=8)
+	public String getMemberIds() {
+		return memberIds;
+	}
+
+	public void setMemberIds(String memberIds) {
+		this.memberIds = memberIds;
+	}
+	
+	@ExcelField(title="清单编制", align=2, sort=9)
+	public String getListPreparation() {
+		return listPreparation;
+	}
+
+	public void setListPreparation(String listPreparation) {
+		this.listPreparation = listPreparation;
+	}
+	
+	@ExcelField(title="项目主键", align=2, sort=10)
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+	
+}

+ 85 - 0
src/main/java/com/jeeplus/modules/project/service/ProjectService.java

@@ -0,0 +1,85 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.project.service;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.workclientinfo.entity.WorkClientLinkman;
+import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
+import com.jeeplus.modules.project.entity.Projectgeneral;
+import com.jeeplus.modules.project.entity.ProjectEvaluationRecord;
+import com.jeeplus.modules.project.entity.Workprojectgroup;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.project.entity.Project;
+import com.jeeplus.modules.project.dao.ProjectDao;
+
+/**
+ * 项目表Service
+ * @author fgy
+ * @version 2017-10-12
+ */
+@Service
+@Transactional(readOnly = true)
+public class ProjectService extends CrudService<ProjectDao, Project> {
+
+	public Project get(String id) {
+		return super.get(id);
+	}
+	
+	public List<Project> findList(Project project) {
+		return super.findList(project);
+	}
+	
+	public Page<Project> findPage(Page<Project> page, Project project) {
+		return super.findPage(page, project);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(Project project) {
+		super.save(project);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(Project project) {
+		super.delete(project);
+	}
+	
+	public Page<WorkClientLinkman> findPageByentrustCompany(Page<WorkClientLinkman> page, WorkClientLinkman entrustCompany) {
+		entrustCompany.setPage(page);
+		page.setList(dao.findListByentrustCompany(entrustCompany));
+		return page;
+	}
+	public Page<WorkContractInfo> findPageBycontractInfo(Page<WorkContractInfo> page, WorkContractInfo contractInfo) {
+		contractInfo.setPage(page);
+		page.setList(dao.findListBycontractInfo(contractInfo));
+		return page;
+	}
+	public Page<Projectgeneral> findPageByprojectGeneral(Page<Projectgeneral> page, Projectgeneral projectGeneral) {
+		projectGeneral.setPage(page);
+		page.setList(dao.findListByprojectGeneral(projectGeneral));
+		return page;
+	}
+	public Page<WorkClientLinkman> findPageByworkClientLinkman(Page<WorkClientLinkman> page, WorkClientLinkman workClientLinkman) {
+		workClientLinkman.setPage(page);
+		page.setList(dao.findListByworkClientLinkman(workClientLinkman));
+		return page;
+	}
+	public Page<ProjectEvaluationRecord> findPageByprojectEvaluationRecord(Page<ProjectEvaluationRecord> page, ProjectEvaluationRecord projectEvaluationRecord) {
+		projectEvaluationRecord.setPage(page);
+		page.setList(dao.findListByprojectEvaluationRecord(projectEvaluationRecord));
+		return page;
+	}
+	public Page<Workprojectgroup> findPageByworkprojectgroup(Page<Workprojectgroup> page, Workprojectgroup workprojectgroup) {
+		workprojectgroup.setPage(page);
+		page.setList(dao.findListByworkprojectgroup(workprojectgroup));
+		return page;
+	}
+	
+	
+	
+}

+ 22 - 0
src/main/java/com/jeeplus/modules/projectcontentinfo/dao/ProjectReportDataCompanyDao.java

@@ -0,0 +1,22 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.projectcontentinfo.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.projectcontentinfo.entity.ProjectReportData;
+import com.jeeplus.modules.projectcontentinfo.entity.ProjectReportDataCompany;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 报告详情DAO接口
+ * @author yangfan
+ * @version 2018-06-05
+ */
+@MyBatisDao
+public interface ProjectReportDataCompanyDao extends CrudDao<ProjectReportDataCompany> {
+
+}

+ 40 - 0
src/main/java/com/jeeplus/modules/projectcontentinfo/dao/ProjectcontentinfoDao.java

@@ -0,0 +1,40 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.projectcontentinfo.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.projectcontentinfo.entity.Projectcontentinfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 工作内容管理DAO接口
+ * @author yangfan
+ * @version 2018-06-04
+ */
+@MyBatisDao
+public interface ProjectcontentinfoDao extends CrudDao<Projectcontentinfo> {
+
+	Projectcontentinfo findByType(Projectcontentinfo projectcontentinfo);
+	Projectcontentinfo getByInfoId(@Param("infoId")String infoId);
+	Projectcontentinfo findByInfoId(Projectcontentinfo projectcontentinfo);
+	List<Projectcontentinfo> findListByProject(Projectcontentinfo projectcontentinfo);
+	List<Projectcontentinfo> findByParentIds(@Param("projectId")String projectId,@Param("parentId")String parentId);
+	List<Projectcontentinfo> findListByProjectAndType(Projectcontentinfo projectcontentinfo);
+	List<Projectcontentinfo> findListByProjectAndTypes(Projectcontentinfo projectcontentinfo);
+	List<Projectcontentinfo> findListByProjectAndDictType(Projectcontentinfo projectcontentinfo);
+	List<Projectcontentinfo> findListByProjectType(Projectcontentinfo projectcontentinfo);
+	void deleteInfoId(Projectcontentinfo projectcontentinfo);
+
+    Integer queryMaxSort(Projectcontentinfo projectcontentinfo);
+
+    List<Projectcontentinfo> findListByParentSelective(Projectcontentinfo projectcontentinfo);
+
+    void deleteByParentAndLinkId(Projectcontentinfo projectcontentinfo);
+
+    void deleteInfosByParent(String parentIds);
+    void updateByLinkId(@Param("linkId")String linkId,@Param("dataName")String dataName);
+}

+ 80 - 0
src/main/java/com/jeeplus/modules/projectcontentinfo/service/ProjectBasedDataService.java

@@ -0,0 +1,80 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.projectcontentinfo.service;
+
+import java.util.List;
+
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.project.entity.Project;
+import com.jeeplus.modules.projectrecord.entity.ProjectRecords;
+import com.jeeplus.modules.sys.dao.WorkattachmentDao;
+import com.jeeplus.modules.sys.entity.Workattachment;
+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 com.jeeplus.modules.workcontractinfo.service.WorkContractInfoService;
+import com.jeeplus.modules.workreimbursement.utils.VarStr;
+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.projectcontentinfo.entity.ProjectBasedData;
+import com.jeeplus.modules.projectcontentinfo.dao.ProjectBasedDataDao;
+
+/**
+ * 依据性资料Service
+ * @author 杨帆
+ * @version 2018-06-05
+ */
+@Service
+@Transactional(readOnly = true)
+public class ProjectBasedDataService extends CrudService<ProjectBasedDataDao, ProjectBasedData> {
+	@Autowired
+	private WorkattachmentDao workattachmentDao;
+
+	public ProjectBasedData get(String id) {
+		ProjectBasedData projectBasedData = super.get(id);
+		if(projectBasedData!=null) {
+            Workattachment workattachment = new Workattachment();
+            workattachment.setAttachmentId(id);
+            workattachment.setAttachmentFlag("84");
+            projectBasedData.setWorkAttachments(workattachmentDao.findList(workattachment));
+        }
+		return projectBasedData;
+	}
+
+	public String getNumber(ProjectRecords projectRecords) {
+		if (projectRecords!=null && StringUtils.isNotBlank(projectRecords.getId())){
+			ProjectBasedData projectBasedData = new ProjectBasedData();
+			projectBasedData.setProject(projectRecords);
+			ProjectBasedData value = dao.getNumber(projectBasedData);
+			if (value==null || StringUtils.isBlank(value.getNumber())){
+				return "001";
+			}else {
+				return UserUtils.getNumber(value.getNumber());
+			}
+		}else {
+			return "001";
+		}
+
+	}
+
+	public List<ProjectBasedData> findList(ProjectBasedData projectBasedData) {
+		return super.findList(projectBasedData);
+	}
+	
+	public Page<ProjectBasedData> findPage(Page<ProjectBasedData> page, ProjectBasedData projectBasedData) {
+		return super.findPage(page, projectBasedData);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(ProjectBasedData projectBasedData) {
+		super.save(projectBasedData);
+	}
+
+
+}

+ 233 - 0
src/main/java/com/jeeplus/modules/projectcontentinfo/web/ProjectReportDataController.java

@@ -0,0 +1,233 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.projectcontentinfo.web;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.projectcontentinfo.entity.ProjectReportRecord;
+import com.jeeplus.modules.projectcontentinfo.entity.Projectcontentinfo;
+import com.jeeplus.modules.projectcontentinfo.service.ProjectReportChangeService;
+import com.jeeplus.modules.projectcontentinfo.service.ProjectcontentinfoService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workreview.entity.WorkReviewAudit;
+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.projectcontentinfo.entity.ProjectReportData;
+import com.jeeplus.modules.projectcontentinfo.service.ProjectReportDataService;
+
+/**
+ * 报告详情Controller
+ * @author yangfan
+ * @version 2018-06-05
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/projectcontentinfo/projectReportData")
+public class ProjectReportDataController extends BaseController {
+
+	@Autowired
+	private ProjectReportDataService projectReportDataService;
+	@Autowired
+	private ProjectReportChangeService projectReportChangeService;
+	@Autowired
+	private ProjectcontentinfoService projectcontentinfoService;
+
+	@ModelAttribute
+	public ProjectReportData get(@RequestParam(required=false) String id) {
+		ProjectReportData entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = projectReportDataService.get(id);
+		}
+		if (entity == null){
+			entity = new ProjectReportData();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 报告详情列表页面
+	 */
+	@RequiresPermissions("projectcontentinfo:projectReportData:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(ProjectReportData projectReportData, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<ProjectReportData> page = projectReportDataService.findInfoPage(new Page<ProjectReportData>(request, response), projectReportData);
+		model.addAttribute("page", page);
+		return "modules/projectcontentinfo/projectReportDataList";
+	}
+
+	/**
+	 * 查看,增加,编辑报告详情表单页面
+	 */
+	@RequestMapping(value = "form")
+	public String form(ProjectReportData reportData, Model model) {
+		String id = reportData.getId();
+		ProjectReportData projectReportData;
+		Projectcontentinfo projectcontentinfo;
+		String view = "reportAudit";
+		if (StringUtils.isNotBlank(projectReportDataService.getChangeId(id))){
+			id = projectReportDataService.getChangeId(id);
+			projectReportData = projectReportChangeService.get(id);
+			List<Projectcontentinfo> projectcontentinfos = projectcontentinfoService.getByChangeInfoId(projectReportData.getId());
+			projectcontentinfo = projectcontentinfos.get(0);
+			view = "reportChangeAudit";
+		}else {
+			projectReportData = projectReportDataService.get(id);
+			projectcontentinfo = projectcontentinfoService.getByInfoId(projectReportData.getId());
+		}
+		projectcontentinfo.setProjectReportData(projectReportData);
+		model.addAttribute("projectId", projectcontentinfo.getProject().getId());
+		model.addAttribute("id", projectcontentinfo.getId());
+		model.addAttribute("projectcontentinfo", projectcontentinfo);
+		return "modules/projectcontentinfo/"+view;
+	}
+
+	/**
+	 * 保存报告详情
+	 */
+	@RequiresPermissions(value={"projectcontentinfo:projectReportData:add","projectcontentinfo:projectReportData:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(ProjectReportData projectReportData, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, projectReportData)){
+			return form(projectReportData, model);
+		}
+		if(!projectReportData.getIsNewRecord()){//编辑表单保存
+			ProjectReportData t = projectReportDataService.get(projectReportData.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(projectReportData, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			projectReportDataService.save(t);//保存
+		}else{//新增表单保存
+			projectReportDataService.save(projectReportData);//保存
+		}
+		addMessage(redirectAttributes, "保存报告详情成功");
+		return "redirect:"+Global.getAdminPath()+"/projectcontentinfo/projectReportData/?repage";
+	}
+
+	@RequestMapping("selectreportData")
+	public String gridSelectData(ProjectReportData projectReportData, String searchLabel , HttpServletRequest request, HttpServletResponse response, Model model){
+		projectReportData.setFileStatus("1");
+		Page<ProjectReportData> page = projectReportDataService.findInfoPageByStatus(new Page<ProjectReportData>(request, response), projectReportData);
+		model.addAttribute("obj", projectReportData);
+		model.addAttribute("page", page);
+		model.addAttribute("searchLabel",searchLabel);
+		return "modules/sys/gridselectreportrecord";
+	}
+	
+	/**
+	 * 删除报告详情
+	 */
+	@RequiresPermissions("projectcontentinfo:projectReportData:del")
+	@RequestMapping(value = "delete")
+	public String delete(ProjectReportData projectReportData, RedirectAttributes redirectAttributes) {
+		projectReportDataService.delete(projectReportData);
+		addMessage(redirectAttributes, "删除报告详情成功");
+		return "redirect:"+Global.getAdminPath()+"/projectcontentinfo/projectReportData/?repage";
+	}
+	
+	/**
+	 * 批量删除报告详情
+	 */
+	@RequiresPermissions("projectcontentinfo:projectReportData:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			projectReportDataService.delete(projectReportDataService.get(id));
+		}
+		addMessage(redirectAttributes, "删除报告详情成功");
+		return "redirect:"+Global.getAdminPath()+"/projectcontentinfo/projectReportData/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("projectcontentinfo:projectReportData:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(ProjectReportData projectReportData, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "报告明细"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<ProjectReportData> page = projectReportDataService.findInfoPage(new Page<ProjectReportData>(request, response, -1), projectReportData);
+    		new ExportExcel("报告明细", ProjectReportData.class).setDataList(page.getList()).write(response, fileName,request.getHeader("USER-AGENT")).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出报告详情记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/projectcontentinfo/projectReportData/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("projectcontentinfo:projectReportData: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<ProjectReportData> list = ei.getDataList(ProjectReportData.class);
+			for (ProjectReportData projectReportData : list){
+				try{
+					projectReportDataService.save(projectReportData);
+					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()+"/projectcontentinfo/projectReportData/?repage";
+    }
+	
+	/**
+	 * 下载导入报告详情数据模板
+	 */
+	@RequiresPermissions("projectcontentinfo:projectReportData:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "报告详情数据导入模板.xlsx";
+    		List<ProjectReportData> list = Lists.newArrayList(); 
+    		new ExportExcel("报告详情数据", ProjectReportData.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/projectcontentinfo/projectReportData/?repage";
+    }
+	
+	
+	
+
+}

File diff suppressed because it is too large
+ 1382 - 0
src/main/java/com/jeeplus/modules/projectcontentinfo/web/ProjectcontentinfoController.java


+ 273 - 0
src/main/java/com/jeeplus/modules/projectcontroltable/web/ProjectControlTableController.java

@@ -0,0 +1,273 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.projectcontroltable.web;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.projectcontentinfo.entity.ProjectContentData;
+import com.jeeplus.modules.projectcontroltable.entity.ProjectControlTable;
+import com.jeeplus.modules.projectcontroltable.service.ProjectControlTableService;
+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.workcommunicaterecord.entity.WorkCommunicateContent;
+import com.jeeplus.modules.workcommunicaterecord.entity.WorkCommunicateRecord;
+import com.jeeplus.modules.workcommunicaterecord.service.WorkCommunicateContentService;
+import com.jeeplus.modules.workcommunicaterecord.service.WorkCommunicateRecordService;
+import com.jeeplus.modules.workdevicerecord.entity.WorkDeviceRecord;
+import com.jeeplus.modules.workdevicerecord.entity.WorkDeviceXjRecord;
+import com.jeeplus.modules.workdevicerecord.service.WorkDeviceRecordService;
+import com.jeeplus.modules.workdevicerecord.service.WorkDeviceXjRecordService;
+import com.jeeplus.modules.workexplore.entity.WorkExplore;
+import com.jeeplus.modules.workexplore.service.WorkExploreService;
+import com.jeeplus.modules.workhandbill.entity.WorkHandBill;
+import com.jeeplus.modules.workhandbill.entity.WorkHandBillDetail;
+import com.jeeplus.modules.workhandbill.service.WorkHandBillDetailService;
+import com.jeeplus.modules.workhandbill.service.WorkHandBillService;
+import com.jeeplus.modules.workinfolist.entity.WorkInfoList;
+import com.jeeplus.modules.workinfolist.service.WorkInfoListService;
+import com.jeeplus.modules.workprojectcalc.entity.WorkProjectCalcBuild;
+import com.jeeplus.modules.workprojectcalc.entity.WorkProjectCalcDecor;
+import com.jeeplus.modules.workprojectcalc.service.WorkProjectCalcBuildService;
+import com.jeeplus.modules.workprojectcalc.service.WorkProjectCalcDecorService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 过程控制表Controller
+ * @author 马鹏波
+ * @version 2018-06-08
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/projectcontroltable/projectControlTable")
+public class ProjectControlTableController extends BaseController {
+
+	@Autowired
+	private ProjectControlTableService projectControlTableService;
+	@Autowired
+	private WorkattachmentService workattachmentService;
+
+	@ModelAttribute
+	public ProjectControlTable get(@RequestParam(required=false) String id) {
+		ProjectControlTable entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = projectControlTableService.get(id);
+		}
+		if (entity == null){
+			entity = new ProjectControlTable();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 过程控制表列表页面
+	 */
+//	@RequiresPermissions("projectcontroltable:projectControlTable:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(ProjectControlTable projectControlTable, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<ProjectControlTable> page = projectControlTableService.findPage(new Page<ProjectControlTable>(request, response), projectControlTable); 
+		model.addAttribute("page", page);
+		return "modules/projectcontroltable/projectControlTableList";
+	}
+
+	/**
+	 * 查看,增加,编辑过程控制表表单页面
+	 */
+//	@RequiresPermissions(value={"projectcontroltable:projectControlTable:view","projectcontroltable:projectControlTable:add","projectcontroltable:projectControlTable:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(ProjectControlTable projectControlTable, HttpServletRequest request,Model model) {
+		String view = request.getParameter("view");
+		if("view".equals(view)){
+			view = "modules/projectcontroltable/projectControlTableFormView";
+		}else{
+			view = "modules/projectcontroltable/projectControlTableForm";
+		}
+		if(!projectControlTable.getIsNewRecord()){
+            String flag = projectControlTableService.getDetailInfo(projectControlTable);
+			List<Workattachment> listByAttachmentIdAndFlag = workattachmentService.getListByAttachmentIdAndFlag(projectControlTable.getId(), flag);
+			projectControlTable.setWorkAttachments(listByAttachmentIdAndFlag);
+		}
+		model.addAttribute("projectControlTable", projectControlTable);
+		return view;
+	}
+
+	/**
+	 * 保存过程控制表
+	 */
+//	@RequiresPermissions(value={"projectcontroltable:projectControlTable:add","projectcontroltable:projectControlTable:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	@ResponseBody
+	public String save(ProjectControlTable projectControlTable, HttpServletRequest request,Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, projectControlTable)){
+			return form(projectControlTable, request,model);
+		}
+		if(!projectControlTable.getIsNewRecord()){//编辑表单保存
+			ProjectControlTable t = projectControlTableService.get(projectControlTable.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(projectControlTable, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			projectControlTableService.save(t);//保存
+		}else{//新增表单保存
+			String id = UserUtils.getSelectCompany().getId();
+			String userId = UserUtils.getUser().getId(); //当前登陆人
+			String projectId = id + userId + projectControlTable.getPfId();	//项目编号
+			projectControlTable.setPfId(projectId);
+			projectControlTableService.save(projectControlTable);//保存
+		}
+		addMessage(redirectAttributes, "保存过程控制表成功");
+		return projectControlTable.getId();
+	}
+	
+	/**
+	 * 删除过程控制表
+	 */
+//	@RequiresPermissions("projectcontroltable:projectControlTable:del")
+	@RequestMapping(value = "delete")
+	public String delete(ProjectControlTable projectControlTable, RedirectAttributes redirectAttributes) {
+		projectControlTableService.delete(projectControlTable);
+		addMessage(redirectAttributes, "删除过程控制表成功");
+		return "redirect:"+Global.getAdminPath()+"/projectcontroltable/projectControlTable/?repage";
+	}
+	
+	/**
+	 * 批量删除过程控制表
+	 */
+//	@RequiresPermissions("projectcontroltable:projectControlTable:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			projectControlTableService.delete(projectControlTableService.get(id));
+		}
+		addMessage(redirectAttributes, "删除过程控制表成功");
+		return "redirect:"+Global.getAdminPath()+"/projectcontroltable/projectControlTable/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("projectcontroltable:projectControlTable:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(ProjectControlTable projectControlTable, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "过程控制表"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<ProjectControlTable> page = projectControlTableService.findPage(new Page<ProjectControlTable>(request, response, -1), projectControlTable);
+    		new ExportExcel("过程控制表", ProjectControlTable.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出过程控制表记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/projectcontroltable/projectControlTable/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("projectcontroltable:projectControlTable: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<ProjectControlTable> list = ei.getDataList(ProjectControlTable.class);
+			for (ProjectControlTable projectControlTable : list){
+				try{
+					projectControlTableService.save(projectControlTable);
+					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()+"/projectcontroltable/projectControlTable/?repage";
+    }
+	
+	/**
+	 * 下载导入过程控制表数据模板
+	 */
+	@RequiresPermissions("projectcontroltable:projectControlTable:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "过程控制表数据导入模板.xlsx";
+    		List<ProjectControlTable> list = Lists.newArrayList(); 
+    		new ExportExcel("过程控制表数据", ProjectControlTable.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/projectcontroltable/projectControlTable/?repage";
+    }
+
+    @RequestMapping("getControlData")
+    @ResponseBody
+	public Map<Object,Object> getControlData(HttpServletRequest request){
+		Map<Object,Object> map = new HashMap<>();
+		String projectId = request.getParameter("projectId");
+		String projectContentId = request.getParameter("proId");
+		String id = UserUtils.getSelectCompany().getId();
+		String userId = UserUtils.getUser().getId();
+		projectId = id+userId+projectId;
+		List<ProjectControlTable> controlData = projectControlTableService.getControlData(projectId,projectContentId);
+		ProjectContentData projectContentData = new ProjectContentData();
+		projectContentData.setProjectControlTableList(controlData);
+		map.put("list",projectContentData);
+		return map;
+	}
+
+
+	/**
+	 * 删除所有数据
+	 * @param request
+	 * @return
+	 */
+	@RequestMapping("delControlData")
+	@ResponseBody
+	public Map<Object,Object> delControlData(HttpServletRequest request){
+		Map<Object,Object> map = new HashMap<>();
+		String projectId = request.getParameter("projectId");
+		String flag = request.getParameter("flag");
+		String projectContentId = request.getParameter("projectContentId");
+		String id = UserUtils.getSelectCompany().getId();
+		String userId = UserUtils.getUser().getId();
+		projectId = id+userId+projectId;
+		//点击删除 ,不是初始化删除时
+		boolean b = false;
+		if(!"del".equals(flag)){
+			b = projectControlTableService.deleteAllData(projectId,"");
+		}else{
+			b = projectControlTableService.deleteAllData(projectId,projectContentId);
+		}
+		map.put("flag",b);
+		return map;
+	}
+}

+ 537 - 0
src/main/java/com/jeeplus/modules/projectrecord/web/ProjectRecordsAlterController.java

@@ -0,0 +1,537 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.projectrecord.web;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.act.utils.ActUtils;
+import com.jeeplus.modules.projectrecord.entity.ProjectRecords;
+import com.jeeplus.modules.projectrecord.entity.ProjectRecordsAlter;
+import com.jeeplus.modules.projectrecord.enums.AlterStatusEnum;
+import com.jeeplus.modules.projectrecord.enums.ProjectStatusEnum;
+import com.jeeplus.modules.projectrecord.service.ProjectRecordsAlterService;
+import com.jeeplus.modules.projectrecord.service.ProjectRecordsService;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.Role;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.DictUtils;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workactivity.entity.Activity;
+import com.jeeplus.modules.workactivity.service.ActivityService;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
+import com.jeeplus.modules.workcontractinfo.service.WorkContractInfoService;
+import com.jeeplus.modules.workfullmanage.service.WorkFullRecordService;
+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.commons.beanutils.BeanUtils;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+/**
+ * 项目登记Controller
+ * @author ppt
+ * @version 2018-05-02
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/project/projectRecordsAlter")
+public class ProjectRecordsAlterController extends BaseController {
+
+	@Autowired
+	private ProjectRecordsAlterService projectRecordsAlterService;
+	@Autowired
+	private ProjectRecordsService projectRecordsService;
+
+	@Autowired
+	private WorkContractInfoService contractInfoService;
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private WorkFullRecordService workFullRecordService;
+
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private ActivityService activityService;
+	
+	@ModelAttribute
+	public ProjectRecordsAlter get(@RequestParam(required=false) String id) {
+		ProjectRecordsAlter entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = projectRecordsAlterService.get(id);
+		}
+		if (entity == null){
+			entity = new ProjectRecordsAlter();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 项目列表页面
+	 */
+	@RequiresPermissions("project:projectRecords:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(ProjectRecordsAlter projectRecordsAlter, HttpServletRequest request, HttpServletResponse response, Model model) {
+        if(UserUtils.isManager()){
+            model.addAttribute("flag","1");
+        }
+		Page<ProjectRecordsAlter> page = projectRecordsAlterService.findPage(new Page<ProjectRecordsAlter>(request, response), projectRecordsAlter);
+		model.addAttribute("page", page);
+		return "modules/projectrecord/projectRecordsAlterList";
+	}
+
+	/**
+	 * 查看,增加,编辑项目表单页面
+	 */
+	@RequiresPermissions(value={"project:projectRecords:add","project:projectRecords:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(ProjectRecordsAlter projectRecordsAlter, Model model,RedirectAttributes redirectAttributes) {
+        ProjectRecords projectRecords = new ProjectRecords();
+        if (projectRecordsAlter.getAlterBeforeRecords()!=null&&StringUtils.isNotBlank(projectRecordsAlter.getAlterBeforeRecords().getId())){
+            projectRecords = projectRecordsService.get(projectRecordsAlter.getAlterBeforeRecords().getId());
+            //设置详细信息
+            projectRecordsService.queryProjectDetail(projectRecords);
+        }
+		if (projectRecordsAlter!=null&&StringUtils.isNotBlank(projectRecordsAlter.getId())) {
+		    projectRecordsAlter=projectRecordsAlterService.get(projectRecordsAlter.getId());
+            projectRecordsAlter.setAlterBeforeRecords(projectRecords);
+			//设置合同信息
+            projectRecordsAlterService.queryProjectAlterDetail(projectRecordsAlter);
+		}else {
+            //判断项目状态
+            if (projectRecords.getProjectStatus()!=ProjectStatusEnum.SIGNED.getValue()){
+                addMessage(redirectAttributes, "状态异常,不能发起项目变更");
+                return "redirect:"+Global.getAdminPath()+"/project/projectRecords/?repage";
+            }
+            try {
+                BeanUtils.copyProperties(projectRecordsAlter,projectRecords);
+                projectRecordsAlter.setId(null);
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            } catch (InvocationTargetException e) {
+                e.printStackTrace();
+            }
+            projectRecordsAlter.setAlterBeforeRecords(projectRecords);
+            if(projectRecordsAlter.getWorkAttachments()!=null)projectRecordsAlter.setWorkAttachments(new ArrayList<WorkClientAttachment>());
+            projectRecordsAlter.setCreateBy(UserUtils.getUser());
+            projectRecordsAlter.setCreateDate(new Date());
+		}
+		model.addAttribute("projectRecordsAlter", projectRecordsAlter);
+		return "modules/projectrecord/projectRecordsAlterForm";
+	}
+
+    /**
+	 * 编辑项目表单页面
+	 */
+	@RequiresPermissions(value={"project:projectRecords:edit"},logical=Logical.OR)
+	@RequestMapping(value = "modify")
+	public String modify(ProjectRecordsAlter projectRecordsAlter, Model model,RedirectAttributes redirectAttributes) {
+	    if(StringUtils.isBlank(projectRecordsAlter.getId())){
+            projectRecordsAlter = projectRecordsAlterService.getByProcessInstanceId(projectRecordsAlter.getAct().getProcInsId());
+            projectRecordsAlterService.queryProjectAlterDetail(projectRecordsAlter);
+        }
+        ProjectRecords projectRecords = new ProjectRecords();
+        if (projectRecordsAlter.getAlterBeforeRecords()!=null&&StringUtils.isNotBlank(projectRecordsAlter.getAlterBeforeRecords().getId())){
+            projectRecords = projectRecordsService.get(projectRecordsAlter.getAlterBeforeRecords().getId());
+            //设置项目组成员
+            projectRecordsService.queryUserNames(projectRecords);
+            projectRecordsAlter.setAlterBeforeRecords(projectRecords);
+        }
+        projectRecordsAlter=projectRecordsAlterService.get(projectRecordsAlter.getId());
+        ProcessInstance processInstance = actTaskService.getProcIns(projectRecordsAlter.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);
+            projectRecordsAlter.setAct(act);
+        }
+
+        projectRecordsAlter.setAlterBeforeRecords(projectRecords);
+        //设置合同信息
+        projectRecordsAlterService.queryProjectAlterDetail(projectRecordsAlter);
+		model.addAttribute("projectRecordsAlter", projectRecordsAlter);
+		return "modules/projectrecord/projectRecordsAlterModify";
+	}
+
+	/**
+	 * 查看
+	 * @param projectRecordsAlter
+	 * @param model
+	 * @return
+	 */
+	@RequiresPermissions(value={"project:projectRecords:view"})
+	@RequestMapping(value = "view")
+	public String view(ProjectRecordsAlter projectRecordsAlter, Model model) {
+	    ProjectRecords projectRecords = null;
+        if (projectRecordsAlter.getAlterBeforeRecords()!=null&&StringUtils.isNotBlank(projectRecordsAlter.getAlterBeforeRecords().getId())){
+            projectRecords = projectRecordsService.get(projectRecordsAlter.getAlterBeforeRecords().getId());
+            //设置详细信息
+            projectRecordsService.queryProjectDetail(projectRecords);
+            projectRecordsAlter.setAlterBeforeRecords(projectRecords);
+        }
+		if (projectRecords!=null&&StringUtils.isNotBlank(projectRecords.getId())) {
+			//设置合同信息
+            projectRecordsAlterService.queryProjectAlterDetail(projectRecordsAlter);
+		}
+		model.addAttribute("projectRecordsAlter", projectRecordsAlter);
+		return "modules/projectrecord/projectRecordsAlterView";
+	}
+
+	/**
+	 * 保存项目
+	 */
+	@RequiresPermissions(value={"project:projectRecords:add","project:projectRecords:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(ProjectRecordsAlter projectRecords, Model model, RedirectAttributes redirectAttributes){
+		if (!beanValidator(model, projectRecords)){
+			return form(projectRecords, model,redirectAttributes);
+		}
+        try {
+            if(!projectRecords.getIsNewRecord()){//编辑表单保存
+                ProjectRecordsAlter t = projectRecordsAlterService.get(projectRecords.getId());//从数据库取出记录的值
+                MyBeanUtils.copyBeanNotNull2Bean(projectRecords, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+                projectRecordsAlterService.saveProject(t, AlterStatusEnum.IN_APRL);//保存
+            }else{//新增表单保存
+                projectRecordsAlterService.saveProject(projectRecords,AlterStatusEnum.IN_APRL);//保存
+            }
+            addMessage(model,"保存项目变更成功");
+        } catch (Exception e) {
+            logger.error("保存项目变更异常:",e);
+            addMessage(model,"保存项目变更异常:"+e.getMessage());
+        }
+		return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+	}
+
+	/**
+	 * 保存项目
+	 */
+	@RequiresPermissions(value={"project:projectRecords:add","project:projectRecords:edit"},logical=Logical.OR)
+	@RequestMapping(value = "tstore")
+	public String tStore(ProjectRecordsAlter projectRecords, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, projectRecords)){
+			return form(projectRecords, model,redirectAttributes);
+		}
+        try {
+            if(!projectRecords.getIsNewRecord()){//编辑表单保存
+                ProjectRecordsAlter t = projectRecordsAlterService.get(projectRecords.getId());//从数据库取出记录的值
+                MyBeanUtils.copyBeanNotNull2Bean(projectRecords, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+                projectRecordsAlterService.saveProject(t,AlterStatusEnum.TSTORE);//保存
+            }else{//新增表单保存
+                projectRecordsAlterService.saveProject(projectRecords,AlterStatusEnum.TSTORE);//保存
+            }
+            addMessage(model,"暂存项目变更成功");
+        } catch (Exception e) {
+            logger.error("暂存项目变更异常:",e);
+            addMessage(model,"暂存项目变更异常:"+e.getMessage());
+        }
+		return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+	}
+	
+	/**
+	 * 删除项目
+	 */
+	@RequiresPermissions("project:projectRecords:del")
+	@RequestMapping(value = "delete")
+	public String delete(ProjectRecordsAlter projectRecords, RedirectAttributes redirectAttributes) {
+		int status = projectRecords.getProjectStatus();
+		if(status==AlterStatusEnum.TSTORE.getValue()||status==AlterStatusEnum.REJECTED.getValue()||status==AlterStatusEnum.RECALL.getValue()){
+			projectRecordsAlterService.delete(projectRecords);
+			addMessage(redirectAttributes, "删除项目变更记录成功");
+			return "redirect:"+Global.getAdminPath()+"/project/projectRecords/?repage";
+		}else {
+			addMessage(redirectAttributes, "删除项目变更记录失败,只有“暂存”、“驳回”、“撤回”状态的项目才能删除");
+		}
+		return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+	}
+	
+	/**
+	 * 批量删除项目
+	 */
+	@RequiresPermissions("project:projectRecords:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			projectRecordsAlterService.delete(projectRecordsAlterService.get(id));
+		}
+		addMessage(redirectAttributes, "删除项目成功");
+		return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("project:projectRecords:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(ProjectRecordsAlter projectRecords, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "项目"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<ProjectRecordsAlter> page = projectRecordsAlterService.findPage(new Page<ProjectRecordsAlter>(request, response, -1), projectRecords);
+    		new ExportExcel("项目", ProjectRecords.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出项目记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("project:projectRecords: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<ProjectRecordsAlter> list = ei.getDataList(ProjectRecordsAlter.class);
+			for (ProjectRecordsAlter projectRecords : list){
+				try{
+					projectRecordsAlterService.save(projectRecords);
+					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()+"/project/projectRecordsAlter/?repage";
+    }
+	
+	/**
+	 * 下载导入项目数据模板
+	 */
+	@RequiresPermissions("project:projectRecords:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "项目数据导入模板.xlsx";
+    		List<ProjectRecordsAlter> list = Lists.newArrayList();
+    		new ExportExcel("项目数据", ProjectRecordsAlter.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+    }
+	
+	
+	
+	@RequestMapping("getContractInfo")
+	@ResponseBody
+	public WorkContractInfo queryContractInfo(WorkContractInfo  contractInfo){
+		WorkContractInfo workContractInfo = contractInfoService.get(contractInfo.getId());
+		workContractInfo.setConstructionProjectTypeStr(DictUtils.getDictLabel(String.valueOf(workContractInfo.getConstructionProjectType()),"construction_project_type",""));
+		return  workContractInfo;
+	}
+
+	//	审批页面
+	@RequestMapping(value = "projectRecordsAudit")
+	public String projectRecordsAudit(Act act, ProjectRecordsAlter projectRecordsAlter, Model model) {
+		projectRecordsAlter = projectRecordsAlterService.getByProcessInstanceId(act.getProcInsId());
+        ProjectRecords projectRecords = null;
+        if (projectRecordsAlter.getAlterBeforeRecords()!=null&&StringUtils.isNotBlank(projectRecordsAlter.getAlterBeforeRecords().getId())){
+            projectRecords = projectRecordsService.get(projectRecordsAlter.getAlterBeforeRecords().getId());
+            //设置详细信息
+            projectRecordsService.queryProjectDetail(projectRecords);
+            projectRecordsAlter.setAlterBeforeRecords(projectRecords);
+        }
+		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())) {
+			projectRecordsAlter.setAct(act);
+			model.addAttribute("processInstanceId", projectRecordsAlter.getProcessInstanceId());
+		}
+		if (projectRecordsAlter!=null&&StringUtils.isNotBlank(projectRecordsAlter.getId())) {
+            projectRecordsAlterService.queryProjectAlterDetail(projectRecordsAlter);
+
+        }
+		model.addAttribute("projectRecordsAlter", projectRecordsAlter);
+		return "modules/projectrecord/projectRecordsAlterAudit";
+	}
+
+    @RequestMapping(value = "getProcess")
+	public String getProcess(ProjectRecordsAlter projectRecords, Model model,HttpServletRequest request){
+		model.addAttribute("processInstanceId", projectRecords.getProcessInstanceId());
+		return "modules/projectrecord/projectRecordsTask";
+	}
+
+	@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 {
+            ProjectRecordsAlter projectRecordsAlter = projectRecordsAlterService.get(id);
+            if(5==projectRecordsAlter.getProjectStatus()){
+                addMessage(redirectAttributes, "项目变更已审批通过,无法撤回");
+                return "redirect:"+Global.getAdminPath()+"/project/projectRecordsAlter/?repage";
+            }
+            projectRecordsAlterService.cancelProcess(projectRecordsAlter);
+			addMessage(redirectAttributes, "撤回该项目变更成功");
+		}catch (Exception e){
+			logger.info(e.getMessage());
+			addMessage(redirectAttributes, "撤回项目变更失败");
+		}
+		return "redirect:" + Global.getAdminPath() + "/project/projectRecordsAlter/?repage";
+	}
+
+	/**
+	 * 查询待办任务
+	 *
+	 * @param act
+	 * @param model
+	 * @return
+	 */
+	@RequestMapping("/toDoList")
+	public String queryToList(Act act, Model model) {
+
+		//合同申请流程
+		act.setProcDefKey(ActUtils.PD_PROJECTRECORD[0]);
+		List<Act> list = actTaskService.todoList(act);
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<Activity> activities = activityService.groupByActivityMenu("7854872f45b84acd893010e66a3db2c8",companyId);
+		for (Activity activity:activities){
+			act.setProcDefKey(activity.getProcessKey());
+			list.addAll(actTaskService.todoList(act));
+		}
+
+		Role role = UserUtils.getSelectRole().get(0);
+		List<ProjectRecordsAlter> lists = new ArrayList<ProjectRecordsAlter>();
+		for (Act a : list) {
+			if (a.getTask().getTaskDefinitionKey()!=null && !"modifyApply".equals(a.getTask().getTaskDefinitionKey())) {
+				ProjectRecordsAlter projectRecords = projectRecordsAlterService.getByProcessInstanceId(a.getProcInsId());
+				if (projectRecords==null){continue;}
+				projectRecords.setAuditType("项目登记");
+				if(projectRecords.getProjectStatus()!= AlterStatusEnum.RECALL.getValue()) {
+					User user1 = UserUtils.get(projectRecords.getCreateBy().getId());
+					if (projectRecords != null && user1.getCompany().getId().equals(companyId)) {
+						projectRecords.setCreateBy(user1);
+						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());
+							}
+						}
+						projectRecords.setAct(a);
+						lists.add(projectRecords);
+					}
+				}
+			}
+		}
+
+		//排除 重新申请|撤销
+		Iterator<ProjectRecordsAlter> it = lists.iterator();
+		while(it.hasNext()){
+			ProjectRecordsAlter w = it.next();
+			if(w.getAct()!=null && w.getAct().getTaskDefKey().equals("reapply")){
+				it.remove();
+			}
+		}
+
+		model.addAttribute("list", lists);
+		return "modules/projectrecord/projectRecordsToDoList";
+	}
+
+	/**
+	 * 审批
+	 * @param projectRecords
+	 * @param model
+	 * @param upload_files
+	 * @param redirectAttributes
+	 * @return
+	 */
+	@RequestMapping("saveAudit")
+	public String saveAudit(ProjectRecordsAlter projectRecords, Model model,
+							@RequestParam(value = "upload_files", required = false) MultipartFile[] upload_files,
+							RedirectAttributes redirectAttributes) {
+		String home = projectRecords.getHome();
+		try {
+			String taskDefKey = projectRecords.getAct().getTaskDefKey();
+			//当状态为未通过时,重新修改数据
+			if ("modifyApply".equals(taskDefKey)) {
+				projectRecords.getAct().setComment("重新申请");
+			}
+			List<User> users = UserUtils.getByProssType(projectRecords.getProcessInstanceId(),1);
+			String flag = projectRecords.getAct().getFlag();
+			if ("yes".equals(flag) && (users==null || users.size()==0)){
+				addMessage(redirectAttributes, "审批失败,审批人为空,请联系管理员!");
+			}else {
+				String str = projectRecordsAlterService.auditSave(projectRecords,users);
+				addMessage(redirectAttributes, str);
+			}
+		}catch (Exception e){
+			addMessage(redirectAttributes, "审批失败:"+e);
+		}
+
+        if (StringUtils.isNotBlank(home) && "home".equals(home)){
+            return "redirect:" + Global.getAdminPath() + "/home/?repage";
+        }else {
+            return "redirect:" + Global.getAdminPath() + "/project/projectRecordsAlter/?repage";
+        }
+	}
+
+	/**
+	 * 查询已办列表
+	 * @return
+	 */
+	@RequestMapping("/queryCompleteList")
+	public String queryCompleteList(Act act,HttpServletRequest request,HttpServletResponse response,Model model){
+		act.setProcDefKey("projectAudit");
+		List<ProjectRecordsAlter> list = projectRecordsAlterService.historicList(act);
+		Office office = UserUtils.getSelectCompany();
+		String companyId = office==null?"":office.getId();
+		List<Activity> activities = activityService.groupByActivityMenu("ggh3125f1f194c82bdea93555c750906",companyId);
+		for (Activity activity:activities){
+			act.setProcDefKey(activity.getProcessKey());
+			list.addAll(projectRecordsAlterService.historicList(act));
+		}
+		model.addAttribute("list",list);
+		return "modules/projectrecord/projectRecordsHistoricList";
+	}
+}

+ 12 - 0
src/main/java/com/jeeplus/modules/serialnum/exception/SerialGenException.java

@@ -0,0 +1,12 @@
+package com.jeeplus.modules.serialnum.exception;
+
+public class SerialGenException extends RuntimeException{
+
+    public SerialGenException(String message) {
+        super(message);
+    }
+
+    public SerialGenException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

+ 148 - 0
src/main/java/com/jeeplus/modules/sys/entity/Log.java

@@ -0,0 +1,148 @@
+/**
+ * Copyright &copy; 2013-2017 <a href="http://www.rhcncpa.com/">瑞华会计师事务所</a> All rights reserved.
+ */
+package com.jeeplus.modules.sys.entity;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.StringUtils;
+
+/**
+ * 日志Entity
+ * @author jeeplus
+ * @version 2014-8-19
+ */
+public class Log extends DataEntity<Log> {
+
+	private static final long serialVersionUID = 1L;
+	private String type; 		// 日志类型(1:接入日志;2:错误日志)
+	private String title;		// 日志标题
+	private String remoteAddr; 	// 操作用户的IP地址
+	private String requestUri; 	// 操作的URI
+	private String method; 		// 操作的方式
+	private String params; 		// 操作提交的数据
+	private String userAgent;	// 操作用户代理信息
+	private String exception; 	// 异常信息
+	
+	private Date beginDate;		// 开始日期
+	private Date endDate;		// 结束日期
+	
+	// 日志类型(1:接入日志;2:错误日志)
+	public static final String TYPE_ACCESS = "1";
+	public static final String TYPE_EXCEPTION = "2";
+	
+	public Log(){
+		super();
+	}
+	
+	public Log(String id){
+		super(id);
+	}
+	
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public String getRemoteAddr() {
+		return remoteAddr;
+	}
+
+	public void setRemoteAddr(String remoteAddr) {
+		this.remoteAddr = remoteAddr;
+	}
+
+	public String getUserAgent() {
+		return userAgent;
+	}
+
+	public void setUserAgent(String userAgent) {
+		this.userAgent = userAgent;
+	}
+
+	public String getRequestUri() {
+		return requestUri;
+	}
+
+	public void setRequestUri(String requestUri) {
+		this.requestUri = requestUri;
+	}
+
+	public String getMethod() {
+		return method;
+	}
+
+	public void setMethod(String method) {
+		this.method = method;
+	}
+
+	public String getParams() {
+		return params;
+	}
+
+	public void setParams(String params) {
+		this.params = params;
+	}
+	
+	public String getException() {
+		return exception;
+	}
+
+	public void setException(String exception) {
+		this.exception = exception;
+	}
+
+	public Date getBeginDate() {
+		return beginDate;
+	}
+
+	public void setBeginDate(Date beginDate) {
+		this.beginDate = beginDate;
+	}
+
+	public Date getEndDate() {
+		return endDate;
+	}
+
+	public void setEndDate(Date endDate) {
+		this.endDate = endDate;
+	}
+	
+	/**
+	 * 设置请求参数
+	 * @param paramMap
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public void setParams(Map paramMap){
+		if (paramMap == null){
+			return;
+		}
+		StringBuilder params = new StringBuilder();
+		for (Map.Entry<String, String[]> param : ((Map<String, String[]>)paramMap).entrySet()){
+			params.append(("".equals(params.toString()) ? "" : "&") + param.getKey() + "=");
+			String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
+			params.append(StringUtils.abbr(StringUtils.endsWithIgnoreCase(param.getKey(), "password") ? "" : paramValue, 100));
+		}
+		this.params = params.toString();
+	}
+	
+	@Override
+	public String toString() {
+		return ReflectionToStringBuilder.toString(this);
+	}
+}

+ 68 - 0
src/main/java/com/jeeplus/modules/sys/interceptor/LogInterceptor.java

@@ -0,0 +1,68 @@
+/**
+ * Copyright &copy; 2013-2017 <a href="http://www.rhcncpa.com/">瑞华会计师事务所</a> All rights reserved.
+ */
+package com.jeeplus.modules.sys.interceptor;
+
+import java.text.SimpleDateFormat;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.core.NamedThreadLocal;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.jeeplus.common.service.BaseService;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.modules.sys.utils.LogUtils;
+
+/**
+ * 日志拦截器
+ * @author jeeplus
+ * @version 2014-8-19
+ */
+public class LogInterceptor extends BaseService implements HandlerInterceptor {
+
+	private static final ThreadLocal<Long> startTimeThreadLocal =
+			new NamedThreadLocal<Long>("ThreadLocal StartTime");
+	
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
+			Object handler) throws Exception {
+		if (logger.isDebugEnabled()){
+			long beginTime = System.currentTimeMillis();//1、开始时间  
+	        startTimeThreadLocal.set(beginTime);		//线程绑定变量(该数据只有当前请求的线程可见)  
+	        logger.debug("开始计时: {}  URI: {}", new SimpleDateFormat("hh:mm:ss.SSS")
+	        	.format(beginTime), request.getRequestURI());
+		}
+		return true;
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 
+			ModelAndView modelAndView) throws Exception {
+		if (modelAndView != null){
+			logger.info("ViewName: " + modelAndView.getViewName());
+		}
+	}
+
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
+			Object handler, Exception ex) throws Exception {
+
+		// 保存日志
+		LogUtils.saveLog(request, handler, ex, null);
+		
+		// 打印JVM信息。
+		if (logger.isDebugEnabled()){
+			long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)  
+			long endTime = System.currentTimeMillis(); 	//2、结束时间  
+	        logger.debug("计时结束:{}  耗时:{}  URI: {}  最大内存: {}m  已分配内存: {}m  已分配内存中的剩余空间: {}m  最大可用内存: {}m",
+	        		new SimpleDateFormat("hh:mm:ss.SSS").format(endTime), DateUtils.formatDateTime(endTime - beginTime),
+					request.getRequestURI(), Runtime.getRuntime().maxMemory()/1024/1024, Runtime.getRuntime().totalMemory()/1024/1024, Runtime.getRuntime().freeMemory()/1024/1024, 
+					(Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024); 
+		}
+		
+	}
+
+}

+ 305 - 0
src/main/java/com/jeeplus/modules/sys/utils/DictUtils.java

@@ -0,0 +1,305 @@
+/**
+ * Copyright &copy; 2013-2017 <a href="http://www.rhcncpa.com/">瑞华会计师事务所</a> All rights reserved.
+ */
+package com.jeeplus.modules.sys.utils;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.jeeplus.modules.sys.dao.MainDictDetailDao;
+import com.jeeplus.modules.sys.entity.MainDict;
+import com.jeeplus.modules.sys.entity.MainDictDetail;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.service.MainDictService;
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.common.utils.CacheUtils;
+import com.jeeplus.common.utils.SpringContextHolder;
+import com.jeeplus.modules.sys.dao.DictDao;
+import com.jeeplus.modules.sys.entity.Dict;
+
+/**
+ * 字典工具类
+ * @author jeeplus
+ * @version 2013-5-29
+ */
+public class DictUtils {
+	
+	private static DictDao dictDao = SpringContextHolder.getBean(DictDao.class);
+	private static MainDictService mainDictService = SpringContextHolder.getBean(MainDictService.class);
+	private static MainDictDetailDao mainDictDetailDao = SpringContextHolder.getBean(MainDictDetailDao.class);
+
+	public static final String CACHE_DICT_MAP = "dictMap";
+
+	public static String getDictLabel(String value, String type, String defaultValue){
+		if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(value)){
+			for (Dict dict : getDictList(type)){
+				if (type.equals(dict.getType()) && value.equals(dict.getValue())){
+					return dict.getLabel();
+				}
+			}
+		}
+		return defaultValue;
+	}
+
+	/**
+	 * 公司级业务字典
+	 * @param value
+	 * @param type
+	 * @param defaultValue
+	 * @return
+	 */
+	public static String getMainDictLabel(String value, String type, String defaultValue){
+		if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(value)){
+			for (MainDictDetail mainDictDetail : getMainDictListView(type)){
+				if (type.equals(mainDictDetail.getType()) && value.equals(mainDictDetail.getValue())){
+					return mainDictDetail.getLabel();
+				}
+			}
+		}
+		return defaultValue;
+	}
+	public static String getDictLabels(String values, String type, String defaultValue){
+		if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(values)){
+			List<String> valueList = Lists.newArrayList();
+			for (String value : StringUtils.split(values, ",")){
+				valueList.add(getDictLabel(value, type, defaultValue));
+			}
+			return StringUtils.join(valueList, ",");
+		}
+		return defaultValue;
+	}
+
+	public static String getDictValue(String label, String type, String defaultLabel){
+		if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(label)){
+			for (Dict dict : getDictList(type)){
+				if (type.equals(dict.getType()) && label.equals(dict.getLabel())){
+					return dict.getValue();
+				}
+			}
+		}
+		return defaultLabel;
+	}
+
+	public static String getMainDictValue(String label, String type, String defaultLabel){
+		if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(label)){
+			for (MainDictDetail mainDictDetail : getMainDictList(type)){
+				if (type.equals(mainDictDetail.getType()) && label.equals(mainDictDetail.getLabel())){
+					return mainDictDetail.getDetailKey();
+				}
+			}
+		}
+		return defaultLabel;
+	}
+	
+	public static List<Dict> getDictList(String type){
+		@SuppressWarnings("unchecked")
+		Map<String, List<Dict>> dictMap = (Map<String, List<Dict>>)CacheUtils.get(CACHE_DICT_MAP);
+		if (dictMap==null){
+			dictMap = Maps.newHashMap();
+			for (Dict dict : dictDao.findAllList(new Dict())){
+				List<Dict> dictList = dictMap.get(dict.getType());
+				if (dictList != null){
+					dictList.add(dict);
+				}else{
+					dictMap.put(dict.getType(), Lists.newArrayList(dict));
+				}
+			}
+			CacheUtils.put(CACHE_DICT_MAP, dictMap);
+		}
+		List<Dict> dictList = dictMap.get(type);
+		if (dictList == null){
+			dictList = Lists.newArrayList();
+		}
+		return dictList;
+	}
+
+	/**
+	 * 公司级业务字典
+	 * @param type
+	 * @return
+	 */
+	public static List<MainDictDetail> getMainDictList(String type){
+		MainDict mainDict = mainDictService.getIdByName(type);
+		MainDictDetail mainDictDetail = new MainDictDetail();
+		boolean admin = UserUtils.getUser().isAdmin();
+		List<MainDictDetail> dictList=new ArrayList<>();
+		if(!admin){
+			if("1".equals(mainDict.getDictType())){
+				mainDictDetail.setBranchOffice(UserUtils.getSelectCompany().getId());
+			}else{
+				mainDictDetail.setBranchOffice(UserUtils.getSelectBranchOffice());
+			}
+			mainDictDetail.setType(type);
+			mainDictDetail.setLevel("2");
+			dictList = mainDictDetailDao.findAllList(mainDictDetail);
+			return dictList;
+		}else{
+			mainDictDetail.setType(type);
+			mainDictDetail.setLevel("1");
+			dictList= mainDictDetailDao.findAllList(mainDictDetail);
+			return dictList;
+		}
+	}
+
+	public static List<MainDictDetail> getMainDictListView(String type){
+		MainDict mainDict = mainDictService.getIdByName(type);
+		MainDictDetail mainDictDetail = new MainDictDetail();
+		boolean admin = UserUtils.getUser().isAdmin();
+		List<MainDictDetail> dictList=new ArrayList<>();
+		if(!admin){
+			if("1".equals(mainDict.getDictType())){
+				mainDictDetail.setBranchOffice(UserUtils.getSelectCompany().getId());
+			}else{
+				mainDictDetail.setBranchOffice(UserUtils.getSelectBranchOffice());
+			}
+			mainDictDetail.setType(type);
+			mainDictDetail.setLevel("2");
+			dictList = mainDictDetailDao.findAllListView(mainDictDetail);
+			return dictList;
+		}else{
+			mainDictDetail.setType(type);
+			mainDictDetail.setLevel("1");
+			dictList= mainDictDetailDao.findAllListView(mainDictDetail);
+			return dictList;
+		}
+	}
+	/**
+	 * 公司级业务字典
+	 * @param
+	 * @return
+	 *//*
+	public static List<MainDictDetail> getMainDictList(String type){
+		MainDictDetail mainDictDetail = new MainDictDetail();
+		boolean admin = UserUtils.getUser().isAdmin();
+		List<MainDictDetail> dictList=new ArrayList<>();
+		if(!admin){
+			mainDictDetail.setType(type);
+			Office office=UserUtils.getSelectOffice();
+			if(com.jeeplus.common.utils.StringUtils.isNotBlank(office.getBranchOffice())){//登录人是分公司
+				mainDictDetail.setBranchOffice(office.getBranchOffice());
+				mainDictDetail.setLevel("3");
+				dictList = mainDictDetailDao.findAllList(mainDictDetail);
+				if(dictList != null&&dictList.size()>0){
+					return dictList;
+				}else{
+					mainDictDetail.setBranchOffice(UserUtils.getSelectCompany().getId());
+					mainDictDetail.setLevel("2");
+					dictList = mainDictDetailDao.findAllList(mainDictDetail);
+					if(dictList != null&&dictList.size()>0){
+						return dictList;
+					}else{
+						MainDictDetail dictDetail = new MainDictDetail();
+						dictDetail.setType(type);
+						dictDetail.setLevel("1");
+						dictList= mainDictDetailDao.findAllList(dictDetail);
+						return dictList;
+					}
+				}
+			}else{
+				mainDictDetail.setBranchOffice(UserUtils.getSelectCompany().getId());
+				mainDictDetail.setLevel("2");
+				dictList = mainDictDetailDao.findAllList(mainDictDetail);
+				if(dictList != null&&dictList.size()>0){
+					return dictList;
+				}else{
+					MainDictDetail dictDetail = new MainDictDetail();
+					dictDetail.setType(type);
+					dictDetail.setLevel("1");
+					dictList= mainDictDetailDao.findAllList(dictDetail);
+					return dictList;
+				}
+			}
+		}else{
+			mainDictDetail.setType(type);
+			mainDictDetail.setLevel("1");
+			dictList= mainDictDetailDao.findAllList(mainDictDetail);
+			return dictList;
+		}
+	}*/
+
+	/*public static List<MainDictDetail> getMainDictListView(String type){
+		MainDictDetail mainDictDetail = new MainDictDetail();
+		boolean admin = UserUtils.getUser().isAdmin();
+		List<MainDictDetail> dictList=new ArrayList<>();
+		if(!admin){
+			mainDictDetail.setType(type);
+			Office office=UserUtils.getSelectOffice();
+			if(com.jeeplus.common.utils.StringUtils.isNotBlank(office.getBranchOffice())){//登录人是分公司
+				mainDictDetail.setBranchOffice(office.getBranchOffice());
+				mainDictDetail.setLevel("3");
+				dictList = mainDictDetailDao.findAllListView(mainDictDetail);
+				if(dictList != null&&dictList.size()>0){
+					return dictList;
+				}else{
+					mainDictDetail.setBranchOffice(UserUtils.getSelectCompany().getId());
+					mainDictDetail.setLevel("2");
+					dictList = mainDictDetailDao.findAllListView(mainDictDetail);
+					if(dictList != null&&dictList.size()>0){
+						return dictList;
+					}else{
+						MainDictDetail dictDetail = new MainDictDetail();
+						dictDetail.setType(type);
+						dictDetail.setLevel("1");
+						dictList= mainDictDetailDao.findAllListView(dictDetail);
+						return dictList;
+					}
+				}
+			}else{
+				mainDictDetail.setBranchOffice(UserUtils.getSelectCompany().getId());
+				mainDictDetail.setLevel("2");
+				dictList = mainDictDetailDao.findAllListView(mainDictDetail);
+				if(dictList != null&&dictList.size()>0){
+					return dictList;
+				}else{
+					MainDictDetail dictDetail = new MainDictDetail();
+					dictDetail.setType(type);
+					dictDetail.setLevel("1");
+					dictList= mainDictDetailDao.findAllListView(dictDetail);
+					return dictList;
+				}
+			}
+		}else{
+			mainDictDetail.setType(type);
+			mainDictDetail.setLevel("1");
+			dictList= mainDictDetailDao.findAllListView(mainDictDetail);
+			return dictList;
+		}
+	}*/
+	/*
+	 * 反射根据对象和属性名获取属性值
+	 */
+	public static Object getValue(Object obj, String filed) {
+		try {
+			Class clazz = obj.getClass();
+			PropertyDescriptor pd = new PropertyDescriptor(filed, clazz);
+			Method getMethod = pd.getReadMethod();//获得get方法
+
+			if (pd != null) {
+
+				Object o = getMethod.invoke(obj);//执行get方法返回一个Object
+				return o;
+
+			}
+		} catch (SecurityException e) {
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			e.printStackTrace();
+		} catch (IntrospectionException e) {
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			e.printStackTrace();
+		}
+		
+		return null;
+	}
+}

+ 221 - 0
src/main/java/com/jeeplus/modules/sys/web/SysRoleActivityController.java

@@ -0,0 +1,221 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sys.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.sys.entity.SysRoleActivity;
+import com.jeeplus.modules.sys.service.SysRoleActivityService;
+
+/**
+ * 工作流角色信息Controller
+ * @author 杨帆
+ * @version 2018-04-23
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/sys/sysroleactivity")
+public class SysRoleActivityController extends BaseController {
+
+	@Autowired
+	private SysRoleActivityService sysRoleActivityService;
+	
+	@ModelAttribute
+	public SysRoleActivity get(@RequestParam(required=false) String id) {
+		SysRoleActivity entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = sysRoleActivityService.get(id);
+		}
+		if (entity == null){
+			entity = new SysRoleActivity();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 工作流角色信息列表页面
+	 */
+	@RequiresPermissions("sys:sysroleactivity:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(SysRoleActivity sysRoleActivity, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<SysRoleActivity> page = sysRoleActivityService.findPage(new Page<SysRoleActivity>(request, response), sysRoleActivity);
+		model.addAttribute("page", page);
+		return "modules/sys/sysroleactivityList";
+	}
+
+	/**
+	 * 查看,增加,编辑工作流角色信息表单页面
+	 */
+	@RequiresPermissions(value={"sys:sysroleactivity:view","sys:sysroleactivity:add","sys:sysroleactivity:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(SysRoleActivity sysRoleActivity, Model model, HttpServletRequest request) {
+		model.addAttribute("sysroleactivity", sysRoleActivity);
+		String view = request.getParameter("view");
+		if (!StringUtils.isBlank(view)) {
+			return "modules/sys/sysroleactivityView";
+		}
+		return "modules/sys/sysroleactivityForm";
+	}
+
+	/**
+	 * 保存工作流角色信息
+	 */
+	@RequiresPermissions(value={"sys:sysroleactivity:add","sys:sysroleactivity:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(SysRoleActivity sysRoleActivity, Model model, RedirectAttributes redirectAttributes, HttpServletRequest request) throws Exception{
+		if (!beanValidator(model, sysRoleActivity)){
+			return form(sysRoleActivity, model,request);
+		}
+		if(!sysRoleActivity.getIsNewRecord()){//编辑表单保存
+			SysRoleActivity t = sysRoleActivityService.get(sysRoleActivity.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(sysRoleActivity, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			sysRoleActivityService.save(t);//保存
+		}else{//新增表单保存
+			sysRoleActivityService.save(sysRoleActivity);//保存
+		}
+		addMessage(redirectAttributes, "保存工作流角色信息成功");
+		return "redirect:"+Global.getAdminPath()+"/sys/sysroleactivity/?repage";
+	}
+	
+	/**
+	 * 删除工作流角色信息
+	 */
+	@RequiresPermissions("sys:sysroleactivity:del")
+	@RequestMapping(value = "delete")
+	public String delete(SysRoleActivity sysRoleActivity1, RedirectAttributes redirectAttributes) {
+        SysRoleActivity sysRoleActivity = sysRoleActivityService.get(sysRoleActivity1.getId());
+        if (!"1".equals(sysRoleActivity.getDelType()) ){
+            String count = sysRoleActivityService.isSysRoleActivityRelation(sysRoleActivity);
+            if ("0".equals(count)){
+                sysRoleActivityService.delete(sysRoleActivity);
+                addMessage(redirectAttributes, "删除工作流角色信息成功");
+            }else {
+                addMessage(redirectAttributes, "该角色为默认角色或存在管理岗位数据不允许删除");
+            }
+        }
+		return "redirect:"+Global.getAdminPath()+"/sys/sysroleactivity/?repage";
+	}
+	
+	/**
+	 * 批量删除工作流角色信息
+	 */
+	@RequiresPermissions("sys:sysroleactivity:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		int count1 = 0;
+		int count2 = 0;
+		for(String id : idArray){
+			SysRoleActivity sysRoleActivity = sysRoleActivityService.get(id);
+			if (!"1".equals(sysRoleActivity.getDelType()) ){
+				String count = sysRoleActivityService.isSysRoleActivityRelation(sysRoleActivity);
+				if ("0".equals(count)){
+					sysRoleActivityService.delete(sysRoleActivity);
+					count1 ++;
+				}else {
+					count2 ++;
+				}
+			}else {
+				count2 ++;
+			}
+		}
+		addMessage(redirectAttributes, "删除工作流角色信息成功"+count1+"条,未成功"+count2+"条,默认角色/存在管理岗位数据不允许删除");
+		return "redirect:"+Global.getAdminPath()+"/sys/sysroleactivity/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("sys:sysroleactivity:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(SysRoleActivity sysRoleActivity, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "工作流角色信息"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<SysRoleActivity> page = sysRoleActivityService.findPage(new Page<SysRoleActivity>(request, response, -1), sysRoleActivity);
+    		new ExportExcel("工作流角色信息", SysRoleActivity.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出工作流角色信息记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/sys/sysroleactivity/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("sys:sysroleactivity: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<SysRoleActivity> list = ei.getDataList(SysRoleActivity.class);
+			for (SysRoleActivity sysRoleActivity : list){
+				try{
+					sysRoleActivityService.save(sysRoleActivity);
+					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()+"/sys/sysroleactivity/?repage";
+    }
+	
+	/**
+	 * 下载导入工作流角色信息数据模板
+	 */
+	@RequiresPermissions("sys:sysroleactivity:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "工作流角色信息数据导入模板.xlsx";
+    		List<SysRoleActivity> list = Lists.newArrayList();
+    		new ExportExcel("工作流角色信息数据", SysRoleActivity.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/sys/sysroleactivity/?repage";
+    }
+	
+	
+	
+
+}

+ 23 - 0
src/main/java/com/jeeplus/modules/sysmodular/dao/SysModularFieldDao.java

@@ -0,0 +1,23 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysmodular.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.sysmodular.entity.SysModularField;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 子段关系DAO接口
+ * @author ssrh
+ * @version 2018-08-17
+ */
+@MyBatisDao
+public interface SysModularFieldDao extends CrudDao<SysModularField> {
+
+    List<SysModularField> find();
+    List<SysModularField> gridColumn(@Param("tableName") String tableName, @Param("dbName") String dbName);
+}

+ 264 - 0
src/main/java/com/jeeplus/modules/sysmodular/web/SysModularController.java

@@ -0,0 +1,264 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysmodular.web;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+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.service.DictService;
+import com.jeeplus.modules.sys.service.MainDictService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.sysmodular.entity.SysModularField;
+import com.jeeplus.modules.sysmodular.service.SysModularFieldService;
+import com.jeeplus.modules.workchangejob.entity.WorkChangeJobUser;
+import com.jeeplus.modules.workstaff.entity.WorkStaffBasicInfo;
+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.sysmodular.entity.SysModular;
+import com.jeeplus.modules.sysmodular.service.SysModularService;
+
+/**
+ * 业务模块Controller
+ * @author ssrh
+ * @version 2018-08-17
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/sysmodular/sysModular")
+public class SysModularController extends BaseController {
+
+	@Autowired
+	private MainDictService mainDictService;
+	@Autowired
+	private DictService dictService;
+	@Autowired
+	private SysModularService sysModularService;
+	@Autowired
+	private SysModularFieldService sysModularFieldService;
+	@Autowired
+	private HttpServletRequest request;
+
+	@ModelAttribute
+	public SysModular get(@RequestParam(required=false) String id) {
+		SysModular entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = sysModularService.get(id);
+		}
+		if (entity == null){
+			entity = new SysModular();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 业务模块列表页面
+	 */
+	//@RequiresPermissions("sysmodular:sysModular:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(SysModular sysModular, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<SysModular> page = sysModularService.findPage(new Page<SysModular>(request, response), sysModular); 
+		model.addAttribute("page", page);
+		return "modules/sysmodular/sysModularList";
+	}
+
+	/**
+	 * 查看,增加,编辑业务模块表单页面
+	 */
+	@RequiresPermissions(value={"sysmodular:sysModular:view","sysmodular:sysModular:add","sysmodular:sysModular:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(SysModular sysModular, Model model) {
+		String tabId = request.getParameter("tabId");
+			List tableList=sysModularService.findTable(Global.getDbName());
+			model.addAttribute("tableList", tableList);
+			model.addAttribute("sysModular", sysModular);
+			return "modules/sysmodular/sysModularFormAdd";
+
+	}
+
+	@RequestMapping(value = "formColumn")
+	public String formColumn(SysModular sysModular, Model model) {
+		String tabId = request.getParameter("tabId");
+		SysModularField sysModularField=new SysModularField();
+		sysModularField.setModularId(sysModular.getId());
+		List<SysModularField> sysModularFieldList=sysModularFieldService.findList(sysModularField);
+		sysModular.setSysModularFieldList(sysModularFieldList);
+		model.addAttribute("sysModular", sysModular);
+		if("1".equals(tabId)){
+			List<String> dictList = dictService.findTypeList();
+			List<String> mainDictList = mainDictService.findTypeList();
+			dictList.addAll(mainDictList);
+			HashSet set = new HashSet(dictList);
+			dictList.clear();
+			dictList.addAll(set);
+			model.addAttribute("dictList", dictList);
+			return "modules/sysmodular/sysModularForm";
+		}else{
+			return "modules/sysmodular/sysModularFormView";
+		}
+	}
+
+	/**
+	 * 保存业务模块
+	 */
+	@RequiresPermissions(value={"sysmodular:sysModular:add","sysmodular:sysModular:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(SysModular sysModular, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, sysModular)){
+			return form(sysModular, model);
+		}
+		//校验模块是否存在
+		List<SysModular> s=sysModularService.findByTableName(sysModular);
+		if(s!=null&&s.size()>0){
+			addMessage(redirectAttributes, "该模块已存在添加失败!");
+			return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+		}
+		if(!sysModular.getIsNewRecord()){//编辑表单保存
+			SysModular t = sysModularService.get(sysModular.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(sysModular, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			sysModularService.save(t);//保存
+		}else{//新增表单保存
+
+			sysModularService.save(sysModular);//保存
+		}
+		addMessage(redirectAttributes, "保存业务模块成功");
+		return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+	}
+
+	@RequestMapping(value = "saveColumn")
+	public String saveColumn(SysModular sysModular, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		sysModularService.saveColumn(sysModular);//保存
+		addMessage(redirectAttributes, "保存业务模块成功");
+		return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+	}
+
+	/**
+	 * 删除业务模块
+	 */
+	@RequiresPermissions("sysmodular:sysModular:del")
+	@RequestMapping(value = "delete")
+	public String delete(SysModular sysModular, RedirectAttributes redirectAttributes) {
+		sysModularService.delete(sysModular);
+		addMessage(redirectAttributes, "删除业务模块成功");
+		return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+	}
+	
+	/**
+	 * 批量删除业务模块
+	 */
+	@RequiresPermissions("sysmodular:sysModular:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			sysModularService.delete(sysModularService.get(id));
+		}
+		addMessage(redirectAttributes, "删除业务模块成功");
+		return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("sysmodular:sysModular:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(SysModular sysModular, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "业务模块"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<SysModular> page = sysModularService.findPage(new Page<SysModular>(request, response, -1), sysModular);
+    		new ExportExcel("业务模块", SysModular.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出业务模块记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("sysmodular:sysModular: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<SysModular> list = ei.getDataList(SysModular.class);
+			for (SysModular sysModular : list){
+				try{
+					sysModularService.save(sysModular);
+					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()+"/sysmodular/sysModular/?repage";
+    }
+	
+	/**
+	 * 下载导入业务模块数据模板
+	 */
+	@RequiresPermissions("sysmodular:sysModular:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "业务模块数据导入模板.xlsx";
+    		List<SysModular> list = Lists.newArrayList(); 
+    		new ExportExcel("业务模块数据", SysModular.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/sysmodular/sysModular/?repage";
+    }
+
+	@RequestMapping(value = "gridColumn")
+	public String gridSelectUser(SysModularField sysModularField,String tableName, String url, HttpServletRequest request, HttpServletResponse response, Model model){
+		/*sysModularField.setTableName(modularId);
+		sysModularField.setDbName();*/
+		List<SysModularField> list=sysModularFieldService.gridColumn("'"+tableName+"'","'"+Global.getDbName()+"'");
+		model.addAttribute("sysModularField", sysModularField);
+		model.addAttribute("url", url);
+		model.addAttribute("tableName", tableName);
+		model.addAttribute("list", list);
+		return  "modules/sysmodular/sysModularFieldList";
+	}
+	
+
+}

+ 18 - 0
src/main/java/com/jeeplus/modules/sysnumberclass/dao/SysNumberClassDao.java

@@ -0,0 +1,18 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysnumberclass.dao;
+
+import com.jeeplus.common.persistence.TreeDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.sysnumberclass.entity.SysNumberClass;
+
+/**
+ * 编码管理DAO接口
+ * @author 丁旭
+ * @version 2017-03-22
+ */
+@MyBatisDao
+public interface SysNumberClassDao extends TreeDao<SysNumberClass> {
+	
+}

+ 69 - 0
src/main/java/com/jeeplus/modules/sysnumberclass/entity/SysNumberClass.java

@@ -0,0 +1,69 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysnumberclass.entity;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+import javax.validation.constraints.NotNull;
+
+import com.jeeplus.common.persistence.TreeEntity;
+
+/**
+ * 编码管理Entity
+ * @author 丁旭
+ * @version 2017-03-22
+ */
+public class SysNumberClass extends TreeEntity<SysNumberClass> {
+	
+	private static final long serialVersionUID = 1L;
+	private SysNumberClass parent;		// 父级编号
+	private String parentIds;		// 所有父级编号
+	private String name;		// 编号分类名
+	private Integer sort;		// 排序
+	
+	public SysNumberClass() {
+		super();
+	}
+
+	public SysNumberClass(String id){
+		super(id);
+	}
+
+	@JsonBackReference
+	public SysNumberClass getParent() {
+		return parent;
+	}
+
+	public void setParent(SysNumberClass parent) {
+		this.parent = parent;
+	}
+	
+	public String getParentIds() {
+		return parentIds;
+	}
+
+	public void setParentIds(String parentIds) {
+		this.parentIds = parentIds;
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@NotNull(message="排序不能为空")
+	public Integer getSort() {
+		return sort;
+	}
+
+	public void setSort(Integer sort) {
+		this.sort = sort;
+	}
+	
+	public String getParentId() {
+		return parent != null && parent.getId() != null ? parent.getId() : "0";
+	}
+}

+ 155 - 0
src/main/java/com/jeeplus/modules/sysnumberinfo/entity/SysNumberInfo.java

@@ -0,0 +1,155 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysnumberinfo.entity;
+
+
+import javax.validation.constraints.NotNull;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sysnumberclass.entity.SysNumberClass;
+
+/**
+ * 编码制定Entity
+ * @author 丁旭
+ * @version 2017-03-22
+ */
+public class SysNumberInfo extends DataEntity<SysNumberInfo> {
+	
+	private static final long serialVersionUID = 1L;
+	private String name;		// 流水名称
+	private String first;		// 前缀名
+	private String separator;		// 分割符
+	private String year;		// 年
+	private String mouth;		// 月
+	private String day;		// 日
+	private String identifier;		// 标识符
+	private String sequence;		// 序列
+	private SysNumberClass sysNumberClass;		// 分类ID
+	private String numLength;		// 序列长度
+	private String numFirst;		// 序列起始值
+	private String example;		// 示例编号
+	
+	public SysNumberInfo() {
+		super();
+	}
+
+	public SysNumberInfo(String id){
+		super(id);
+	}
+
+	@ExcelField(title="流水名称", align=2, sort=6)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@ExcelField(title="前缀名", align=2, sort=7)
+	public String getFirst() {
+		return first;
+	}
+
+	public void setFirst(String first) {
+		this.first = first;
+	}
+	
+	@ExcelField(title="分割符", align=2, sort=8)
+	public String getSeparator() {
+		return separator;
+	}
+
+	public void setSeparator(String separator) {
+		this.separator = separator;
+	}
+	
+	@ExcelField(title="年", dictType="is_yesno", align=2, sort=9)
+	public String getYear() {
+		return year;
+	}
+
+	public void setYear(String year) {
+		this.year = year;
+	}
+	
+	@ExcelField(title="月", dictType="is_yesno", align=2, sort=10)
+	public String getMouth() {
+		return mouth;
+	}
+
+	public void setMouth(String mouth) {
+		this.mouth = mouth;
+	}
+	
+	@ExcelField(title="日", dictType="is_yesno", align=2, sort=11)
+	public String getDay() {
+		return day;
+	}
+
+	public void setDay(String day) {
+		this.day = day;
+	}
+	
+	@ExcelField(title="标识符", align=2, sort=12)
+	public String getIdentifier() {
+		return identifier;
+	}
+
+	public void setIdentifier(String identifier) {
+		this.identifier = identifier;
+	}
+	
+	@ExcelField(title="序列", align=2, sort=13)
+	public String getSequence() {
+		return sequence;
+	}
+
+	public void setSequence(String sequence) {
+		this.sequence = sequence;
+	}
+	
+	
+	
+	
+	@ExcelField(title="序列长度", align=2, sort=15)
+	public String getNumLength() {
+		return numLength;
+	}
+    
+	
+	@NotNull(message="分类ID不能为空")
+	@ExcelField(title="分类ID", align=2, sort=14)
+	public SysNumberClass getSysNumberClass() {
+		return sysNumberClass;
+	}
+
+	public void setSysNumberClass(SysNumberClass sysNumberClass) {
+		this.sysNumberClass = sysNumberClass;
+	}
+
+	public void setNumLength(String numLength) {
+		this.numLength = numLength;
+	}
+	
+	@ExcelField(title="序列起始值", align=2, sort=16)
+	public String getNumFirst() {
+		return numFirst;
+	}
+
+	public void setNumFirst(String numFirst) {
+		this.numFirst = numFirst;
+	}
+	
+	@ExcelField(title="示例编号", align=2, sort=17)
+	public String getExample() {
+		return example;
+	}
+
+	public void setExample(String example) {
+		this.example = example;
+	}
+	
+}

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

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysparameter.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.sysparameter.entity.SysParameterValue;
+import com.jeeplus.modules.sysparameter.dao.SysParameterValueDao;
+
+/**
+ * 系统参数值Service
+ * @author chenyuping
+ * @version 2018-08-13
+ */
+@Service
+@Transactional(readOnly = true)
+public class SysParameterValueService extends CrudService<SysParameterValueDao, SysParameterValue> {
+
+	public SysParameterValue get(String id) {
+		return super.get(id);
+	}
+	
+	public List<SysParameterValue> findList(SysParameterValue sysParameterValue) {
+		return super.findList(sysParameterValue);
+	}
+	
+	public Page<SysParameterValue> findPage(Page<SysParameterValue> page, SysParameterValue sysParameterValue) {
+		return super.findPage(page, sysParameterValue);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(SysParameterValue sysParameterValue) {
+		super.save(sysParameterValue);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(SysParameterValue sysParameterValue) {
+		super.delete(sysParameterValue);
+	}
+	
+	
+	
+	
+}

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

@@ -0,0 +1,196 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sysparameter.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.sysparameter.entity.SysParameterValue;
+import com.jeeplus.modules.sysparameter.service.SysParameterValueService;
+
+/**
+ * 系统参数值Controller
+ * @author chenyuping
+ * @version 2018-08-13
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/sysparameter/sysParameterValue")
+public class SysParameterValueController extends BaseController {
+
+	@Autowired
+	private SysParameterValueService sysParameterValueService;
+	
+	@ModelAttribute
+	public SysParameterValue get(@RequestParam(required=false) String id) {
+		SysParameterValue entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = sysParameterValueService.get(id);
+		}
+		if (entity == null){
+			entity = new SysParameterValue();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 系统参数值列表页面
+	 */
+	@RequiresPermissions("sysparameter:sysParameterValue:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(SysParameterValue sysParameterValue, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<SysParameterValue> page = sysParameterValueService.findPage(new Page<SysParameterValue>(request, response), sysParameterValue); 
+		model.addAttribute("page", page);
+		return "modules/sysparameter/sysParameterValueList";
+	}
+
+	/**
+	 * 查看,增加,编辑系统参数值表单页面
+	 */
+	@RequiresPermissions(value={"sysparameter:sysParameterValue:view","sysparameter:sysParameterValue:add","sysparameter:sysParameterValue:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(SysParameterValue sysParameterValue, Model model) {
+		model.addAttribute("sysParameterValue", sysParameterValue);
+		return "modules/sysparameter/sysParameterValueForm";
+	}
+
+	/**
+	 * 保存系统参数值
+	 */
+	@RequiresPermissions(value={"sysparameter:sysParameterValue:add","sysparameter:sysParameterValue:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(SysParameterValue sysParameterValue, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, sysParameterValue)){
+			return form(sysParameterValue, model);
+		}
+		if(!sysParameterValue.getIsNewRecord()){//编辑表单保存
+			SysParameterValue t = sysParameterValueService.get(sysParameterValue.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(sysParameterValue, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			sysParameterValueService.save(t);//保存
+		}else{//新增表单保存
+			sysParameterValueService.save(sysParameterValue);//保存
+		}
+		addMessage(redirectAttributes, "保存系统参数值成功");
+		return "redirect:"+Global.getAdminPath()+"/sysparameter/sysParameterValue/?repage";
+	}
+	
+	/**
+	 * 删除系统参数值
+	 */
+	@RequiresPermissions("sysparameter:sysParameterValue:del")
+	@RequestMapping(value = "delete")
+	public String delete(SysParameterValue sysParameterValue, RedirectAttributes redirectAttributes) {
+		sysParameterValueService.delete(sysParameterValue);
+		addMessage(redirectAttributes, "删除系统参数值成功");
+		return "redirect:"+Global.getAdminPath()+"/sysparameter/sysParameterValue/?repage";
+	}
+	
+	/**
+	 * 批量删除系统参数值
+	 */
+	@RequiresPermissions("sysparameter:sysParameterValue:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			sysParameterValueService.delete(sysParameterValueService.get(id));
+		}
+		addMessage(redirectAttributes, "删除系统参数值成功");
+		return "redirect:"+Global.getAdminPath()+"/sysparameter/sysParameterValue/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("sysparameter:sysParameterValue:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(SysParameterValue sysParameterValue, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "系统参数值"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<SysParameterValue> page = sysParameterValueService.findPage(new Page<SysParameterValue>(request, response, -1), sysParameterValue);
+    		new ExportExcel("系统参数值", SysParameterValue.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出系统参数值记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/sysparameter/sysParameterValue/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("sysparameter:sysParameterValue: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<SysParameterValue> list = ei.getDataList(SysParameterValue.class);
+			for (SysParameterValue sysParameterValue : list){
+				try{
+					sysParameterValueService.save(sysParameterValue);
+					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()+"/sysparameter/sysParameterValue/?repage";
+    }
+	
+	/**
+	 * 下载导入系统参数值数据模板
+	 */
+	@RequiresPermissions("sysparameter:sysParameterValue:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "系统参数值数据导入模板.xlsx";
+    		List<SysParameterValue> list = Lists.newArrayList(); 
+    		new ExportExcel("系统参数值数据", SysParameterValue.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/sysparameter/sysParameterValue/?repage";
+    }
+	
+	
+	
+
+}

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

@@ -0,0 +1,19 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.syswarning.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.syswarning.entity.SysWarningLog;
+
+/**
+ * 预警日志DAO接口
+ * @author ssrh
+ * @version 2018-08-16
+ */
+@MyBatisDao
+public interface SysWarningLogDao extends CrudDao<SysWarningLog> {
+
+	
+}

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

@@ -0,0 +1,196 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.syswarning.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.syswarning.entity.SysWarningUser;
+import com.jeeplus.modules.syswarning.service.SysWarningUserService;
+
+/**
+ * 系统预警Controller
+ * @author chenyuping
+ * @version 2018-08-14
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/syswarning/sysWarningUser")
+public class SysWarningUserController extends BaseController {
+
+	@Autowired
+	private SysWarningUserService sysWarningUserService;
+	
+	@ModelAttribute
+	public SysWarningUser get(@RequestParam(required=false) String id) {
+		SysWarningUser entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = sysWarningUserService.get(id);
+		}
+		if (entity == null){
+			entity = new SysWarningUser();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 系统预警列表页面
+	 */
+	@RequiresPermissions("syswarning:sysWarningUser:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(SysWarningUser sysWarningUser, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<SysWarningUser> page = sysWarningUserService.findPage(new Page<SysWarningUser>(request, response), sysWarningUser); 
+		model.addAttribute("page", page);
+		return "modules/syswarning/sysWarningUserList";
+	}
+
+	/**
+	 * 查看,增加,编辑系统预警表单页面
+	 */
+	@RequiresPermissions(value={"syswarning:sysWarningUser:view","syswarning:sysWarningUser:add","syswarning:sysWarningUser:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(SysWarningUser sysWarningUser, Model model) {
+		model.addAttribute("sysWarningUser", sysWarningUser);
+		return "modules/syswarning/sysWarningUserForm";
+	}
+
+	/**
+	 * 保存系统预警
+	 */
+	@RequiresPermissions(value={"syswarning:sysWarningUser:add","syswarning:sysWarningUser:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(SysWarningUser sysWarningUser, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, sysWarningUser)){
+			return form(sysWarningUser, model);
+		}
+		if(!sysWarningUser.getIsNewRecord()){//编辑表单保存
+			SysWarningUser t = sysWarningUserService.get(sysWarningUser.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(sysWarningUser, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			sysWarningUserService.save(t);//保存
+		}else{//新增表单保存
+			sysWarningUserService.save(sysWarningUser);//保存
+		}
+		addMessage(redirectAttributes, "保存系统预警成功");
+		return "redirect:"+Global.getAdminPath()+"/syswarning/sysWarningUser/?repage";
+	}
+	
+	/**
+	 * 删除系统预警
+	 */
+	@RequiresPermissions("syswarning:sysWarningUser:del")
+	@RequestMapping(value = "delete")
+	public String delete(SysWarningUser sysWarningUser, RedirectAttributes redirectAttributes) {
+		sysWarningUserService.delete(sysWarningUser);
+		addMessage(redirectAttributes, "删除系统预警成功");
+		return "redirect:"+Global.getAdminPath()+"/syswarning/sysWarningUser/?repage";
+	}
+	
+	/**
+	 * 批量删除系统预警
+	 */
+	@RequiresPermissions("syswarning:sysWarningUser:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			sysWarningUserService.delete(sysWarningUserService.get(id));
+		}
+		addMessage(redirectAttributes, "删除系统预警成功");
+		return "redirect:"+Global.getAdminPath()+"/syswarning/sysWarningUser/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("syswarning:sysWarningUser:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(SysWarningUser sysWarningUser, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "系统预警"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<SysWarningUser> page = sysWarningUserService.findPage(new Page<SysWarningUser>(request, response, -1), sysWarningUser);
+    		new ExportExcel("系统预警", SysWarningUser.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出系统预警记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/syswarning/sysWarningUser/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("syswarning:sysWarningUser: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<SysWarningUser> list = ei.getDataList(SysWarningUser.class);
+			for (SysWarningUser sysWarningUser : list){
+				try{
+					sysWarningUserService.save(sysWarningUser);
+					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()+"/syswarning/sysWarningUser/?repage";
+    }
+	
+	/**
+	 * 下载导入系统预警数据模板
+	 */
+	@RequiresPermissions("syswarning:sysWarningUser:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "系统预警数据导入模板.xlsx";
+    		List<SysWarningUser> list = Lists.newArrayList(); 
+    		new ExportExcel("系统预警数据", SysWarningUser.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/syswarning/sysWarningUser/?repage";
+    }
+	
+	
+	
+
+}

+ 19 - 0
src/main/java/com/jeeplus/modules/test/dao/onetomany/TestDataChild3Dao.java

@@ -0,0 +1,19 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.test.dao.onetomany;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.test.entity.onetomany.TestDataChild3;
+
+/**
+ * 票务代理DAO接口
+ * @author liugf
+ * @version 2016-10-06
+ */
+@MyBatisDao
+public interface TestDataChild3Dao extends CrudDao<TestDataChild3> {
+
+	
+}

+ 19 - 0
src/main/java/com/jeeplus/modules/test/dao/validation/TestValidationDao.java

@@ -0,0 +1,19 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.test.dao.validation;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.test.entity.validation.TestValidation;
+
+/**
+ * 测试校验功能DAO接口
+ * @author lgf
+ * @version 2016-10-05
+ */
+@MyBatisDao
+public interface TestValidationDao extends CrudDao<TestValidation> {
+
+	
+}

+ 74 - 0
src/main/java/com/jeeplus/modules/test/entity/onetomany/TestDataChild2.java

@@ -0,0 +1,74 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.test.entity.onetomany;
+
+import com.jeeplus.modules.sys.entity.Area;
+import javax.validation.constraints.NotNull;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+/**
+ * 票务代理Entity
+ * @author liugf
+ * @version 2016-10-06
+ */
+public class TestDataChild2 extends DataEntity<TestDataChild2> {
+	
+	private static final long serialVersionUID = 1L;
+	private Area startArea;		// 出发地
+	private Area endArea;		// 目的地
+	private Double price;		// 代理价格
+	private TestDataMain testDataMain;		// 外键 父类
+	
+	public TestDataChild2() {
+		super();
+	}
+
+	public TestDataChild2(String id){
+		super(id);
+	}
+
+	public TestDataChild2(TestDataMain testDataMain){
+		this.testDataMain = testDataMain;
+	}
+
+	@NotNull(message="出发地不能为空")
+	@ExcelField(title="出发地", fieldType=Area.class, value="startArea.name", align=2, sort=1)
+	public Area getStartArea() {
+		return startArea;
+	}
+
+	public void setStartArea(Area startArea) {
+		this.startArea = startArea;
+	}
+	
+	@NotNull(message="目的地不能为空")
+	@ExcelField(title="目的地", fieldType=Area.class, value="endArea.name", align=2, sort=2)
+	public Area getEndArea() {
+		return endArea;
+	}
+
+	public void setEndArea(Area endArea) {
+		this.endArea = endArea;
+	}
+	
+	@ExcelField(title="代理价格", align=2, sort=3)
+	public Double getPrice() {
+		return price;
+	}
+
+	public void setPrice(Double price) {
+		this.price = price;
+	}
+	
+	public TestDataMain getTestDataMain() {
+		return testDataMain;
+	}
+
+	public void setTestDataMain(TestDataMain testDataMain) {
+		this.testDataMain = testDataMain;
+	}
+	
+}

+ 50 - 0
src/main/java/com/jeeplus/modules/test/service/one/FormLeaveService.java

@@ -0,0 +1,50 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.test.service.one;
+
+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.test.entity.one.FormLeave;
+import com.jeeplus.modules.test.dao.one.FormLeaveDao;
+
+/**
+ * 请假表单Service
+ * @author lgf
+ * @version 2016-10-06
+ */
+@Service
+@Transactional(readOnly = true)
+public class FormLeaveService extends CrudService<FormLeaveDao, FormLeave> {
+
+	public FormLeave get(String id) {
+		return super.get(id);
+	}
+	
+	public List<FormLeave> findList(FormLeave formLeave) {
+		return super.findList(formLeave);
+	}
+	
+	public Page<FormLeave> findPage(Page<FormLeave> page, FormLeave formLeave) {
+		return super.findPage(page, formLeave);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(FormLeave formLeave) {
+		super.save(formLeave);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(FormLeave formLeave) {
+		super.delete(formLeave);
+	}
+	
+	
+	
+	
+}

+ 196 - 0
src/main/java/com/jeeplus/modules/test/web/note/TestNoteController.java

@@ -0,0 +1,196 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.test.web.note;
+
+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.test.entity.note.TestNote;
+import com.jeeplus.modules.test.service.note.TestNoteService;
+
+/**
+ * 富文本测试Controller
+ * @author liugf
+ * @version 2016-10-04
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/test/note/testNote")
+public class TestNoteController extends BaseController {
+
+	@Autowired
+	private TestNoteService testNoteService;
+	
+	@ModelAttribute
+	public TestNote get(@RequestParam(required=false) String id) {
+		TestNote entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = testNoteService.get(id);
+		}
+		if (entity == null){
+			entity = new TestNote();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 富文本测试列表页面
+	 */
+	@RequiresPermissions("test:note:testNote:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(TestNote testNote, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<TestNote> page = testNoteService.findPage(new Page<TestNote>(request, response), testNote); 
+		model.addAttribute("page", page);
+		return "modules/test/note/testNoteList";
+	}
+
+	/**
+	 * 查看,增加,编辑富文本测试表单页面
+	 */
+	@RequiresPermissions(value={"test:note:testNote:view","test:note:testNote:add","test:note:testNote:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(TestNote testNote, Model model) {
+		model.addAttribute("testNote", testNote);
+		return "modules/test/note/testNoteForm";
+	}
+
+	/**
+	 * 保存富文本测试
+	 */
+	@RequiresPermissions(value={"test:note:testNote:add","test:note:testNote:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(TestNote testNote, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, testNote)){
+			return form(testNote, model);
+		}
+		if(!testNote.getIsNewRecord()){//编辑表单保存
+			TestNote t = testNoteService.get(testNote.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(testNote, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			testNoteService.save(t);//保存
+		}else{//新增表单保存
+			testNoteService.save(testNote);//保存
+		}
+		addMessage(redirectAttributes, "保存富文本测试成功");
+		return "redirect:"+Global.getAdminPath()+"/test/note/testNote/?repage";
+	}
+	
+	/**
+	 * 删除富文本测试
+	 */
+	@RequiresPermissions("test:note:testNote:del")
+	@RequestMapping(value = "delete")
+	public String delete(TestNote testNote, RedirectAttributes redirectAttributes) {
+		testNoteService.delete(testNote);
+		addMessage(redirectAttributes, "删除富文本测试成功");
+		return "redirect:"+Global.getAdminPath()+"/test/note/testNote/?repage";
+	}
+	
+	/**
+	 * 批量删除富文本测试
+	 */
+	@RequiresPermissions("test:note:testNote:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			testNoteService.delete(testNoteService.get(id));
+		}
+		addMessage(redirectAttributes, "删除富文本测试成功");
+		return "redirect:"+Global.getAdminPath()+"/test/note/testNote/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("test:note:testNote:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(TestNote testNote, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "富文本测试"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<TestNote> page = testNoteService.findPage(new Page<TestNote>(request, response, -1), testNote);
+    		new ExportExcel("富文本测试", TestNote.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出富文本测试记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/test/note/testNote/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("test:note:testNote: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<TestNote> list = ei.getDataList(TestNote.class);
+			for (TestNote testNote : list){
+				try{
+					testNoteService.save(testNote);
+					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()+"/test/note/testNote/?repage";
+    }
+	
+	/**
+	 * 下载导入富文本测试数据模板
+	 */
+	@RequiresPermissions("test:note:testNote:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "富文本测试数据导入模板.xlsx";
+    		List<TestNote> list = Lists.newArrayList(); 
+    		new ExportExcel("富文本测试数据", TestNote.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/test/note/testNote/?repage";
+    }
+	
+	
+	
+
+}

+ 18 - 0
src/main/java/com/jeeplus/modules/tools/dao/TestInterfaceDao.java

@@ -0,0 +1,18 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.tools.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.tools.entity.TestInterface;
+
+/**
+ * 接口DAO接口
+ * @author lgf
+ * @version 2016-01-07
+ */
+@MyBatisDao
+public interface TestInterfaceDao extends CrudDao<TestInterface> {
+	
+}

+ 43 - 0
src/main/java/com/jeeplus/modules/work/dao/report/WorkReportDao.java

@@ -0,0 +1,43 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.work.dao.report;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.work.entity.report.WorkReport;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 工作日志DAO接口
+ * @author 许凯
+ * @version 2017-04-21
+ */
+@MyBatisDao
+public interface WorkReportDao extends CrudDao<WorkReport> {
+
+	public List<WorkReport> findGetList(WorkReport workReport);
+	public List getCreateDateList(Map<String,String> 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<WorkReport> findByCompany2(@Param("wr") WorkReport workReport,@Param("date") String date);
+	public List<WorkReport> findByCompany(WorkReport workReport);
+	public List<WorkReport> findReportUserByCompany(WorkReport workReport);
+	public List<WorkReport> findOutList(WorkReport workReport);
+
+	public List<WorkReport> findByManage(Map<String,Object> map);
+	public List<WorkReport> findByCompanySelf(Map<String,Object> map);
+	public WorkReport findNewId();
+
+	//更新选择的环信群组
+	void updateEasemobGroupId(WorkReport workReport);
+
+    //查询某一天自己的工作
+	public List<WorkReport> reportlist(Map<String,Object> map);
+	public List<WorkReport> reportlistAll(Map<String,Object> map);
+}

+ 88 - 0
src/main/java/com/jeeplus/modules/work/entity/report/WorkReportRecord.java

@@ -0,0 +1,88 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.work.entity.report;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.iim.entity.LayGroup;
+import com.jeeplus.modules.sys.entity.User;
+
+import java.util.Date;
+
+/**
+ * 工作报告Entity
+ * @author 许凯
+ * @version 2017-04-21
+ */
+public class WorkReportRecord extends DataEntity<WorkReportRecord> {
+	
+	private static final long serialVersionUID = 1L;
+	private WorkReport report;		// 工作报告主键ID 父类
+	private User user;		// 接收人
+	private LayGroup group;	// 接收群//已弃用
+	private String readFlag;		// 阅读标记
+	private Date readDate;		// 阅读时间
+	
+	public WorkReportRecord() {
+		super();
+	}
+
+	public WorkReportRecord(String id){
+		super(id);
+	}
+
+	public WorkReportRecord(WorkReport report){
+		this.report = report;
+	}
+
+	public WorkReport getReport() {
+		return report;
+	}
+
+	public void setReport(WorkReport report) {
+		this.report = report;
+	}
+	
+	@ExcelField(title="接收人", fieldType=User.class, value="user.name", align=2, sort=2)
+	public User getUser() {
+		return user;
+	}
+
+	public void setUser(User user) {
+		this.user = user;
+	}
+	
+	@ExcelField(title="接收群", fieldType=LayGroup.class, value="group.groupname", align=2, sort=3)
+
+	public LayGroup getGroup() {
+	//	System.out.println("=====group======"+group);
+		return group;
+	}
+
+	public void setGroup(LayGroup group) {
+		this.group = group;
+	}
+	
+	@ExcelField(title="阅读标记", align=2, sort=4)
+	public String getReadFlag() {
+		return readFlag;
+	}
+
+
+	public void setReadFlag(String readFlag) {
+		this.readFlag = readFlag;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@ExcelField(title="阅读时间", align=2, sort=5)
+	public Date getReadDate() {
+		return readDate;
+	}
+
+	public void setReadDate(Date readDate) {
+		this.readDate = readDate;
+	}
+	
+}

+ 414 - 0
src/main/java/com/jeeplus/modules/workactivity/service/WorkActivityProcessService.java

@@ -0,0 +1,414 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workactivity.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.workactivity.entity.Activity;
+import com.jeeplus.modules.workactivity.entity.WorkActivityProcessUser;
+import com.jeeplus.modules.workactivitymenu.entity.WorkActivityMenu;
+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.workactivity.entity.WorkActivityProcess;
+import com.jeeplus.modules.workactivity.dao.WorkActivityProcessDao;
+
+/**
+ * 工作流审批信息Service
+ * @author 杨帆
+ * @version 2018-01-30
+ */
+@Service
+@Transactional(readOnly = true)
+public class WorkActivityProcessService extends CrudService<WorkActivityProcessDao, WorkActivityProcess> {
+
+	public WorkActivityProcess get(String id) {
+		return super.get(id);
+	}
+	
+	public List<WorkActivityProcess> findByKeyAndCount(WorkActivityProcess workActivityProcess) {
+		return dao.findByKeyAndCount(workActivityProcess);
+	}
+	public List<WorkActivityProcess> findList(WorkActivityProcess workActivityProcess) {
+		return super.findList(workActivityProcess);
+	}
+	public List<WorkActivityProcess> findByProcInsId(WorkActivityProcess workActivityProcess) {
+		return dao.findByProcInsId(workActivityProcess);
+	}
+	public List<WorkActivityProcess> findByProcInsIdAudit(WorkActivityProcess workActivityProcess) {
+		return dao.findByProcInsIdAudit(workActivityProcess);
+	}
+	public List<WorkActivityProcess> findByProcInsIdAndIsApproval(WorkActivityProcess workActivityProcess) {
+		return dao.findByProcInsIdAndIsApproval(workActivityProcess);
+	}
+
+	public Page<WorkActivityProcess> findPage(Page<WorkActivityProcess> page, WorkActivityProcess workActivityProcess) {
+		return super.findPage(page, workActivityProcess);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkActivityProcess workActivityProcess) {
+		super.save(workActivityProcess);
+	}
+	@Transactional(readOnly = false)
+	public void insert(WorkActivityProcess workActivityProcess) {
+		workActivityProcess.preInsert();
+		dao.insert(workActivityProcess);
+	}
+
+	@Transactional(readOnly = false)
+	public void insertAudits(WorkActivityProcess workActivityProcess) {
+		dao.insertAudits(workActivityProcess);
+	}
+	@Transactional(readOnly = false)
+	public void insertAuditsByType(List<User> users,String processId,int count,int type) {
+		WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+		List<WorkActivityProcessUser> processUserList = new ArrayList<>();
+		if(users!=null&&users.size()!=0){
+			for (User u :users){
+				WorkActivityProcessUser process = new WorkActivityProcessUser();
+				process.setCount(count);
+				process.setUserId(u.getId());
+				process.setProcessId(processId);
+				process.setType(type);
+				processUserList.add(process);
+			}
+			workActivityProcess.setProcessUserList(processUserList);
+			if(count>1 && type==1) {
+				dao.deleteAudits(processId,count);
+			}
+			dao.insertAudits(workActivityProcess);
+		}
+
+	}
+	@Transactional(readOnly = false)
+	public void delFlag(WorkActivityProcess workActivityProcess) {
+		dao.delFlag(workActivityProcess);
+	}
+	@Transactional(readOnly = false)
+	public void updateProcessInstanceId(String processInstanceId,String processId) {
+		dao.updateProcessInstanceId(processInstanceId,processId);
+	}
+	@Transactional(readOnly = false)
+	public void deleteProcessInstanceId(String processId) {
+		dao.deleteProcessInstanceId(processId);
+	}
+	@Transactional(readOnly = false)
+	public void deleteProcessInstanceById(String processId) {
+		dao.deleteProcessInstanceById(processId);
+	}
+	@Transactional(readOnly = false)
+	public void updateProcess(WorkActivityProcess workActivityProcess, WorkActivityMenu workActivityMenu,int key, String taskCount, String processInstanceId, String taskDefKey,String audit, String flag, String comment, List<Activity> activities) {
+		if (workActivityProcess.getCount()!=0){
+			workActivityProcess.setId("");
+		}else {
+			WorkActivityProcess workActivityProcess1 = new WorkActivityProcess();
+			workActivityProcess1.setIsApproval("0");
+			workActivityProcess1.setCount(0);
+			workActivityProcess1.setProcessInstanceId(processInstanceId);
+			this.deleteByAudit(workActivityProcess1);
+		}
+
+		workActivityProcess.setRemarks(comment);
+		workActivityProcess.setProcessInstanceId(processInstanceId);
+		workActivityProcess.setProcessKey(workActivityMenu.getProcessType());
+		if (workActivityProcess.getCount()!=0) {
+			workActivityProcess.setCount(Integer.parseInt(taskCount));
+		}
+		workActivityProcess.setIsApproval("yes".equals(flag)?"1":"2");
+		if (workActivityProcess!=null && StringUtils.isNotBlank(workActivityProcess.getIsApproval())){
+
+			WorkActivityProcess w = new WorkActivityProcess();
+			w.setProcessInstanceId(processInstanceId);
+			w.setIsApproval("0");
+			w.setDelFlag("0");
+			this.delFlag(w);
+			WorkActivityProcess process = w;
+			if((taskDefKey.equals("modifyApply") && key==1) || (taskDefKey.equals(audit)&& key==0)) {
+				if ("yes".equals(flag)){
+					String returnBack = "";
+					for (Activity activity : activities) {
+						if (activity.getCount() == Integer.parseInt(taskCount)) {
+							returnBack = activity.getReturnBack();
+						}
+					}
+					if (!returnBack.equals("0")) {
+						if (returnBack.equals("1")) {
+							if (!taskCount.equals("1")) {
+								process.setCount(1);
+							}else {
+								process.setCount(1);
+							}
+						} else if (returnBack.equals("2")) {
+							process.setCount(1);
+						} else{
+							process.setCount(1);
+						}
+					}
+					workActivityProcess.setId("");
+				}else {
+					process.setCount(11);
+				}
+			}else {
+				if ("yes".equals(flag)) {
+					process.setCount(Integer.parseInt(taskCount) + 1);
+				} else {
+					String returnBack = "";
+					for (Activity activity : activities) {
+						if (activity.getCount() == Integer.parseInt(taskCount)) {
+							returnBack = activity.getReturnBack();
+						}
+					}
+					if (!returnBack.equals("0")) {
+						if (returnBack.equals("1")) {
+							if (!taskCount.equals("1")) {
+								process.setCount(1);
+							}else {
+								process.setCount(1);
+							}
+						} else if (returnBack.equals("2")) {
+							process.setCount(1);
+						} else{
+							process.setCount(1);
+						}
+						WorkActivityProcess workActivityProcess1 = new WorkActivityProcess();
+						workActivityProcess1.setCount(0);
+						workActivityProcess1.setProcessInstanceId(processInstanceId);
+						workActivityProcess1.setProcessKey(workActivityMenu.getProcessType());
+						workActivityProcess1.setIsApproval("0");
+						workActivityProcess1.setActivityTask("modifyApply");
+						this.save(workActivityProcess1);
+					}
+				}
+			}
+			process.setDelFlag("1");
+			this.delFlag(process);
+			if (workActivityProcess.getCount()==0){
+				workActivityProcess.setDelFlag("0");
+			}
+			this.save(workActivityProcess);
+		}
+	}
+	@Transactional(readOnly = false)
+	public void updateProcessSpecial(WorkActivityProcess workActivityProcess, WorkActivityMenu workActivityMenu,int key, String taskCount, String processInstanceId, String taskDefKey,String audit, String flag, String comment, List<Activity> activities) {
+		if (workActivityProcess.getCount()!=0){
+			workActivityProcess.setId("");
+		}else {
+			WorkActivityProcess workActivityProcess1 = new WorkActivityProcess();
+			workActivityProcess1.setIsApproval("0");
+			workActivityProcess1.setCount(0);
+			workActivityProcess1.setProcessInstanceId(processInstanceId);
+			this.deleteByAudit(workActivityProcess1);
+		}
+
+		workActivityProcess.setRemarks(comment);
+		workActivityProcess.setProcessInstanceId(processInstanceId);
+		workActivityProcess.setProcessKey(workActivityMenu.getProcessType());
+		if (workActivityProcess.getCount()!=0) {
+			workActivityProcess.setCount(Integer.parseInt(taskCount));
+		}
+		//1 -3 通过 2驳回
+		workActivityProcess.setIsApproval("2".equals(flag)?"2":"1");
+		if (workActivityProcess!=null && StringUtils.isNotBlank(workActivityProcess.getIsApproval())){
+
+			WorkActivityProcess w = new WorkActivityProcess();
+			w.setProcessInstanceId(processInstanceId);
+			w.setIsApproval("0");
+			w.setDelFlag("0");
+			this.delFlag(w);
+			WorkActivityProcess process = w;
+			if((taskDefKey.equals("modifyApply") && key==1) || (taskDefKey.equals(audit)&& key==0)) {
+				if ("1".equals(flag) || "3".equals(flag)){
+					String returnBack = "";
+					for (Activity activity : activities) {
+						if (activity.getCount() == Integer.parseInt(taskCount)) {
+							returnBack = activity.getReturnBack();
+						}
+					}
+					if (!returnBack.equals("0")) {
+						if (returnBack.equals("1")) {
+							if (!taskCount.equals("1")) {
+								process.setCount(1);
+							}else {
+								process.setCount(1);
+							}
+						} else if (returnBack.equals("2")) {
+							process.setCount(1);
+						} else{
+							process.setCount(1);
+						}
+					}
+					workActivityProcess.setId("");
+				}else {
+					process.setCount(11);
+				}
+			}else {
+				if ("1".equals(flag) || "3".equals(flag)) {
+					process.setCount(Integer.parseInt(taskCount) + 1);
+				} else {
+					String returnBack = "";
+					for (Activity activity : activities) {
+						if (activity.getCount() == Integer.parseInt(taskCount)) {
+							returnBack = activity.getReturnBack();
+						}
+					}
+					if (!returnBack.equals("0")) {
+						if (returnBack.equals("1")) {
+							if (!taskCount.equals("1")) {
+								process.setCount(1);
+							}else {
+								process.setCount(1);
+							}
+						} else if (returnBack.equals("2")) {
+							process.setCount(1);
+						} else{
+							process.setCount(1);
+						}
+						WorkActivityProcess workActivityProcess1 = new WorkActivityProcess();
+						workActivityProcess1.setCount(0);
+						workActivityProcess1.setProcessInstanceId(processInstanceId);
+						workActivityProcess1.setProcessKey(workActivityMenu.getProcessType());
+						workActivityProcess1.setIsApproval("0");
+						workActivityProcess1.setActivityTask("modifyApply");
+						this.save(workActivityProcess1);
+					}
+				}
+			}
+			process.setDelFlag("1");
+			this.delFlag(process);
+			if (workActivityProcess.getCount()==0){
+				workActivityProcess.setDelFlag("0");
+			}
+			this.save(workActivityProcess);
+		}
+	}
+	@Transactional(readOnly = false)
+	public void deleteByAudit(WorkActivityProcess workActivityProcess) {
+		dao.deleteByAudit(workActivityProcess);
+	}
+	@Transactional(readOnly = false)
+	public void deleteProcessIdAuditUsers(String processInstanceId) {
+		dao.deleteProcessIdAuditUsers(processInstanceId);
+	}
+
+	@Transactional(readOnly = false)
+	public void saveList(List<Activity> list,String processInstanceId) {
+		for (Activity activity:list){
+			WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+			workActivityProcess.setProcessKey(activity.getProcessKey());
+			workActivityProcess.setCount(activity.getCount());
+			workActivityProcess.setProcessInstanceId(processInstanceId);
+			workActivityProcess.setIsApproval("0");
+			workActivityProcess.setActivity(activity);
+			workActivityProcess.setActivityTask(activity.getActivityTask());
+			super.save(workActivityProcess);
+		}
+	}
+
+	@Transactional(readOnly = false)
+	public void delete(WorkActivityProcess workActivityProcess) {
+		super.delete(workActivityProcess);
+	}
+	
+	public void deleteyProcess(String id){
+		dao.deleteyProcess(id);
+	}
+
+	@Transactional(readOnly = false)
+	public void updateProcessRegular(WorkActivityProcess workActivityProcess, WorkActivityMenu workActivityMenu,int key, String taskCount, String processInstanceId, String taskDefKey,String audit, String flag, String comment, List<Activity> activities) {
+		if (workActivityProcess.getCount()!=0){
+			workActivityProcess.setId("");
+		}else {
+			WorkActivityProcess workActivityProcess1 = new WorkActivityProcess();
+			workActivityProcess1.setIsApproval("0");
+			workActivityProcess1.setCount(0);
+			workActivityProcess1.setProcessInstanceId(processInstanceId);
+			this.deleteByAudit(workActivityProcess1);
+		}
+
+		workActivityProcess.setRemarks(comment);
+		workActivityProcess.setProcessInstanceId(processInstanceId);
+		workActivityProcess.setProcessKey(workActivityMenu.getProcessType());
+		if (workActivityProcess.getCount()!=0) {
+			workActivityProcess.setCount(Integer.parseInt(taskCount));
+		}
+		workActivityProcess.setIsApproval("yes".equals(flag)?"1":"2");
+		if (workActivityProcess!=null && StringUtils.isNotBlank(workActivityProcess.getIsApproval())){
+
+			WorkActivityProcess w = new WorkActivityProcess();
+			w.setProcessInstanceId(processInstanceId);
+			w.setIsApproval("0");
+			w.setDelFlag("0");
+			this.delFlag(w);
+			WorkActivityProcess process = w;
+			if((taskDefKey.equals("modifyApply") && key==1) || (taskDefKey.equals(audit)&& key==0)) {
+				if ("yes".equals(flag)){
+					String returnBack = "";
+					for (Activity activity : activities) {
+						if (activity.getCount() == Integer.parseInt(taskCount)) {
+							returnBack = activity.getReturnBack();
+						}
+					}
+					if (!returnBack.equals("0")) {
+						if (returnBack.equals("1")) {
+							if (!taskCount.equals("1")) {
+								process.setCount(1);
+							}else {
+								process.setCount(1);
+							}
+						} else if (returnBack.equals("2")) {
+							process.setCount(1);
+						} else{
+							process.setCount(1);
+						}
+					}
+					workActivityProcess.setId("");
+				}else {
+					process.setCount(11);
+				}
+			}else {
+				if ("yes".equals(flag)) {
+					process.setCount(Integer.parseInt(taskCount) + 1);
+				} else {
+					String returnBack = "";
+					for (Activity activity : activities) {
+						if (activity.getCount() == Integer.parseInt(taskCount)) {
+							returnBack = activity.getReturnBack();
+						}
+					}
+					if (!returnBack.equals("0")) {
+						if (returnBack.equals("1")) {
+							if (!taskCount.equals("1")) {
+								process.setCount(1);
+							}else {
+								process.setCount(1);
+							}
+						} else if (returnBack.equals("2")) {
+							process.setCount(1);
+						} else{
+							process.setCount(1);
+						}
+
+					}
+				}
+			}
+			process.setDelFlag("1");
+			this.delFlag(process);
+			if (workActivityProcess.getCount()==0){
+				workActivityProcess.setDelFlag("0");
+			}
+			this.save(workActivityProcess);
+		}
+	}
+
+	@Transactional(readOnly = false)
+	public void updateType(String processInstanceId ,String type) {
+		dao.updateType(processInstanceId,type);
+	}
+}

+ 176 - 0
src/main/java/com/jeeplus/modules/workadministrativeatamp/entity/WorkAdministrativeAtamp.java

@@ -0,0 +1,176 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workadministrativeatamp.entity;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.modules.sys.entity.Office;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+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;
+
+/**
+ * 行政盖章Entity
+ * @author ssrh
+ * @version 2018-07-10
+ */
+public class WorkAdministrativeAtamp extends ActEntity<WorkAdministrativeAtamp> {
+	
+	private static final long serialVersionUID = 1L;
+    public static final String ATTACHMENT_TYPE = "102";
+    public static final String SERIAL_BIZCODE = "12";
+    private Office office;		// 部门ID
+	private Office company;		// 公司ID
+	private String docType;		// 文档类型
+	private String num;		// 申请编号
+	private Office comSign;		// 签章公司
+	private User submiter;		// 申请人
+	private Date submitDate;		// 申请日期
+	private String sealType;		// 印章类型
+	private Integer state;		// 审批状态
+	private String processInstanceId;		// 流程ID
+    private List<WorkClientAttachment> workAttachments = Lists.newArrayList();
+    private Date beginDate;
+    private Date endDate;
+    private String home;
+	
+	public WorkAdministrativeAtamp() {
+		super();
+	}
+
+	public WorkAdministrativeAtamp(String id){
+		super(id);
+	}
+
+	@ExcelField(title="部门ID", align=2, sort=7)
+	public Office getOffice() {
+		return office;
+	}
+
+	public void setOffice(Office office) {
+		this.office = office;
+	}
+	
+	@ExcelField(title="公司ID", align=2, sort=8)
+	public Office getCompany() {
+		return company;
+	}
+
+	public void setCompany(Office company) {
+		this.company = company;
+	}
+	
+	@ExcelField(title="文档类型", dictType="", align=2, sort=9)
+	public String getDocType() {
+		return docType;
+	}
+
+	public void setDocType(String docType) {
+		this.docType = docType;
+	}
+	
+	@ExcelField(title="申请编号", align=2, sort=10)
+	public String getNum() {
+		return num;
+	}
+
+	public void setNum(String num) {
+		this.num = num;
+	}
+	
+	@NotNull(message="签章公司不能为空")
+	@ExcelField(title="签章公司", fieldType=Office.class, value="", align=2, sort=11)
+	public Office getComSign() {
+		return comSign;
+	}
+
+	public void setComSign(Office comSign) {
+		this.comSign = comSign;
+	}
+
+    public User getSubmiter() {
+        return submiter;
+    }
+
+    public void setSubmiter(User submiter) {
+        this.submiter = submiter;
+    }
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@NotNull(message="申请日期不能为空")
+	@ExcelField(title="申请日期", align=2, sort=13)
+	public Date getSubmitDate() {
+		return submitDate;
+	}
+
+	public void setSubmitDate(Date submitDate) {
+		this.submitDate = submitDate;
+	}
+	
+	@ExcelField(title="印章类型", dictType="", align=2, sort=14)
+	public String getSealType() {
+		return sealType;
+	}
+
+	public void setSealType(String sealType) {
+		this.sealType = sealType;
+	}
+	
+	@ExcelField(title="审批状态", align=2, sort=15)
+	public Integer getState() {
+		return state;
+	}
+
+	public void setState(Integer state) {
+		this.state = state;
+	}
+	
+	@ExcelField(title="流程ID", align=2, sort=16)
+	public String getProcessInstanceId() {
+		return processInstanceId;
+	}
+
+	public void setProcessInstanceId(String processInstanceId) {
+		this.processInstanceId = processInstanceId;
+	}
+
+    public List<WorkClientAttachment> getWorkAttachments() {
+        return workAttachments;
+    }
+
+    public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+        this.workAttachments = workAttachments;
+    }
+
+    public Date getBeginDate() {
+        return beginDate;
+    }
+
+    public void setBeginDate(Date beginDate) {
+        this.beginDate = beginDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getHome() {
+        return home;
+    }
+
+    public void setHome(String home) {
+        this.home = home;
+    }
+}

+ 56 - 0
src/main/java/com/jeeplus/modules/workaftermath/service/WorkAftermathService.java

@@ -0,0 +1,56 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workaftermath.service;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeeplus.modules.workbidingproject.entity.WorkBidingProject;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.workaftermath.entity.WorkAftermath;
+import com.jeeplus.modules.workaftermath.dao.WorkAftermathDao;
+
+/**
+ * 评标后工作管理Service
+ * @author liuw
+ * @version 2017-12-26
+ */
+@Service
+@Transactional(readOnly = true)
+public class WorkAftermathService extends CrudService<WorkAftermathDao, WorkAftermath> {
+
+	public WorkAftermath get(String id) {
+		return super.get(id);
+	}
+	
+	public List<WorkAftermath> findList(WorkAftermath workAftermath) {
+		return super.findList(workAftermath);
+	}
+	
+	public Page<WorkAftermath> findPage(Page<WorkAftermath> page, WorkAftermath workAftermath) {
+		return super.findPage(page, workAftermath);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkAftermath workAftermath) {
+		super.save(workAftermath);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(WorkAftermath workAftermath) {
+		super.delete(workAftermath);
+	}
+	
+	public Page<WorkBidingProject> findPageByworkBidingProject(Page<WorkBidingProject> page, WorkBidingProject workBidingProject) {
+		workBidingProject.setPage(page);
+		page.setList(dao.findListByworkBidingProject(workBidingProject));
+		return page;
+	}
+	
+	
+	
+}

+ 474 - 0
src/main/java/com/jeeplus/modules/workaftermath/web/WorkAftermathController.java

@@ -0,0 +1,474 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workaftermath.web;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.modules.sys.entity.Role;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workaftermath.dao.WorkAftermathDao;
+import com.jeeplus.modules.workbidingproject.dao.WorkBidingProjectDao;
+import com.jeeplus.modules.workbidingproject.service.WorkBidingProjectService;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientInfo;
+import com.jeeplus.modules.workclientinfo.service.WorkClientInfoService;
+import com.jeeplus.modules.workfullmanage.entity.WorkFullManage;
+import com.jeeplus.modules.workfullmanage.entity.WorkFullRecord;
+import com.jeeplus.modules.workfullmanage.service.WorkFullRecordService;
+import com.jeeplus.modules.workproject.dao.WorkProjectDao;
+import com.jeeplus.modules.workproject.entity.WorkProject;
+import com.jeeplus.modules.workproject.service.WorkProjectService;
+import com.jeeplus.modules.workprojectdeposit.dao.WorkProjectDepositDao;
+import com.jeeplus.modules.workprojectdeposit.entity.WorkProjectDeposit;
+import com.jeeplus.modules.workprojectdeposit.service.WorkProjectDepositService;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import com.jeeplus.modules.workreimbursement.utils.VarStr;
+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.workbidingproject.entity.WorkBidingProject;
+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.workaftermath.entity.WorkAftermath;
+import com.jeeplus.modules.workaftermath.service.WorkAftermathService;
+
+/**
+ * 评标后工作管理Controller
+ * @author liuw
+ * @version 2017-12-26
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/workaftermath/workAftermath")
+public class WorkAftermathController extends BaseController {
+
+	@Autowired
+	private WorkAftermathService workAftermathService;
+	@Autowired
+	private WorkBidingProjectService workBidingProjectService;
+	@Autowired
+	private WorkAftermathDao workAftermathDao;
+	@Autowired
+	private WorkProjectDepositDao workProjectDepositDao;
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	@Autowired
+	private WorkBidingProjectDao workBidingProjectDao;
+	@Autowired
+	private WorkFullRecordService workFullRecordService;
+	@Autowired
+	private WorkProjectService workProjectService;
+	@Autowired
+	private WorkProjectDao workProjectDao;
+	@Autowired
+	private WorkClientInfoService workClientInfoService;
+
+
+	@Autowired
+	private WorkProjectDepositService workProjectDepositService;
+	@ModelAttribute
+	public WorkAftermath get(@RequestParam(required=false) String id) {
+		WorkAftermath entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = workAftermathService.get(id);
+		}
+		if (entity == null){
+			entity = new WorkAftermath();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 评标后工作管理列表页面
+	 */
+	//@RequiresPermissions("workaftermath:workAftermath:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(WorkAftermath workAftermath, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<WorkAftermath> page = workAftermathService.findPage(new Page<WorkAftermath>(request, response), workAftermath); 
+		model.addAttribute("page", page);
+		return "modules/workaftermath/workAftermathList";
+	}
+
+	/**
+	 * 查看,增加,编辑评标后工作管理表单页面
+	 */
+	//@RequiresPermissions(value={"workaftermath:workAftermath:view","workaftermath:workAftermath:add","workaftermath:workAftermath:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(WorkAftermath workAftermath, Model model,HttpServletRequest request) {
+		String pid = request.getParameter("pid");
+		if(StringUtils.isBlank(pid)){
+			pid = request.getSession().getAttribute("pid").toString();
+		}
+		WorkAftermath workAftermath2 = workAftermathDao.getBypid(pid);
+		if(workAftermath2!=null&&!workAftermath2.equals("")){
+			workAftermath = workAftermath2;
+		}
+		WorkBidingProject workBidingProject = workBidingProjectService.get(pid);
+		workAftermath.setWorkBidingProject(workBidingProject);
+			StringBuffer sb = new StringBuffer();
+			if(workBidingProject.getProjectMaster()!=null&&!workBidingProject.getProjectMaster().equals("")){
+				String [] a = StringUtils.split(workBidingProject.getProjectMaster(), ",");
+				if(a.length>1){
+					for (String id : StringUtils.split(workBidingProject.getProjectMaster(), ",")){
+						//this.masterList.add(new User(id));
+						String name = UserUtils.get(id).getName();
+						sb.append(name+",");
+					}
+				}else {
+					for (String id : StringUtils.split(workBidingProject.getProjectMaster(), ",")) {
+						//this.masterList.add(new User(id));
+						String name = UserUtils.get(id).getName();
+						sb.append(name);
+					}
+				}
+				workAftermath.setProjectMaster(sb+"");
+			}
+		List<WorkProjectDeposit> list = workProjectDepositService.findByPid(workBidingProject.getId());
+		if(StringUtils.isNotBlank(workBidingProject.getClient().getId())){
+			WorkClientInfo workClientInfo = workClientInfoService.get(workBidingProject.getClient().getId());
+			workAftermath.setWorkClientInfo(workClientInfo);
+		};
+		workAftermath.setList(list);
+		model.addAttribute("workAftermath", workAftermath);
+		request.getSession().getAttribute("pid");
+		return "modules/workaftermath/workAftermathForm";
+	}
+
+	/**
+	 * 保存评标后工作管理
+	 */
+	//@RequiresPermissions(value={"workaftermath:workAftermath:add","workaftermath:workAftermath:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(WorkAftermath workAftermath, Model model, RedirectAttributes redirectAttributes,HttpServletRequest request) throws Exception{
+		if (!beanValidator(model, workAftermath)){
+			return form(workAftermath, model,request);
+		}
+		if(!workAftermath.getIsNewRecord()){//编辑表单保存
+			WorkAftermath t = workAftermathService.get(workAftermath.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(workAftermath, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			workAftermathService.save(t);//保存
+		}else{//新增表单保存
+			workAftermath.setCompanyId(UserUtils.getSelectCompany().getId());
+			workAftermath.setOfficeId(UserUtils.getSelectOffice().getId());
+			WorkBidingProject workBidingProject = workBidingProjectService.get(workAftermath.getWorkBidingProject().getId());
+				StringBuffer sb = new StringBuffer();
+				if(workBidingProject.getProjectMaster()!=null&&!workBidingProject.getProjectMaster().equals("")){
+					for (String id : StringUtils.split(workBidingProject.getProjectMaster(), ",")){
+						String name = UserUtils.get(id).getName();
+						sb.append(name+",");
+					}
+					workAftermath.setProjectMaster(sb+"");
+				}
+			workAftermathService.save(workAftermath);//保存
+		}
+		addMessage(redirectAttributes, "保存评标后工作管理成功");
+		return "redirect:"+Global.getAdminPath()+"/workbidingprojectmg/workBidingProjectmg/list";
+	}
+	
+	/**
+	 * 删除评标后工作管理
+	 */
+	//@RequiresPermissions("workaftermath:workAftermath:del")
+	@RequestMapping(value = "delete")
+	public String delete(WorkAftermath workAftermath, RedirectAttributes redirectAttributes) {
+		workAftermathService.delete(workAftermath);
+		addMessage(redirectAttributes, "删除评标后工作管理成功");
+		return "redirect:"+Global.getAdminPath()+"/workaftermath/workAftermath/?repage";
+	}
+	
+	/**
+	 * 批量删除评标后工作管理
+	 */
+	//@RequiresPermissions("workaftermath:workAftermath:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			workAftermathService.delete(workAftermathService.get(id));
+		}
+		addMessage(redirectAttributes, "删除评标后工作管理成功");
+		return "redirect:"+Global.getAdminPath()+"/workaftermath/workAftermath/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	//@RequiresPermissions("workaftermath:workAftermath:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(WorkAftermath workAftermath, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "评标后工作管理"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<WorkAftermath> page = workAftermathService.findPage(new Page<WorkAftermath>(request, response, -1), workAftermath);
+    		new ExportExcel("评标后工作管理", WorkAftermath.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出评标后工作管理记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/workaftermath/workAftermath/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	//@RequiresPermissions("workaftermath:workAftermath: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<WorkAftermath> list = ei.getDataList(WorkAftermath.class);
+			for (WorkAftermath workAftermath : list){
+				try{
+					workAftermathService.save(workAftermath);
+					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()+"/workaftermath/workAftermath/?repage";
+    }
+	
+	/**
+	 * 下载导入评标后工作管理数据模板
+	 */
+	@RequiresPermissions("workaftermath:workAftermath:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "评标后工作管理数据导入模板.xlsx";
+    		List<WorkAftermath> list = Lists.newArrayList(); 
+    		new ExportExcel("评标后工作管理数据", WorkAftermath.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/workaftermath/workAftermath/?repage";
+    }
+	
+	
+	/**
+	 * 选择招标项目
+	 */
+	@RequestMapping(value = "selectworkBidingProject")
+	public String selectworkBidingProject(WorkBidingProject workBidingProject, String url, String fieldLabels, String fieldKeys, String searchLabel, String searchKey, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<WorkBidingProject> page = workAftermathService.findPageByworkBidingProject(new Page<WorkBidingProject>(request, response),  workBidingProject);
+		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", workBidingProject);
+		model.addAttribute("page", page);
+		return "modules/sys/gridselect";
+	}
+
+	/**
+	 * 确认中标企业
+	 */
+	@RequestMapping(value = "updateBiding")
+	public String updateBiding(WorkProjectDeposit workProjectDeposit,HttpServletRequest request) {
+		workProjectDeposit.setBidingState("1");//1为已中标
+		workProjectDepositDao.updateState(workProjectDeposit);
+		WorkProjectDeposit workProjectDeposit2 = workProjectDepositService.get(workProjectDeposit.getId());
+		request.getSession().setAttribute("pid",workProjectDeposit2.getBidingProject().getId());
+		List<WorkProjectDeposit> list = workProjectDepositService.findByPid(workProjectDeposit2.getBidingProject().getId());
+		list.remove(workProjectDeposit);
+		for (WorkProjectDeposit w:
+			 list) {
+			w.setBidingState("2");//2为未中标
+			workProjectDepositDao.updateState(w);
+		}
+		return "redirect:"+Global.getAdminPath()+"/workaftermath/workAftermath/form";
+	}
+	/**
+	 * 退还保证金
+	 */
+	@RequestMapping(value = "updateStatus")
+	public String updateStatus(WorkProjectDeposit workProjectDeposit,HttpServletRequest request) {
+		workProjectDeposit.setDepositStatus("3");//3为已退还
+		workProjectDepositDao.updateStatus(workProjectDeposit);
+		WorkProjectDeposit workProjectDeposit2 = workProjectDepositService.get(workProjectDeposit.getId());
+		request.getSession().setAttribute("pid",workProjectDeposit2.getBidingProject().getId());
+
+		Role role = UserUtils.getSelectRole().get(0);
+		StringBuffer buffer1 = DateUtils.getByEnnme(role.getEnname());
+		buffer1.append("cw");
+		//发起通知给财务
+		WorkProjectNotify workProjectNotify = new WorkProjectNotify();
+		workProjectNotify.setTitle("保证金退还通知");
+		workProjectNotify.setNotifyId(workProjectDeposit.getId());
+		workProjectNotify.setCompanyId(UserUtils.getSelectCompany().getId());
+		workProjectNotify.setContent("保证金退还");
+		workProjectNotify.setRemarks("待通知");
+		workProjectNotify.setNotifyRole(buffer1.toString());
+		workProjectNotify.setType("29");
+		workProjectNotify.setStatus("0");
+		workProjectNotifyService.save(workProjectNotify);
+		//修改总项目归档状态
+		if(workProjectDeposit2.getBidingProject()!=null){
+			WorkBidingProject workBidingProject = workBidingProjectService.get(workProjectDeposit2.getBidingProject().getId());
+			if(getBidState(workBidingProject)&&getMoneyState(workBidingProject)){
+				WorkProject workProject = workProjectService.get(workBidingProject.getWorkProject().getId());
+				workProject.setState("1");//1为能归档
+				workProjectDao.updateStatus(workProject);
+				//通知
+				StringBuffer buffer = DateUtils.getByEnnme(role.getEnname());
+				buffer.append("glygd");//归档管理员角色
+				WorkProjectNotify workProjectNotifyy = new WorkProjectNotify();
+				workProjectNotifyy.setTitle("招标项目相关业务完成,请归档");
+				workProjectNotifyy.setNotifyId(workBidingProject.getId());
+				workProjectNotifyy.setNotifyRole(buffer.toString());
+				workProjectNotifyy.setCompanyId(workBidingProject.getCompanyId());
+				workProjectNotifyy.setContent(workBidingProject.getProjectName()+"已符合归档条件,请归档!");
+				workProjectNotifyy.setType("30");
+				workProjectNotifyy.setStatus("0");
+				workProjectNotifyy.setRemarks("待通知");
+				workProjectNotifyService.save(workProjectNotifyy);
+			}
+		}
+		return "redirect:"+Global.getAdminPath()+"/workaftermath/workAftermath/form";
+	}
+	/**
+	 * 保存项目归档
+	 */
+	@RequestMapping(value = "startposs")
+	public String startposs(WorkBidingProject workBidingProject, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		WorkFullRecord workFullRecord = new WorkFullRecord();
+		WorkBidingProject workBidingProject1 = workBidingProjectService.get(workBidingProject.getId());
+		workFullRecord.setWorkBidingProject(workBidingProject1);
+		workFullRecord.setRecordNumber(workBidingProject1.getProjectNumber());
+		workFullRecord.setRecordName(workBidingProject1.getProjectName());
+		workFullRecord.setStartTime(workBidingProject.getProjectStartDate());
+		workFullRecord.setEndTime(workBidingProject.getProjectEndDate());
+		model.addAttribute("workFullRecord", workFullRecord);
+		if (StringUtils.isNotBlank(workBidingProject.getName()) && workBidingProject.getName().equals("view")){
+			WorkFullRecord workFullRecord1 = workFullRecordService.findUniqueByProperty("work_full_manage_id", workBidingProject.getId());
+			workFullRecord1.setWorkBidingProject(workBidingProject1);
+			workFullRecord1.setRecordNumber(workBidingProject1.getProjectNumber());
+			workFullRecord1.setRecordName(workBidingProject1.getProjectName());
+			model.addAttribute("workFullRecord", workFullRecord1);
+			return "modules/workaftermath/workRecordView";
+		}
+		return "modules/workaftermath/workRecordForm";
+	}
+	/**
+	 * 项目归档
+	 */
+	@RequestMapping(value = "updateRd")
+	public String updateRd(WorkFullRecord workFullRecord,HttpServletRequest request, RedirectAttributes redirectAttributes) {
+
+		String bid=  workFullRecord.getWorkBidingProject().getId();
+		WorkFullRecord workFullManageId = workFullRecordService.findUniqueByProperty("work_full_manage_id", workFullRecord.getWorkBidingProject().getId());
+		if(workFullManageId != null){
+			addMessage(redirectAttributes, "项目归档已申请,不能重新申请");
+			return "redirect:"+Global.getAdminPath()+"/workbidingprojectrd/workBidingProjectrd/list";
+		}
+		WorkBidingProject workBidingProject = workBidingProjectService.get(bid);
+		if(!getBidState(workBidingProject)){
+			addMessage(redirectAttributes, "项目未定标");
+			return "redirect:"+Global.getAdminPath()+"/workbidingprojectrd/workBidingProjectrd/list";
+		}
+		if(!getMoneyState(workBidingProject)){
+			addMessage(redirectAttributes, "项目相关企业保证金未退还");
+			return "redirect:"+Global.getAdminPath()+"/workbidingprojectrd/workBidingProjectrd/list";
+		}
+		//workFullManageId.preInsert();
+		workFullRecord.setCompanyId(UserUtils.getSelectCompany().getId());
+		WorkFullManage w = new WorkFullManage();
+		w.setId(workBidingProject.getId());
+		workFullRecord.setWorkFullManage(w);
+		workFullRecord.setOfficeId(workBidingProject.getOffice()==null?"":workBidingProject.getOffice().getId());
+		workFullRecord.setType("4");
+		workFullRecord.setBackRecordStatus(VarStr.BACKRECORD_STATUS[1]);
+		workFullRecordService.save(workFullRecord);
+
+
+		//Role r = new Role();
+		//r.setEnname(gly.toString());
+		//Role rolegd =  roleDao.getByEnname(r);
+		//List<User> userList = systemService.findUser(new User(new Role(rolegd.getId())));
+		//workFullManageId.setManageUser(userList==null||userList.size()==0?"":userList.get(0).getId());
+		//workFullRecordService.startposs(workFullManageId,variables,false,"4",buffer.toString());//保存
+
+		workBidingProject.setStatus("3");
+		workBidingProjectDao.updateStatus(workBidingProject);
+		addMessage(redirectAttributes, "项目已归档");
+		return "redirect:"+Global.getAdminPath()+"/workbidingprojectrd/workBidingProjectrd/list";
+	}
+	//确定有中标企业
+	public boolean getBidState(WorkBidingProject workBidingProject){
+		int num = 0;
+		List<WorkProjectDeposit> list= workProjectDepositService.findByPid(workBidingProject.getId());
+		for (WorkProjectDeposit workProjectDeposit:
+				list) {
+			if (workProjectDeposit.getBidingState().equals("1")){
+				num++;
+			}
+		}
+		if(num == 0){
+			return false;
+		}else{
+			return true;
+		}
+	}
+	//确定保证金已退还
+	public boolean getMoneyState(WorkBidingProject workBidingProject){
+		int num = 0;
+		List<WorkProjectDeposit> list= workProjectDepositService.findByPid(workBidingProject.getId());
+		for (WorkProjectDeposit workProjectDeposit:
+				list) {
+			if (!workProjectDeposit.getDepositStatus().equals("3")){
+				num++;
+			}
+		}
+		if(num == 0){
+			return true;
+		}else{
+			return false;
+		}
+	}
+}

+ 72 - 0
src/main/java/com/jeeplus/modules/workaftermath/web/WorkBidingProjectRdController.java

@@ -0,0 +1,72 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workaftermath.web;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.sys.entity.Role;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workbidingproject.entity.WorkBidingProject;
+import com.jeeplus.modules.workbidingproject.service.WorkBidingProjectService;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 招标项目Controller
+ * @author
+ * @version
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/workbidingprojectrd/workBidingProjectrd")
+public class WorkBidingProjectRdController extends BaseController {
+
+	@Autowired
+	private WorkBidingProjectService workBidingProjectService;
+
+	@ModelAttribute
+	public WorkBidingProject get(@RequestParam(required=false) String id) {
+		WorkBidingProject entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = workBidingProjectService.get(id);
+		}
+		if (entity == null){
+			entity = new WorkBidingProject();
+		}
+		return entity;
+	}
+
+	/**
+	 * 招标项目信息列表页面
+	 */
+	@RequiresPermissions("workbidingprojectrd:workBidingProjectrd:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(WorkBidingProject workBidingProject, HttpServletRequest request, HttpServletResponse response, Model model) {
+		if(!UserUtils.getSelectRoleInfo()){
+			String id = UserUtils.getUser().getId();
+			workBidingProject.setQueryCon(id);
+		}
+		Page<WorkBidingProject> page = workBidingProjectService.findPage(new Page<WorkBidingProject>(request, response), workBidingProject);
+		model.addAttribute("page", page);
+		return "modules/workaftermath/workBidingProjectRdList";
+	}
+
+	/**
+	 * 查看,增加,编辑招标项目信息表单页面
+	 */
+	//@RequiresPermissions(value={"workbidingproject:workBidingProject:view","workbidingproject:workBidingProject:add","workbidingproject:workBidingProject:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(WorkBidingProject workBidingProject, Model model) {
+		model.addAttribute("workBidingProject", workBidingProject);
+		return "modules/workbidingproject/workBidingProjectForm";
+	}
+}

+ 64 - 0
src/main/java/com/jeeplus/modules/workapprovalcopy/service/ApprovalCopyService.java

@@ -0,0 +1,64 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workapprovalcopy.service;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.workapprovalcopy.dao.ApprovalCopyDao;
+import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * 抄送信息Service
+ * @author yangfan
+ * @version 2017-07-21
+ */
+@Service
+@Transactional(readOnly = true)
+public class ApprovalCopyService extends CrudService<ApprovalCopyDao, ApprovalCopy> {
+	@Autowired
+	private ApprovalCopyDao approvalCopyDao;
+
+	public ApprovalCopy get(String id) {
+		return super.get(id);
+	}
+
+	public ApprovalCopy getByApprovalId(String approvalId){return approvalCopyDao.getByApprovalId(approvalId);}
+	
+	public List<ApprovalCopy> findList(ApprovalCopy approvalCopy) {
+		return super.findList(approvalCopy);
+	}
+
+    public Page<ApprovalCopy> find(Page<ApprovalCopy> page, ApprovalCopy approvalCopy) {
+        approvalCopy.setPage(page);
+        page.setList(dao.findList(approvalCopy));
+        return page;
+    }
+
+	public Page<ApprovalCopy> findPage(Page<ApprovalCopy> page, ApprovalCopy approvalCopy) {
+		return super.findPage(page, approvalCopy);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(ApprovalCopy approvalCopy) {
+		super.save(approvalCopy);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(ApprovalCopy approvalCopy) {
+		super.delete(approvalCopy);
+	}
+	@Transactional(readOnly = false)
+	public void deletes(ApprovalCopy approvalCopy) {
+		dao.deletes(approvalCopy);
+	}
+
+	
+	
+	
+}

+ 20 - 0
src/main/java/com/jeeplus/modules/workattendance/dao/WorkAttendanceRuleDao.java

@@ -0,0 +1,20 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workattendance.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.workattendance.entity.WorkAttendanceRule;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 考勤规则DAO接口
+ * @author 杨帆
+ * @version 2018-09-05
+ */
+@MyBatisDao
+public interface WorkAttendanceRuleDao extends CrudDao<WorkAttendanceRule> {
+    WorkAttendanceRule findAttendanceRuleByCompany(@Param("companyId")String companyId,@Param("userId")String userId,@Param("officeId")String officeId);
+
+}

+ 338 - 0
src/main/java/com/jeeplus/modules/workattendance/entity/WorkAttendanceRule.java

@@ -0,0 +1,338 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workattendance.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.Collections3;
+import com.jeeplus.common.utils.IdGen;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.sys.entity.Area;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * 考勤规则Entity
+ * @author 杨帆
+ * @version 2018-09-05
+ */
+public class WorkAttendanceRule extends DataEntity<WorkAttendanceRule> {
+	
+	private static final long serialVersionUID = 1L;
+	private String companyId;		// 公司
+	private Office branchOffice;		// 分公司
+	private String branchOfficeId;		// 分公司
+	private String type;		// 考勤方式(签到,打卡,不考勤)
+	@DateTimeFormat(pattern = "HH:mm:ss")
+	private Date startTime;		// 上班时间
+	@DateTimeFormat(pattern = "HH:mm:ss")
+	private Date endTime;		// 下班时间
+	private String workCount;		// 工作日计算加班/不计算加班
+	private String workNeed;		// 工作日需要加班/需要算加班
+	private String workType;		// 工作日处理方式 计算调休/发放工资
+	@DateTimeFormat(pattern = "HH:mm:ss")
+	private Date workStartTime;		// 上班时间
+	@DateTimeFormat(pattern = "HH:mm:ss")
+	private Date workEndTime;		// 下班时间
+	private String notWorkCount;		// 非工作日计算加班/不计算加班
+	private String notWorkNeed;		// 非工作日需要加班/需要算加班
+	private String notWorkType;		// 非工作日处理方式 计算调休/发放工资
+	private String leaveType;		// 调休请假类型
+	private String leaveTypeName;		//调休请假类型
+	private String name;		// 名称
+	private String number;     //规则编号
+	private List<WorkAttendancePlace> workAttendancePlaces;//考勤地点/wifi集合
+	private List<User> userList;
+	private List<Office> officeList;
+	private List<WorkAttendanceRuleRecord> workAttendanceRuleRecordList = Lists.newArrayList();
+	private List<WorkAttendanceRuleRecord> workAttendanceRuleRecordOfficeList = Lists.newArrayList();
+	private Area area;
+	private String view;
+	
+	public WorkAttendanceRule() {
+		super();
+	}
+
+	public WorkAttendanceRule(String id){
+		super(id);
+	}
+
+	@ExcelField(title="公司", align=2, sort=1)
+	public String getCompanyId() {
+		return companyId;
+	}
+
+	public void setCompanyId(String companyId) {
+		this.companyId = companyId;
+	}
+	
+	@ExcelField(title="分公司", align=2, sort=2)
+	public Office getBranchOffice() {
+		return branchOffice;
+	}
+
+	public void setBranchOffice(Office branchOffice) {
+		this.branchOffice = branchOffice;
+	}
+	
+	@ExcelField(title="考勤方式(签到,打卡,不考勤)", align=2, sort=3)
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	@JsonFormat(pattern = "HH:mm:ss")
+	@ExcelField(title="上班时间", align=2, sort=4)
+	public Date getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(Date startTime) {
+		this.startTime = startTime;
+	}
+	
+	@JsonFormat(pattern = "HH:mm:ss")
+	@ExcelField(title="下班时间", align=2, sort=5)
+	public Date getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(Date endTime) {
+		this.endTime = endTime;
+	}
+	
+	@ExcelField(title="工作日计算加班/不计算加班", align=2, sort=6)
+	public String getWorkCount() {
+		return workCount;
+	}
+
+	public void setWorkCount(String workCount) {
+		this.workCount = workCount;
+	}
+	
+	@ExcelField(title="工作日需要加班/需要算加班", align=2, sort=7)
+	public String getWorkNeed() {
+		return workNeed;
+	}
+
+	public void setWorkNeed(String workNeed) {
+		this.workNeed = workNeed;
+	}
+	
+	@ExcelField(title="工作日处理方式 计算调休/发放工资", align=2, sort=8)
+	public String getWorkType() {
+		return workType;
+	}
+
+	public void setWorkType(String workType) {
+		this.workType = workType;
+	}
+	
+	@JsonFormat(pattern = "HH:mm:ss")
+	@ExcelField(title="上班时间", align=2, sort=9)
+	public Date getWorkStartTime() {
+		return workStartTime;
+	}
+
+	public void setWorkStartTime(Date workStartTime) {
+		this.workStartTime = workStartTime;
+	}
+	
+	@JsonFormat(pattern = "HH:mm:ss")
+	@ExcelField(title="下班时间", align=2, sort=10)
+	public Date getWorkEndTime() {
+		return workEndTime;
+	}
+
+	public void setWorkEndTime(Date workEndTime) {
+		this.workEndTime = workEndTime;
+	}
+	
+	@ExcelField(title="非工作日计算加班/不计算加班", align=2, sort=11)
+	public String getNotWorkCount() {
+		return notWorkCount;
+	}
+
+	public void setNotWorkCount(String notWorkCount) {
+		this.notWorkCount = notWorkCount;
+	}
+	
+	@ExcelField(title="非工作日需要加班/需要算加班", align=2, sort=12)
+	public String getNotWorkNeed() {
+		return notWorkNeed;
+	}
+
+	public void setNotWorkNeed(String notWorkNeed) {
+		this.notWorkNeed = notWorkNeed;
+	}
+	
+	@ExcelField(title="非工作日处理方式 计算调休/发放工资", align=2, sort=13)
+	public String getNotWorkType() {
+		return notWorkType;
+	}
+
+	public void setNotWorkType(String notWorkType) {
+		this.notWorkType = notWorkType;
+	}
+	
+	@ExcelField(title="名称", align=2, sort=20)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<WorkAttendancePlace> getWorkAttendancePlaces() {
+		return workAttendancePlaces;
+	}
+
+	public void setWorkAttendancePlaces(List<WorkAttendancePlace> workAttendancePlaces) {
+		this.workAttendancePlaces = workAttendancePlaces;
+	}
+
+	public String getNumber() {
+		return number;
+	}
+
+	public void setNumber(String number) {
+		this.number = number;
+	}
+
+	/**
+	 * 获取通知发送记录用户ID
+	 * @return
+	 */
+	public String getworkAttendanceRuleRecordIds() {
+		return Collections3.extractToString(workAttendanceRuleRecordList, "user.id", ",") ;
+	}
+
+	/**
+	 * 设置通知发送记录用户ID
+	 * @return
+	 */
+	public void setworkAttendanceRuleRecordIds(List<User> users) {
+		this.workAttendanceRuleRecordList = Lists.newArrayList();
+		if (users!=null && users.size()!=0) {
+			for (User user : users) {
+				if (user.getDelFlag().equals("0")) {
+					WorkAttendanceRuleRecord entity = new WorkAttendanceRuleRecord();
+					entity.setId(IdGen.uuid());
+					entity.setWorkAttendanceRule(this);
+					entity.setUser(user);
+					this.workAttendanceRuleRecordList.add(entity);
+				}
+			}
+		}
+	}
+	/**
+	 * 设置通知发送记录用户ID
+	 * @return
+	 */
+	public void setworkAttendanceRuleRecordOffices(List<Office> offices) {
+		this.workAttendanceRuleRecordOfficeList = Lists.newArrayList();
+		if (offices!=null && offices.size()!=0) {
+			for (Office office : offices) {
+				if (office.getDelFlag().equals("0")) {
+					WorkAttendanceRuleRecord entity = new WorkAttendanceRuleRecord();
+					entity.setId(IdGen.uuid());
+					entity.setWorkAttendanceRule(this);
+					entity.setOfficeId(office.getId());
+					this.workAttendanceRuleRecordOfficeList.add(entity);
+				}
+			}
+		}
+	}
+
+	/**
+	 * 获取通知发送记录用户Name
+	 * @return
+	 */
+	public String getworkAttendanceRuleRecordNames() {
+		return Collections3.extractToString(workAttendanceRuleRecordList, "user.name", ",") ;
+	}
+
+	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<WorkAttendanceRuleRecord> getWorkAttendanceRuleRecordList() {
+		return workAttendanceRuleRecordList;
+	}
+
+	public void setWorkAttendanceRuleRecordOfficeList(List<WorkAttendanceRuleRecord> workAttendanceRuleRecordOfficeList) {
+		this.workAttendanceRuleRecordOfficeList = workAttendanceRuleRecordOfficeList;
+	}
+
+	public void setWorkAttendanceRuleRecordList(List<WorkAttendanceRuleRecord> workAttendanceRuleRecordList) {
+		this.workAttendanceRuleRecordList = workAttendanceRuleRecordList;
+	}
+
+	public List<WorkAttendanceRuleRecord> getWorkAttendanceRuleRecordOfficeList() {
+		return workAttendanceRuleRecordOfficeList;
+	}
+
+    public Area getArea() {
+        return area;
+    }
+
+    public void setArea(Area area) {
+        this.area = area;
+    }
+
+	public String getBranchOfficeId() {
+		return branchOfficeId;
+	}
+
+	public void setBranchOfficeId(String branchOfficeId) {
+		this.branchOfficeId = branchOfficeId;
+	}
+
+	public String getView() {
+		return view;
+	}
+
+	public void setView(String view) {
+		this.view = view;
+	}
+
+	public String getLeaveType() {
+		return leaveType;
+	}
+
+	public void setLeaveType(String leaveType) {
+		this.leaveType = leaveType;
+	}
+
+	public String getLeaveTypeName() {
+		return leaveTypeName;
+	}
+
+	public void setLeaveTypeName(String leaveTypeName) {
+		this.leaveTypeName = leaveTypeName;
+	}
+}

+ 124 - 0
src/main/java/com/jeeplus/modules/workattendance/service/WorkAttendanceCountService.java

@@ -0,0 +1,124 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workattendance.service;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+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.utils.UserUtils;
+import com.jeeplus.modules.workattendance.dao.WorkAttendanceInfoDao;
+import com.jeeplus.modules.workattendance.dao.WorkAttendanceMonthDao;
+import com.jeeplus.modules.workattendance.entity.WorkAttendanceInfo;
+import com.jeeplus.modules.workattendance.entity.WorkAttendanceMonth;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import com.jeeplus.modules.workstaff.entity.WorkStaffBasicInfo;
+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.workattendance.entity.WorkAttendanceCount;
+import com.jeeplus.modules.workattendance.dao.WorkAttendanceCountDao;
+
+/**
+ * 考勤统计Service
+ * @author 杨帆
+ * @version 2018-09-14
+ */
+@Service
+@Transactional(readOnly = true)
+public class WorkAttendanceCountService extends CrudService<WorkAttendanceCountDao, WorkAttendanceCount> {
+	@Autowired
+	private WorkAttendanceMonthDao workAttendanceMonthDao;
+	@Autowired
+	private WorkAttendanceInfoDao workAttendanceInfoDao;
+	@Autowired
+	private WorkProjectNotifyService workProjectNotifyService;
+	public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+	public WorkAttendanceCount get(String id) {
+		WorkAttendanceCount workAttendanceCount = super.get(id);
+		WorkAttendanceMonth workAttendanceMonth = new WorkAttendanceMonth();
+		workAttendanceMonth.setAttendanceMonth(workAttendanceCount.getAttendanceMonth());
+		workAttendanceMonth.setOffice(workAttendanceCount.getOffice());
+		List<WorkAttendanceMonth> workAttendanceMonths = workAttendanceMonthDao.findList(workAttendanceMonth);
+		if (workAttendanceMonths!=null && workAttendanceMonths.size()!=0){
+			workAttendanceCount.setWorkAttendanceMonths(workAttendanceMonths);
+		}
+		return workAttendanceCount;
+	}
+	
+	public List<WorkAttendanceCount> findList(WorkAttendanceCount workAttendanceCount) {
+		return super.findList(workAttendanceCount);
+	}
+	public List<WorkAttendanceCount> findListByMonth(WorkAttendanceCount workAttendanceCount) {
+		return dao.findListByMonth(workAttendanceCount);
+	}
+
+	public List<WorkAttendanceCount> groupByOfficeList(WorkStaffBasicInfo workStaffBasicInfo) {
+		return dao.groupByOfficeList(workStaffBasicInfo);
+	}
+
+	public Page<WorkAttendanceCount> findPage(Page<WorkAttendanceCount> page, WorkAttendanceCount workAttendanceCount) {
+		return super.findPage(page, workAttendanceCount);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkAttendanceCount workAttendanceCount) {
+		workAttendanceCount.setStatus("0");
+		workAttendanceCount.setUser(UserUtils.getUser());
+		workAttendanceCount.setAttendanceDate(new Date());
+		WorkProjectNotify workProjectNotify = new WorkProjectNotify();
+		workProjectNotify.setNotifyId(workAttendanceCount.getId());
+		workProjectNotifyService.readByNotifyId(workProjectNotify);
+		super.save(workAttendanceCount);
+	}
+	@Transactional(readOnly = false)
+	public void store(WorkAttendanceCount workAttendanceCount) throws ParseException {
+		Calendar now = Calendar.getInstance();
+		String day = UserUtils.getSysParamByCompany("attendance_date",workAttendanceCount.getCompanyId());
+		String firstDay = StringUtils.firstDay("", day, workAttendanceCount.getCompanyId());
+		String lastDay = StringUtils.lastDay("", day, workAttendanceCount.getCompanyId());
+		WorkAttendanceInfo workAttendanceInfo = new WorkAttendanceInfo();
+		try {
+			workAttendanceInfo.setStartDate(format.parse(firstDay));
+			workAttendanceInfo.setEndDate(format.parse(lastDay));
+			workAttendanceInfo.setCompanyId(workAttendanceCount.getCompanyId());
+			workAttendanceInfo.setOffice(workAttendanceCount.getOffice());
+		} catch (ParseException e) {
+			logger.info("ParseException e" + e);
+		}
+		List<WorkAttendanceMonth> WorkAttendanceMonths = workAttendanceInfoDao.findListByTime(workAttendanceInfo);
+		String month = lastDay.substring(0, 7);
+		WorkAttendanceMonth attendanceMonth = new WorkAttendanceMonth();
+		attendanceMonth.setAttendanceMonth(month);
+		attendanceMonth.setOffice(workAttendanceCount.getOffice());
+		attendanceMonth.setCompanyId(workAttendanceCount.getCompanyId());
+		workAttendanceMonthDao.deleteByMonth(attendanceMonth);
+		for (WorkAttendanceMonth workAttendanceMonth : WorkAttendanceMonths) {
+			workAttendanceMonth.setAttendanceMonth(month);
+			workAttendanceMonth.preInsert();
+			workAttendanceMonth.setUpdateBy(new User("1"));
+			workAttendanceMonth.setCreateBy(new User("1"));
+			workAttendanceMonthDao.insert(workAttendanceMonth);
+		}
+	}
+
+	@Transactional(readOnly = false)
+	public void delete(WorkAttendanceCount workAttendanceCount) {
+		super.delete(workAttendanceCount);
+	}
+	
+	
+	
+	
+}

+ 226 - 0
src/main/java/com/jeeplus/modules/workattendance/web/WorkAttendanceInfoController.java

@@ -0,0 +1,226 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workattendance.web;
+
+import java.text.ParseException;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+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.workattendance.entity.WorkAttendanceInfo;
+import com.jeeplus.modules.workattendance.service.WorkAttendanceInfoService;
+
+/**
+ * 考勤详情Controller
+ * @author 杨帆
+ * @version 2018-09-10
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/workattendance/workAttendanceInfo")
+public class WorkAttendanceInfoController extends BaseController {
+
+	@Autowired
+	private WorkAttendanceInfoService workAttendanceInfoService;
+	
+	@ModelAttribute
+	public WorkAttendanceInfo get(@RequestParam(required=false) String id) {
+		WorkAttendanceInfo entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = workAttendanceInfoService.get(id);
+		}
+		if (entity == null){
+			entity = new WorkAttendanceInfo();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 考勤详情列表页面
+	 */
+	@RequiresPermissions("workattendance:workAttendanceInfo:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(WorkAttendanceInfo workAttendanceInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<WorkAttendanceInfo> page = workAttendanceInfoService.findPage(new Page<WorkAttendanceInfo>(request, response), workAttendanceInfo); 
+		model.addAttribute("page", page);
+		return "modules/workattendance/workAttendanceInfoList";
+	}
+
+	/**
+	 * 查看,增加,编辑考勤详情表单页面
+	 */
+	//@RequiresPermissions(value={"workattendance:workAttendanceInfo:view","workattendance:workAttendanceInfo:add","workattendance:workAttendanceInfo:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(WorkAttendanceInfo workAttendanceInfo, Model model) {
+		model.addAttribute("workAttendanceInfo", workAttendanceInfo);
+		if (StringUtils.isNotBlank(workAttendanceInfo.getHome())){
+			return "modules/workattendance/workAttendanceInfoEdit";
+		}else {
+			return "modules/workattendance/workAttendanceInfoForm";
+		}
+	}
+	/**
+	 * 查看,增加,编辑考勤详情表单页面
+	 */
+	@RequestMapping(value = "view")
+	public String view(WorkAttendanceInfo workAttendanceInfo, Model model) {
+		List<WorkAttendanceInfo> attendanceInfos = workAttendanceInfoService.findLists(workAttendanceInfo);
+		model.addAttribute("workAttendanceInfos", attendanceInfos);
+		model.addAttribute("home", workAttendanceInfo.getHome());
+		return "modules/workattendance/workAttendanceInfoView";
+	}
+
+	/**
+	 * 保存考勤规则
+	 */
+	@RequestMapping(value = "saveAudit")
+	public String saveAudit(WorkAttendanceInfo workAttendanceInfo, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) throws Exception{
+		workAttendanceInfoService.saveAudit(workAttendanceInfo.getId(),workAttendanceInfo.getIds(),workAttendanceInfo.getFlag());//保存
+		addMessage(redirectAttributes, "审批成功");
+		if (StringUtils.isNotBlank(workAttendanceInfo.getHome()) && "home".equals(workAttendanceInfo.getHome())){
+			return "redirect:" + Global.getAdminPath() + "/home/?repage";
+		}else {
+			return "redirect:"+Global.getAdminPath()+"/workattendance/workAttendanceRule/?repage";
+		}
+	}
+
+	/**
+	 * 保存考勤详情
+	 */
+	//@RequiresPermissions(value={"workattendance:workAttendanceInfo:add","workattendance:workAttendanceInfo:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(WorkAttendanceInfo workAttendanceInfo, Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, workAttendanceInfo)){
+			return form(workAttendanceInfo, model);
+		}
+		if(!workAttendanceInfo.getIsNewRecord()){//编辑表单保存
+			WorkAttendanceInfo t = workAttendanceInfoService.get(workAttendanceInfo.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(workAttendanceInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			workAttendanceInfoService.save(t);//保存
+		}else{//新增表单保存
+			workAttendanceInfoService.save(workAttendanceInfo);//保存
+		}
+		addMessage(redirectAttributes, "保存考勤详情成功");
+		return "redirect:"+Global.getAdminPath()+"/workattendance/workAttendanceInfo/?repage";
+	}
+	
+	/**
+	 * 删除考勤详情
+	 */
+	@RequiresPermissions("workattendance:workAttendanceInfo:del")
+	@RequestMapping(value = "delete")
+	public String delete(WorkAttendanceInfo workAttendanceInfo, RedirectAttributes redirectAttributes) {
+		workAttendanceInfoService.delete(workAttendanceInfo);
+		addMessage(redirectAttributes, "删除考勤详情成功");
+		return "redirect:"+Global.getAdminPath()+"/workattendance/workAttendanceInfo/?repage";
+	}
+	
+	/**
+	 * 批量删除考勤详情
+	 */
+	@RequiresPermissions("workattendance:workAttendanceInfo:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			workAttendanceInfoService.delete(workAttendanceInfoService.get(id));
+		}
+		addMessage(redirectAttributes, "删除考勤详情成功");
+		return "redirect:"+Global.getAdminPath()+"/workattendance/workAttendanceInfo/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+	@RequiresPermissions("workattendance:workAttendanceInfo:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(WorkAttendanceInfo workAttendanceInfo, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "考勤详情"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<WorkAttendanceInfo> page = workAttendanceInfoService.findPage(new Page<WorkAttendanceInfo>(request, response, -1), workAttendanceInfo);
+    		new ExportExcel("考勤详情", WorkAttendanceInfo.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出考勤详情记录失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/workattendance/workAttendanceInfo/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+	@RequiresPermissions("workattendance:workAttendanceInfo: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<WorkAttendanceInfo> list = ei.getDataList(WorkAttendanceInfo.class);
+			for (WorkAttendanceInfo workAttendanceInfo : list){
+				try{
+					workAttendanceInfoService.save(workAttendanceInfo);
+					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()+"/workattendance/workAttendanceInfo/?repage";
+    }
+	
+	/**
+	 * 下载导入考勤详情数据模板
+	 */
+	@RequiresPermissions("workattendance:workAttendanceInfo:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "考勤详情数据导入模板.xlsx";
+    		List<WorkAttendanceInfo> list = Lists.newArrayList(); 
+    		new ExportExcel("考勤详情数据", WorkAttendanceInfo.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/workattendance/workAttendanceInfo/?repage";
+    }
+	
+	
+	
+
+}

+ 20 - 0
src/main/java/com/jeeplus/modules/workborrowmangement/dao/WorkBorrowBackDao.java

@@ -0,0 +1,20 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workborrowmangement.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.workborrowmangement.entity.WorkBorrowBack;
+import com.jeeplus.modules.workborrowmangement.entity.WorkBorrowMangement;
+
+/**
+ * 归还DAO接口
+ * @author chenyuping
+ * @version 2018-07-13
+ */
+@MyBatisDao
+public interface WorkBorrowBackDao extends CrudDao<WorkBorrowBack> {
+    void updateProcessIdAndStatus(WorkBorrowBack workBorrowBack);
+	
+}

+ 63 - 0
src/main/java/com/jeeplus/modules/workclientinfo/entity/WorkClientBank.java

@@ -0,0 +1,63 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workclientinfo.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+import javax.validation.constraints.Size;
+
+/**
+ * 客户开行信息Entity
+ * @author mapengbo
+ * @version 2017-10-11
+ */
+public class WorkClientBank extends DataEntity<WorkClientBank> {
+	
+	private static final long serialVersionUID = 1L;
+	private String ourBank;		// 开户银行
+    @Size(min = 16,max = 19,message = "银行账号长度应为16-19位")
+	private String bankNumber;		// 开户账号
+    private WorkClientInfo clientId;		// 外键关联客户表 父类
+	
+	public WorkClientBank() {
+		super();
+	}
+
+	public WorkClientBank(String id){
+		super(id);
+	}
+
+    public WorkClientBank(WorkClientInfo clientId){
+        this.clientId = clientId;
+    }
+
+	@ExcelField(title="开户银行", align=2, sort=7)
+	public String getOurBank() {
+		return ourBank;
+	}
+
+	public void setOurBank(String ourBank) {
+		this.ourBank = ourBank;
+	}
+	
+	@ExcelField(title="开户账号", align=2, sort=8)
+	public String getBankNumber() {
+		return bankNumber;
+	}
+
+	public void setBankNumber(String bankNumber) {
+		this.bankNumber = bankNumber;
+	}
+
+    public WorkClientInfo getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(WorkClientInfo clientId) {
+        this.clientId = clientId;
+    }
+	
+}

+ 139 - 0
src/main/java/com/jeeplus/modules/workclientinfo/entity/WorkClientLinkman.java

@@ -0,0 +1,139 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workclientinfo.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+
+import java.util.List;
+
+/**
+ * 客户管理Entity
+ * @author 丁旭
+ * @version 2017-03-20
+ */
+public class WorkClientLinkman extends DataEntity<WorkClientLinkman> {
+	
+	private static final long serialVersionUID = 1L;
+	private String office ;   //部门
+	private String name;		// 联系人姓名
+	private String position;		// 职务
+	private String qq;		// QQ
+	private String linkPhone;		// 联系人电话
+	private String linkMobile;		// 联系人手机
+	private String email;		// E-mail
+	private String isDefault;		// 是否默认联系人
+	private WorkClientInfo clientId;		// 外键关联客户表 父类
+	private String projectId;		// 外键关联工程表(资格预审)
+	private List<String> clientIds;
+	public WorkClientLinkman() {
+		super();
+	}
+
+	public WorkClientLinkman(String id){
+		super(id);
+	}
+
+	public WorkClientLinkman(WorkClientInfo clientId){
+		this.clientId = clientId;
+	}
+
+	
+	
+	@ExcelField(title="联系人姓名", align=2, sort=1)
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@ExcelField(title="职务", align=2, sort=2)
+	public String getPosition() {
+		return position;
+	}
+
+	public void setPosition(String position) {
+		this.position = position;
+	}
+	
+	@ExcelField(title="QQ", align=2, sort=3)
+	public String getQq() {
+		return qq;
+	}
+
+	public void setQq(String qq) {
+		this.qq = qq;
+	}
+	
+	@ExcelField(title="联系人电话", align=2, sort=4)
+	public String getLinkPhone() {
+		return linkPhone;
+	}
+
+	public void setLinkPhone(String linkPhone) {
+		this.linkPhone = linkPhone;
+	}
+	
+	@ExcelField(title="联系人手机", align=2, sort=5)
+	public String getLinkMobile() {
+		return linkMobile;
+	}
+
+	public void setLinkMobile(String linkMobile) {
+		this.linkMobile = linkMobile;
+	}
+	
+	@ExcelField(title="E-mail", align=2, sort=6)
+	public String getEmail() {
+		return email;
+	}
+
+	public void setEmail(String email) {
+		this.email = email;
+	}
+	
+	@ExcelField(title="是否默认联系人", align=2, sort=7)
+	public String getIsDefault() {
+		return isDefault;
+	}
+
+	public void setIsDefault(String isDefault) {
+		this.isDefault = isDefault;
+	}
+	
+	public WorkClientInfo getClientId() {
+		return clientId;
+	}
+
+	public void setClientId(WorkClientInfo clientId) {
+		this.clientId = clientId;
+	}
+
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+
+	public String getOffice() {
+		return office;
+	}
+
+	public void setOffice(String office) {
+		this.office = office;
+	}
+
+    public List<String> getClientIds() {
+        return clientIds;
+    }
+
+    public void setClientIds(List<String> clientIds) {
+        this.clientIds = clientIds;
+    }
+}

+ 121 - 0
src/main/java/com/jeeplus/modules/workcontent/entity/WorkContentBudget.java

@@ -0,0 +1,121 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workcontent.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import org.springframework.format.annotation.NumberFormat;
+
+/**
+ * 结算编审Entity
+ * @author ssrh
+ * @version 2018-06-06
+ */
+public class WorkContentBudget extends DataEntity<WorkContentBudget> {
+	
+	private static final long serialVersionUID = 1L;
+	private String projectId;		// 项目id
+	private String contentId;		// 工作内容ID
+	private String budgetNum;		// 编号
+	private String costName;		// 工程费用名称
+    @NumberFormat(style = NumberFormat.Style.CURRENCY)
+	private Double reviewAmt;		// 送审金额
+    @NumberFormat(style = NumberFormat.Style.CURRENCY)
+	private Double setAmt;		// 定审金额
+    @NumberFormat(style = NumberFormat.Style.CURRENCY)
+	private Double floatAmt;		// 审增减金额
+	private String floatReason;		// 审增减原因
+	private String nodeTypes;		// 节点类型
+	
+	public WorkContentBudget() {
+		super();
+	}
+
+	public WorkContentBudget(String id){
+		super(id);
+	}
+
+	@ExcelField(title="项目id", align=2, sort=7)
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+	
+	@ExcelField(title="工作内容ID", align=2, sort=8)
+	public String getContentId() {
+		return contentId;
+	}
+
+	public void setContentId(String contentId) {
+		this.contentId = contentId;
+	}
+	
+	@ExcelField(title="编号", align=2, sort=9)
+	public String getBudgetNum() {
+		return budgetNum;
+	}
+
+	public void setBudgetNum(String budgetNum) {
+		this.budgetNum = budgetNum;
+	}
+	
+	@ExcelField(title="工程费用名称", align=2, sort=10)
+	public String getCostName() {
+		return costName;
+	}
+
+	public void setCostName(String costName) {
+		this.costName = costName;
+	}
+	
+	@ExcelField(title="送审金额", align=2, sort=11)
+	public Double getReviewAmt() {
+		return reviewAmt;
+	}
+
+	public void setReviewAmt(Double reviewAmt) {
+		this.reviewAmt = reviewAmt;
+	}
+	
+	@ExcelField(title="定审金额", align=2, sort=12)
+	public Double getSetAmt() {
+		return setAmt;
+	}
+
+	public void setSetAmt(Double setAmt) {
+		this.setAmt = setAmt;
+	}
+	
+	@ExcelField(title="审增减金额", align=2, sort=13)
+	public Double getFloatAmt() {
+		return floatAmt;
+	}
+
+	public void setFloatAmt(Double floatAmt) {
+		this.floatAmt = floatAmt;
+	}
+	
+	@ExcelField(title="审增减原因", align=2, sort=14)
+	public String getFloatReason() {
+		return floatReason;
+	}
+
+	public void setFloatReason(String floatReason) {
+		this.floatReason = floatReason;
+	}
+	
+	@ExcelField(title="节点类型", align=2, sort=15)
+	public String getNodeTypes() {
+		return nodeTypes;
+	}
+
+	public void setNodeTypes(String nodeTypes) {
+		this.nodeTypes = nodeTypes;
+	}
+	
+}

+ 117 - 0
src/main/java/com/jeeplus/modules/workcontent/entity/WorkContentContprogram.java

@@ -0,0 +1,117 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workcontent.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.projectcontentinfo.entity.ProjectContentData;
+
+/**
+ * 合约规划Entity
+ * @author ssrh
+ * @version 2018-06-06
+ */
+public class WorkContentContprogram extends DataEntity<WorkContentContprogram> {
+	
+	private static final long serialVersionUID = 1L;
+	private String projectId;		// 项目id
+	private String contentId;		// 工作内容ID
+	private String contCate;		// 合同分类
+	private String contAttr;		// 合同属性
+	private String priceType;		// 合同价格类型
+	private String bidType;		// 招标方式
+	private ProjectContentData otherProgram;		// 与其他合同关系
+	private String scope;		// 合同范围
+	private String inteface;		// 界面的处理
+	
+	public WorkContentContprogram() {
+		super();
+	}
+
+	public WorkContentContprogram(String id){
+		super(id);
+	}
+
+	@ExcelField(title="项目id", align=2, sort=7)
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+	
+	@ExcelField(title="工作内容ID", align=2, sort=8)
+	public String getContentId() {
+		return contentId;
+	}
+
+	public void setContentId(String contentId) {
+		this.contentId = contentId;
+	}
+	
+	@ExcelField(title="合同分类", dictType="", align=2, sort=9)
+	public String getContCate() {
+		return contCate;
+	}
+
+	public void setContCate(String contCate) {
+		this.contCate = contCate;
+	}
+	
+	@ExcelField(title="合同属性", dictType="", align=2, sort=10)
+	public String getContAttr() {
+		return contAttr;
+	}
+
+	public void setContAttr(String contAttr) {
+		this.contAttr = contAttr;
+	}
+	
+	@ExcelField(title="合同价格类型", dictType="", align=2, sort=11)
+	public String getPriceType() {
+		return priceType;
+	}
+
+	public void setPriceType(String priceType) {
+		this.priceType = priceType;
+	}
+	
+	@ExcelField(title="招标方式", dictType="", align=2, sort=12)
+	public String getBidType() {
+		return bidType;
+	}
+
+	public void setBidType(String bidType) {
+		this.bidType = bidType;
+	}
+
+    public ProjectContentData getOtherProgram() {
+        return otherProgram;
+    }
+
+    public void setOtherProgram(ProjectContentData otherProgram) {
+        this.otherProgram = otherProgram;
+    }
+
+    @ExcelField(title="合同范围", align=2, sort=14)
+	public String getScope() {
+		return scope;
+	}
+
+	public void setScope(String scope) {
+		this.scope = scope;
+	}
+	
+	@ExcelField(title="界面的处理", align=2, sort=15)
+	public String getInteface() {
+		return inteface;
+	}
+
+	public void setInteface(String inteface) {
+		this.inteface = inteface;
+	}
+	
+}

+ 80 - 0
src/main/java/com/jeeplus/modules/workcontractinfo/service/WorkContractReviewService.java

@@ -0,0 +1,80 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workcontractinfo.service;
+
+import java.util.List;
+
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.isignature.service.ISignatureDocumentService;
+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.dao.WorkContractReviewDao;
+import com.jeeplus.modules.workcontractinfo.entity.WorkContractReview;
+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;
+
+/**
+ * 合同评价表Service
+ * @author 杨帆
+ * @version 2018-03-23
+ */
+@Service
+@Transactional(readOnly = true)
+public class WorkContractReviewService extends CrudService<WorkContractReviewDao, WorkContractReview> {
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+
+	@Autowired
+	private ISignatureDocumentService signatureDocumentService;
+
+	public WorkContractReview get(String id) {
+		return super.get(id);
+	}
+	
+	public List<WorkContractReview> findList(WorkContractReview workContractReview) {
+		return super.findList(workContractReview);
+	}
+	
+	public Page<WorkContractReview> findPage(Page<WorkContractReview> page, WorkContractReview workContractReview) {
+		return super.findPage(page, workContractReview);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkContractReview workContractReview) {
+		super.save(workContractReview);
+		for (WorkClientAttachment workClientAttachment : workContractReview.getWorkAttachments()){
+			if (workClientAttachment.getId() == null){
+				continue;
+			}
+			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())){
+				workClientAttachment.setAttachmentId(workContractReview.getId());
+				workClientAttachment.setAttachmentFlag("80");
+				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(WorkContractReview workContractReview) {
+		super.delete(workContractReview);
+	}
+	
+	
+	
+	
+}

+ 95 - 0
src/main/java/com/jeeplus/modules/workdailyroutine/service/WorkDailyRoutineDetailService.java

@@ -0,0 +1,95 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.workdailyroutine.service;
+
+import java.util.Date;
+import java.util.List;
+
+import com.jeeplus.common.utils.IdGen;
+import com.jeeplus.common.utils.StringUtils;
+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.workdailyroutine.dao.WorkDailyRoutineDao;
+import com.jeeplus.modules.workdailyroutine.entity.WorkDailyRoutine;
+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.workdailyroutine.entity.WorkDailyRoutineDetail;
+import com.jeeplus.modules.workdailyroutine.dao.WorkDailyRoutineDetailDao;
+
+/**
+ * 日常事务Service
+ * @author ssrh
+ * @version 2018-07-11
+ */
+@Service
+@Transactional(readOnly = true)
+public class WorkDailyRoutineDetailService extends CrudService<WorkDailyRoutineDetailDao, WorkDailyRoutineDetail> {
+
+    @Autowired
+    private WorkDailyRoutineDao workDailyRoutineDao;
+    @Autowired
+    private WorkClientAttachmentDao workClientAttachmentDao;
+
+	public WorkDailyRoutineDetail get(String id) {
+        WorkDailyRoutineDetail workDailyRoutineDetail = super.get(id);
+        if(workDailyRoutineDetail!=null && workDailyRoutineDetail.getWorkDailyRoutine()!=null && StringUtils.isNotBlank(workDailyRoutineDetail.getWorkDailyRoutine().getId())){
+            workDailyRoutineDetail.setWorkDailyRoutine(workDailyRoutineDao.get(workDailyRoutineDetail.getWorkDailyRoutine().getId()));
+        }
+        return workDailyRoutineDetail;
+	}
+	
+	public List<WorkDailyRoutineDetail> findList(WorkDailyRoutineDetail workDailyRoutineDetail) {
+		return super.findList(workDailyRoutineDetail);
+	}
+	
+	public Page<WorkDailyRoutineDetail> findPage(Page<WorkDailyRoutineDetail> page, WorkDailyRoutineDetail workDailyRoutineDetail) {
+		return super.findPage(page, workDailyRoutineDetail);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkDailyRoutineDetail workDailyRoutineDetail) {
+	    if(workDailyRoutineDetail.getIsNewRecord()) {
+            workDailyRoutineDetail.setId(IdGen.uuid());
+            dao.insert(workDailyRoutineDetail);
+        }else {
+	        dao.update(workDailyRoutineDetail);
+        }
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(WorkDailyRoutineDetail workDailyRoutineDetail) {
+		super.delete(workDailyRoutineDetail);
+	}
+
+    public Integer countUndone(WorkDailyRoutineDetail select) {
+        return dao.countUndone(select);
+    }
+
+    public WorkDailyRoutineDetail getByDailyId(String notifyId) {
+        WorkDailyRoutineDetail select = new WorkDailyRoutineDetail();
+        select.setWorkDailyRoutine(new WorkDailyRoutine(notifyId));
+        select.setOperator(UserUtils.getUser());
+        List<WorkDailyRoutineDetail> list = this.findList(select);
+        if (list==null||list.size()<=0)return null;
+        WorkDailyRoutineDetail workDailyRoutineDetail = list.get(0);
+        if(workDailyRoutineDetail!=null && workDailyRoutineDetail.getWorkDailyRoutine()!=null && StringUtils.isNotBlank(workDailyRoutineDetail.getWorkDailyRoutine().getId())){
+            WorkDailyRoutine workDailyRoutine = workDailyRoutineDao.get(workDailyRoutineDetail.getWorkDailyRoutine().getId());
+            workDailyRoutineDetail.setWorkDailyRoutine(workDailyRoutine);
+            if(workDailyRoutine!=null&&StringUtils.isNotBlank(workDailyRoutine.getId())){
+                WorkClientAttachment attachment = new WorkClientAttachment();
+                attachment.setAttachmentId(workDailyRoutine.getId());
+                workDailyRoutine.setWorkAttachments(workClientAttachmentDao.findList(attachment));
+            }
+            if(workDailyRoutineDetail.getUpdateDate()==null){
+                workDailyRoutineDetail.setUpdateDate(new Date());
+            }
+        }
+        return workDailyRoutineDetail;
+    }
+}

+ 0 - 0
src/main/java/com/jeeplus/modules/workdevicerecord/web/WorkDeviceXjRecordController.java


Some files were not shown because too many files changed in this diff