yue 5 年之前
父節點
當前提交
388b072168

+ 310 - 260
src/main/java/com/jeeplus/common/config/Global.java

@@ -23,276 +23,326 @@ import com.jeeplus.common.utils.StringUtils;
 
 /**
  * 全局配置类
+ *
  * @author jeeplus
  * @version 2017-06-25
  */
 public class Global {
 
-	/**
-	 * 当前对象实例
-	 */
-	private static Global global = new Global();
-	
-	/**
-	 * 保存全局属性值
-	 */
-	private static Map<String, String> map = Maps.newHashMap();
-	
-	/**
-	 * 属性文件加载对象
-	 */
-	private static PropertiesLoader loader = new PropertiesLoader("/properties/jeeplus.properties");
-
-	/**
-	 * 显示/隐藏
-	 */
-	public static final String SHOW = "1";
-	public static final String HIDE = "0";
-
-	/**
-	 * 是/否
-	 */
-	public static final String YES = "1";
-	public static final String NO = "0";
-	
-	/**
-	 * 对/错
-	 */
-	public static final String TRUE = "true";
-	public static final String FALSE = "false";
-	
-	/**
-	 * 上传文件基础虚拟路径
-	 */
-	public static final String USERFILES_BASE_URL = "/userfiles/";
-
-	/**
-	 * 共享文档物理存储地址
-	 * @return
-	 */
-	public static String getShareBaseDir(){
-		String dir =  Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL  + "共享文档/";
-		FileUtils.createDirectory(dir);
-		return dir;
-	}
-	/**
-	 * 共享文档网络访问地址
-	 * @return
-	 */
-	public static String getShareBaseUrl(){
-		SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
-		return  Servlets.getRequest().getContextPath() + Global.USERFILES_BASE_URL +  "/共享文档/";
-	}
-
-	/**
-	 * 我的文档物理存储地址
-	 * @return
-	 */
-	public static String getMyDocDir(){
-		SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
-		String dir = Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + principal + "/我的文档/";
-		FileUtils.createDirectory(dir);
-		return dir;
-	}
-	/**
-	 * 我的文档网络访问地址
-	 * @return
-	 */
-	public static String getMyDocUrl(){
-		SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
-		return  Servlets.getRequest().getContextPath() + Global.USERFILES_BASE_URL + principal + "/我的文档/";
-	}
-
-	/**
-	 * 程序附件物理存储地址
-	 * @return
-	 */
-	public static String getAttachmentDir(){
-		SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
-		String dir = Global.getUserfilesBaseDir()  ;
-		FileUtils.createDirectory(dir);
-		return dir;
-	}
-
-	/**
-	 * 程序附件网络访问地址
-	 * @return
-	 */
-	public static String getAttachmentUrl(){
-
-		SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
-		return  Servlets.getRequest().getContextPath() ;
-	}
-
-	/**
-	 * 绝对地址转换为网络地址
-	 * @return
-	 */
-	public static String transDirToUrl(String dir){
-		return   Servlets.getRequest().getContextPath()+"/" + dir.substring(Global.getUserfilesBaseDir().length());
-	}
-	/**
-	 * 获取当前对象实例
-	 */
-	public static Global getInstance() {
-		return global;
-	}
-	
-	/**
-	 * 获取配置
-	 */
-	public static String getConfig(String key) {
-		String value = map.get(key);
-		if (value == null){
-			value = loader.getProperty(key);
-			map.put(key, value != null ? value : StringUtils.EMPTY);
-		}
-		return value;
-	}
-	
-	/**
-	 * 获取管理端根路径
-	 */
-	public static String getAdminPath() {
-		return getConfig("adminPath");
-	}
-
-
-	/**
-	 * 获取管理端根路径
-	 */
-	public static String getDefaultTheme() {
-		return getConfig("defaultTheme");
-	}
-	
-	/**
-	 * 获取前端根路径
-	 */
-	public static String getFrontPath() {
-		return getConfig("frontPath");
-	}
-	
-	/**
-	 * 获取URL后缀
-	 */
-	public static String getUrlSuffix() {
-		return getConfig("urlSuffix");
-	}
-	
-	/**
-	 * 是否是演示模式,演示模式下不能修改用户、角色、密码、菜单、授权
-	 */
-	public static Boolean isDemoMode() {
-		String dm = getConfig("demoMode");
-		return "true".equals(dm) || "1".equals(dm);
-	}
-	
-	/**
-	 * 在修改系统用户和角色时是否同步到Activiti
-	 */
-	public static Boolean isSynActivitiIndetity() {
-		String dm = getConfig("activiti.isSynActivitiIndetity");
-		return "true".equals(dm) || "1".equals(dm);
-	}
-    
-	/**
-	 * 页面获取常量
-	 */
-	public static Object getConst(String field) {
-		try {
-			return Global.class.getField(field).get(null);
-		} catch (Exception e) {
-			// 异常代表无配置,这里什么也不做
-		}
-		return null;
-	}
-
-	/**
-	 * 获取上传文件的根目录
-	 * @return
-	 */
-	public static String getUserfilesBaseDir() {
-		String dir = getConfig("userfiles.basedir");
-		if (StringUtils.isBlank(dir)){
-			return "";
-		}
-		if(!dir.endsWith("/")) {
-			dir += "/";
-		}
+    /**
+     * 当前对象实例
+     */
+    private static Global global = new Global();
+
+    /**
+     * 保存全局属性值
+     */
+    private static Map<String, String> map = Maps.newHashMap();
+
+    /**
+     * 属性文件加载对象
+     */
+    private static PropertiesLoader loader = new PropertiesLoader("/properties/jeeplus.properties");
+
+    /**
+     * 显示/隐藏
+     */
+    public static final String SHOW = "1";
+    public static final String HIDE = "0";
+
+    /**
+     * 是/否
+     */
+    public static final String YES = "1";
+    public static final String NO = "0";
+
+    /**
+     * 对/错
+     */
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    /**
+     * 上传文件基础虚拟路径
+     */
+    public static final String USERFILES_BASE_URL = "/freemarker/";
+
+    public static final String FILES_fileServer = "/fileServer/";
+
+
+    /**
+     * 判断服务器系统类型,1是windows系统,2是linux系统
+     */
+    public static final String SYS_TYPE = System.getProperty("os.name").toLowerCase().startsWith("win") ? "1" : "2";
+
+
+    /**
+     * 共享文档物理存储地址
+     *
+     * @return
+     */
+    public static String getShareBaseDir() {
+        String dir = Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + "共享文档/";
+        FileUtils.createDirectory(dir);
+        return dir;
+    }
+
+    /**
+     * 共享文档网络访问地址
+     *
+     * @return
+     */
+    public static String getShareBaseUrl() {
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        return Servlets.getRequest().getContextPath() + Global.USERFILES_BASE_URL + "/共享文档/";
+    }
+
+    /**
+     * 我的文档物理存储地址
+     *
+     * @return
+     */
+    public static String getMyDocDir() {
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        String dir = Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + principal + "/我的文档/";
+        FileUtils.createDirectory(dir);
+        return dir;
+    }
+
+    /**
+     * 我的文档网络访问地址
+     *
+     * @return
+     */
+    public static String getMyDocUrl() {
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        return Servlets.getRequest().getContextPath() + Global.USERFILES_BASE_URL + principal + "/我的文档/";
+    }
+
+    /**
+     * 程序附件物理存储地址
+     *
+     * @return
+     */
+    public static String getAttachmentDir() {
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        String dir = Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL;
+        FileUtils.createDirectory(dir);
+        return dir;
+    }
+
+    /**
+     * 程序附件物理存储地址
+     *
+     * @return
+     */
+    public static String getAttachmentDir2() {
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        String dir = "";
+        if (SYS_TYPE.equals("1")) {
+            dir = Global.getUserfilesBaseDir() + Global.FILES_fileServer;
+        } else {
+            dir = Global.getUserfilesBaseDir() + "data/nginx/file" + Servlets.getRequest().getContextPath() + Global.FILES_fileServer;
+        }
+        FileUtils.createDirectory(dir);
+        return dir;
+    }
+
+    /**
+     * 程序附件网络访问地址
+     *
+     * @return
+     */
+    public static String getAttachmentUrl() {
+
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        return Servlets.getRequest().getContextPath() + Global.USERFILES_BASE_URL;
+    }
+
+
+    /**
+     * 程序附件网络访问地址
+     *
+     * @return
+     */
+    public static String getAttachmentUrl2() {
+
+        SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
+        return Servlets.getRequest().getContextPath() + Global.FILES_fileServer;
+    }
+
+    /**
+     * 绝对地址转换为网络地址
+     *
+     * @return
+     */
+    public static String transDirToUrl(String dir) {
+        return Servlets.getRequest().getContextPath() + "/" + dir.substring(Global.getUserfilesBaseDir().length());
+    }
+
+    /**
+     * 获取当前对象实例
+     */
+    public static Global getInstance() {
+        return global;
+    }
+
+    /**
+     * 获取配置
+     */
+    public static String getConfig(String key) {
+        String value = map.get(key);
+        if (value == null) {
+            value = loader.getProperty(key);
+            map.put(key, value != null ? value : StringUtils.EMPTY);
+        }
+        return value;
+    }
+
+    /**
+     * 获取管理端根路径
+     */
+    public static String getAdminPath() {
+        return getConfig("adminPath");
+    }
+
+
+    /**
+     * 获取管理端根路径
+     */
+    public static String getDefaultTheme() {
+        return getConfig("defaultTheme");
+    }
+
+    /**
+     * 获取前端根路径
+     */
+    public static String getFrontPath() {
+        return getConfig("frontPath");
+    }
+
+    /**
+     * 获取URL后缀
+     */
+    public static String getUrlSuffix() {
+        return getConfig("urlSuffix");
+    }
+
+    /**
+     * 是否是演示模式,演示模式下不能修改用户、角色、密码、菜单、授权
+     */
+    public static Boolean isDemoMode() {
+        String dm = getConfig("demoMode");
+        return "true".equals(dm) || "1".equals(dm);
+    }
+
+    /**
+     * 在修改系统用户和角色时是否同步到Activiti
+     */
+    public static Boolean isSynActivitiIndetity() {
+        String dm = getConfig("activiti.isSynActivitiIndetity");
+        return "true".equals(dm) || "1".equals(dm);
+    }
+
+    /**
+     * 页面获取常量
+     */
+    public static Object getConst(String field) {
+        try {
+            return Global.class.getField(field).get(null);
+        } catch (Exception e) {
+            // 异常代表无配置,这里什么也不做
+        }
+        return null;
+    }
+
+    /**
+     * 获取上传文件的根目录
+     *
+     * @return
+     */
+    public static String getUserfilesBaseDir() {
+        String dir = getConfig("userfiles.basedir");
+        if (StringUtils.isBlank(dir)) {
+            return "";
+        }
+        if (!dir.endsWith("/")) {
+            dir += "/";
+        }
 //		System.out.println("userfiles.basedir: " + dir);
-		return dir;
-	}
-	
+        return dir;
+    }
+
     /**
      * 获取工程路径
+     *
      * @return
      */
-    public static String getProjectPath(){
-    	// 如果配置了工程路径,则直接返回,否则自动获取。
-		String projectPath = Global.getConfig("projectPath");
-		if (StringUtils.isNotBlank(projectPath)){
-			return projectPath;
-		}
-		try {
-			File file = new DefaultResourceLoader().getResource("").getFile();
-			if (file != null){
-				while(true){
-					File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
-					if (f == null || f.exists()){
-						break;
-					}
-					if (file.getParentFile() != null){
-						file = file.getParentFile();
-					}else{
-						break;
-					}
-				}
-				projectPath = file.toString();
-			}
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return projectPath;
+    public static String getProjectPath() {
+        // 如果配置了工程路径,则直接返回,否则自动获取。
+        String projectPath = Global.getConfig("projectPath");
+        if (StringUtils.isNotBlank(projectPath)) {
+            return projectPath;
+        }
+        try {
+            File file = new DefaultResourceLoader().getResource("").getFile();
+            if (file != null) {
+                while (true) {
+                    File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
+                    if (f == null || f.exists()) {
+                        break;
+                    }
+                    if (file.getParentFile() != null) {
+                        file = file.getParentFile();
+                    } else {
+                        break;
+                    }
+                }
+                projectPath = file.toString();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return projectPath;
     }
-    
+
     /**
-	 * 写入properties信息
-	 * 
-	 * @param key
-	 *            名称
-	 * @param value
-	 *            值
-	 */
-	public static void modifyConfig(String key, String value) {
-		try {
-			// 从输入流中读取属性列表(键和元素对)
-			Properties prop = getProperties();
-			prop.setProperty(key, value);
-			String path = Global.class.getResource("/properties/jeeplus.properties").getPath();
-			FileOutputStream outputFile = new FileOutputStream(path);
-			prop.store(outputFile, "modify");
-			outputFile.close();
-			outputFile.flush();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-	
-	/**
-	 * 返回 Properties
-	 * @param
-	 * @return
-	 */
-	public static Properties getProperties(){
-		Properties prop = new Properties();
-		try {
-			Reader reader = Resources.getResourceAsReader("/properties/jeeplus.properties");
-			prop.load(reader);
-		} catch (Exception e) {
-			return null;
-		}
-		return prop;
-	}
-
-	
+     * 写入properties信息
+     *
+     * @param key   名称
+     * @param value 值
+     */
+    public static void modifyConfig(String key, String value) {
+        try {
+            // 从输入流中读取属性列表(键和元素对)
+            Properties prop = getProperties();
+            prop.setProperty(key, value);
+            String path = Global.class.getResource("/properties/jeeplus.properties").getPath();
+            FileOutputStream outputFile = new FileOutputStream(path);
+            prop.store(outputFile, "modify");
+            outputFile.close();
+            outputFile.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 返回 Properties
+     *
+     * @param
+     * @return
+     */
+    public static Properties getProperties() {
+        Properties prop = new Properties();
+        try {
+            Reader reader = Resources.getResourceAsReader("/properties/jeeplus.properties");
+            prop.load(reader);
+        } catch (Exception e) {
+            return null;
+        }
+        return prop;
+    }
+
+
 }

+ 243 - 0
src/main/java/com/jeeplus/core/servlet/UserUploadServlet.java

@@ -0,0 +1,243 @@
+package com.jeeplus.core.servlet;
+
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.util.UriUtils;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+
+/**
+ * @author jeeplus
+ * @version 2017-06-25
+ */
+public class UserUploadServlet 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.FILES_fileServer);
+		if(index >= 0) {
+			filepath = filepath.substring(index + Global.FILES_fileServer.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.FILES_fileServer + filepath);
+		//此处修改为断点续传模式,实现视频分段解析,解决视频加载缓慢及微信解析异常问题
+		try{
+			downRangeFile(file,resp,req);
+		}catch (Exception e){
+			e.printStackTrace();
+		}
+
+	}
+
+	@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);
+	}
+
+	public void downRangeFile(File downloadFile, HttpServletResponse response, HttpServletRequest request) throws Exception {
+
+		String extName = "";
+		// 文件不存在
+		if (!downloadFile.exists()) {
+			response.sendError(HttpServletResponse.SC_NOT_FOUND);
+			return;
+		}
+
+		long fileLength = downloadFile.length();// 记录文件大小
+		long pastLength = 0;// 记录已下载文件大小
+		int rangeSwitch = 0;// 0:从头开始的全文下载;1:从某字节开始的下载(bytes=27000-);2:从某字节开始到某字节结束的下载(bytes=27000-39000)
+		long toLength = 0;// 记录客户端需要下载的字节段的最后一个字节偏移量(比如bytes=27000-39000,则这个值是为39000)
+		long contentLength = 0;// 客户端请求的字节总量
+		String rangeBytes = "";// 记录客户端传来的形如“bytes=27000-”或者“bytes=27000-39000”的内容
+		RandomAccessFile raf = null;// 负责读取数据
+		OutputStream os = null;// 写出数据
+		OutputStream out = null;// 缓冲
+		int bsize = 1024;// 缓冲区大小
+		byte b[] = new byte[bsize];// 暂存容器
+
+		String range = request.getHeader("Range");
+		int responseStatus = 206;
+		if (range != null && range.trim().length() > 0 && !"null".equals(range)) {// 客户端请求的下载的文件块的开始字节
+			responseStatus =HttpServletResponse.SC_PARTIAL_CONTENT;
+//			logger.info("request.getHeader(\"Range\")=" + range);
+			rangeBytes = range.replaceAll("bytes=", "");
+			if (rangeBytes.endsWith("-")) {// bytes=969998336-
+				rangeSwitch = 1;
+				rangeBytes = rangeBytes.substring(0, rangeBytes.indexOf('-'));
+				pastLength = Long.parseLong(rangeBytes.trim());
+				contentLength = fileLength - pastLength;// 客户端请求的是
+				// 969998336之后的字节(包括bytes下标索引为969998336的字节)
+			} else {// bytes=1275856879-1275877358
+				rangeSwitch = 2;
+				String temp0 = rangeBytes.substring(0, rangeBytes.indexOf('-'));
+				String temp2 = rangeBytes.substring(rangeBytes.indexOf('-') + 1, rangeBytes.length());
+				// bytes=1275856879-1275877358,从第1275856879个字节开始下载
+				pastLength = Long.parseLong(temp0.trim());
+				toLength = Long.parseLong(temp2);// bytes=1275856879-1275877358,到第
+				// 1275877358 个字节结束
+				contentLength = toLength - pastLength + 1;// 客户端请求的是
+				// 1275856879-1275877358
+				// 之间的字节
+			}
+		} else {// 从开始进行下载
+			contentLength = fileLength;// 客户端要求全文下载
+		}
+
+		/**
+		 * 如果设设置了Content-Length,则客户端会自动进行多线程下载。如果不希望支持多线程,则不要设置这个参数。 响应的格式是:
+		 * Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节]
+		 * ServletActionContext.getResponse().setHeader("Content-Length", new
+		 * Long(file.length() - p).toString());
+		 */
+		// 来清除首部的空白行
+		response.reset();
+		// 告诉客户端允许断点续传多线程连接下载,响应的格式是:Accept-Ranges: bytes
+		response.setHeader("Accept-Ranges", "bytes");
+		// 如果是第一次下,还没有断点续传,状态是默认的 200,无需显式设置;响应的格式是:HTTP/1.1
+		if (rangeSwitch != 0) {
+			response.setStatus(responseStatus);
+			// 不是从最开始下载,断点下载响应号为206
+			// 响应的格式是:
+			// Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
+//			logger.info("----------------------------片段下载,服务器即将开始断点续传...");
+			switch (rangeSwitch) {
+				case 1: {// 针对 bytes=27000- 的请求
+					String contentRange = new StringBuffer("bytes ")
+							.append(new Long(pastLength).toString()).append("-")
+							.append(new Long(fileLength - 1).toString())
+							.append("/").append(new Long(fileLength).toString())
+							.toString();
+					response.setHeader("Content-Range", contentRange);
+					break;
+				}
+				case 2: {// 针对 bytes=27000-39000 的请求
+					String contentRange = range.replace("=", " ") + "/"
+							+ new Long(fileLength).toString();
+					response.setHeader("Content-Range", contentRange);
+					break;
+				}
+				default: {
+					break;
+				}
+			}
+		} else {
+			String contentRange = new StringBuffer("bytes ").append("0-")
+					.append(fileLength - 1).append("/").append(fileLength)
+					.toString();
+			response.setHeader("Content-Range", contentRange);
+			// 是从开始下载
+//			logger.info("----------------------------是从开始到最后完整下载!");
+		}
+
+		try {
+			// /////////////////////////设置文件Content-Type///////////////////////////
+			String finalFileName = null;
+			//获得浏览器代理信息
+			final String userAgent = request.getHeader("USER-AGENT");
+			if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")||StringUtils.contains(userAgent,"Edge")){//IE浏览器
+				finalFileName = URLEncoder.encode(downloadFile.getName(),"UTF8");
+			}else if(StringUtils.contains(userAgent, "Mozilla")){//google,火狐浏览器
+				finalFileName = new String(downloadFile.getName().getBytes("GBK"), "iso8859-1");
+			}else{
+				finalFileName = URLEncoder.encode(downloadFile.getName(),"UTF8");//其他浏览器
+			}
+			response.setHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+"");//下载文件的名称
+			response.setHeader("Content-Length", String.valueOf(contentLength));
+			os = response.getOutputStream();
+			out = new BufferedOutputStream(os);
+			raf = new RandomAccessFile(downloadFile, "r");
+			try {
+				long outLength = 0;// 实际输出字节数
+				switch (rangeSwitch) {
+					case 0: {// 普通下载,或者从头开始的下载
+						// 同1,没有break
+					}
+					case 1: {// 针对 bytes=27000- 的请求
+						raf.seek(pastLength);// 形如 bytes=969998336- 的客户端请求,跳过
+						// 969998336 个字节
+						int n = 0;
+						while ((n = raf.read(b)) != -1) {
+							out.write(b, 0, n);
+							outLength += n;
+						}
+						// while ((n = raf.read(b, 0, 1024)) != -1) {
+						// out.write(b, 0, n);
+						// }
+						break;
+					}
+					case 2: {
+						// 针对 bytes=27000-39000 的请求,从27000开始写数据
+						raf.seek(pastLength);
+						int n = 0;
+						long readLength = 0;// 记录已读字节数
+						while (readLength <= contentLength - bsize) {// 大部分字节在这里读取
+							n = raf.read(b);
+							readLength += n;
+							out.write(b, 0, n);
+							outLength += n;
+						}
+						if (readLength <= contentLength) {// 余下的不足 1024 个字节在这里读取
+							n = raf.read(b, 0, (int) (contentLength - readLength));
+							out.write(b, 0, n);
+							outLength += n;
+						}
+						break;
+					}
+					default: {
+						break;
+					}
+				}
+//				logger.info("Content-Length为:" + contentLength + ";实际输出字节数:" + outLength);
+				out.flush();
+			} catch (IOException ie) {
+				/**
+				 * 在写数据的时候, 对于 ClientAbortException 之类的异常,
+				 * 是因为客户端取消了下载,而服务器端继续向浏览器写入数据时, 抛出这个异常,这个是正常的。
+				 * 尤其是对于迅雷这种吸血的客户端软件, 明明已经有一个线程在读取 bytes=1275856879-1275877358,
+				 * 如果短时间内没有读取完毕,迅雷会再启第二个、第三个。。。线程来读取相同的字节段, 直到有一个线程读取完毕,迅雷会 KILL
+				 * 掉其他正在下载同一字节段的线程, 强行中止字节读出,造成服务器抛 ClientAbortException。
+				 * 所以,我们忽略这种异常
+				 */
+				// ignore
+			}
+		} catch (Exception e) {
+		} finally {
+			if (out != null) {
+				try {
+					out.close();
+				} catch (IOException e) {
+				}
+			}
+			if (raf != null) {
+				try {
+					raf.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+
+	}
+}

+ 4 - 1
src/main/java/com/jeeplus/modules/sg/managementcenter/activiti/mapper/xml/UploadImagesMapper.xml

@@ -20,7 +20,7 @@
 	<select id="get" resultType="com.jeeplus.modules.sg.managementcenter.activiti.entity.UploadImages" >
 		SELECT *
 		FROM xm_upolad_images a
-		WHERE a.uId = #{uId}
+		WHERE a.id = #{id}
 	</select>
 	
 	<select id="findList" resultType="UploadImages" >
@@ -33,6 +33,9 @@
 			<if test="uId != null and uId != ''">
 				AND a.uId = #{uId}
 			</if>
+			<if test="procInsId!=null and procInsId!=''">
+				and a.proc_ins_id = #{procInsId}
+			</if>
 		</where>
 		<choose>
 			<when test="page !=null and page.orderBy != null and page.orderBy != ''">

+ 9 - 62
src/main/java/com/jeeplus/modules/sg/managementcenter/activiti/web/DivideController.java

@@ -20,6 +20,7 @@ import com.jeeplus.modules.sg.managementcenter.activiti.service.UploadImagesServ
 import com.jeeplus.modules.sys.utils.UserUtils;
 import com.jeeplus.modules.test.pic.entity.TestPic;
 import org.activiti.engine.repository.ProcessDefinition;
+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;
@@ -63,33 +64,16 @@ public class DivideController extends BaseController {
 		return entity;
 	}
 
-	@RequestMapping(value = "upload")
-	public String formUp(Construction construction, Model model) {
-		model.addAttribute("construction", construction);
-		return "modules/sg/managementcenter/activiti/upload";
-	}
 
 
-
-	/**
-	 * 图片管理列表页面
-	 */
-	@RequestMapping(value = {"images"})
-	public String list(Construction construction, Model model) {
-		model.addAttribute("construction", construction);
-		return "modules/sg/managementcenter/activiti/uploadList";
-	}
-
-
-	/**
-	 * 文件管理列表数据
-	 */
-	@ResponseBody
-	@RequestMapping(value = "data")
-	public Map<String, Object> data(UploadImages uploadImages, HttpServletRequest request, HttpServletResponse response, Model model) {
-		Page<UploadImages> page = uploadImagesService.findPage(new Page<UploadImages>(request, response), uploadImages);
-		return getBootstrapData(page);
-	}
+//	/**
+//	 * 文件管理列表数据
+//	@ResponseBody
+//	@RequestMapping(value = "data")
+//	public Map<String, Object> data(UploadImages uploadImages, HttpServletRequest request, HttpServletResponse response, Model model) {
+//		Page<UploadImages> page = uploadImagesService.findPage(new Page<UploadImages>(request, response), uploadImages);
+//		return getBootstrapData(page);
+//	}*/
 
 
 	
@@ -153,41 +137,4 @@ public class DivideController extends BaseController {
 		return j;
 	}
 
-	@ResponseBody
-	@RequestMapping(value = "uploadSave")
-	public AjaxJson uploadSave(Disclose disclose, Model model,String pic) throws Exception{
-		AjaxJson j = new AjaxJson();
-		/**
-		 * 后台hibernate-validation插件校验
-		 */
-		String errMsg = beanValidator(disclose);
-		if (StringUtils.isNotBlank(errMsg)){
-			j.setSuccess(false);
-			j.setMsg(errMsg);
-			return j;
-		}
-
-		/**
-		 * 流程审批
-		 */
-		if (StringUtils.isBlank(disclose.getId())){
-			UploadImages uploadImages = new UploadImages();
-			uploadImages.setPath(pic);
-			uploadImages.setProcInsId(disclose.getAct().getProcDefId());
-			uploadImages.setuId(UserUtils.getUser().getLoginName());
-			uploadImagesService.save(uploadImages);
-			//新增或编辑表单保存
-			// 启动流程
-			ProcessDefinition p = actProcessService.getProcessDefinition(disclose.getAct().getProcDefId());
-			String title = disclose.getCurrentUser().getName()+"在"+ DateUtils.getDateTime()+"发起"+p.getName();
-			actTaskService.startProcess(p.getKey(),  "xm_construction_clarificaiton", disclose.getId(), title);
-			j.setMsg("提交审批成功!");
-			j.getBody().put("targetUrl",  "/act/task/process/");
-		}
-
-		return j;
-	}
-	
-
-
 }

+ 156 - 0
src/main/java/com/jeeplus/modules/sg/managementcenter/activiti/web/UploadController.java

@@ -0,0 +1,156 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.sg.managementcenter.activiti.web;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.json.AjaxJson;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.core.persistence.Page;
+import com.jeeplus.core.web.BaseController;
+import com.jeeplus.modules.act.service.ActProcessService;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.sg.managementcenter.activiti.entity.Construction;
+import com.jeeplus.modules.sg.managementcenter.activiti.entity.Disclose;
+import com.jeeplus.modules.sg.managementcenter.activiti.entity.UploadImages;
+import com.jeeplus.modules.sg.managementcenter.activiti.service.ConstructionService;
+import com.jeeplus.modules.sg.managementcenter.activiti.service.DiscloseService;
+import com.jeeplus.modules.sg.managementcenter.activiti.service.UploadImagesService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 施工交底Controller
+ * @author
+ * @version 2019-11-08
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/managementcenter/upload")
+
+public class UploadController extends BaseController {
+
+	@Autowired
+	private ConstructionService constructionService;
+	@Autowired
+	private ActProcessService actProcessService;
+	@Autowired
+	private ActTaskService actTaskService;
+	@Autowired
+	private DiscloseService discloseService;
+	@Autowired
+	private UploadImagesService uploadImagesService;
+
+	@ModelAttribute
+	public UploadImages get(@RequestParam(required=false) String id) {
+		UploadImages entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = uploadImagesService.get(id);
+		}
+		if (entity == null){
+			entity = new UploadImages();
+		}
+		return entity;
+	}
+
+	@RequestMapping(value = "list")
+	public String formList(UploadImages uploadImages, Model model) {
+		model.addAttribute("uploadImages", uploadImages);
+		return "modules/sg/managementcenter/activiti/upload";
+	}
+
+	@RequestMapping(value = "form")
+	public String formUp(UploadImages uploadImages, Model model) {
+		model.addAttribute("uploadImages", uploadImages);
+		return "modules/sg/managementcenter/activiti/uploadList";
+	}
+
+	/**
+	 * 图片管理列表页面
+	 */
+	@RequestMapping(value = {"images"})
+	public String list(UploadImages uploadImages, Model model) {
+		model.addAttribute("uploadImages", uploadImages);
+		return "modules/sg/managementcenter/activiti/uploadList";
+	}
+
+	/**
+	 * 查看,增加,编辑图片管理表单页面
+	 */
+	@RequestMapping(value = "imagesForm")
+	public String form(UploadImages uploadImages, Model model) {
+		model.addAttribute("uploadImages", uploadImages);
+		return "modules/sg/managementcenter/activiti/uploadListForm";
+	}
+
+
+	/**
+	 * 文件管理列表数据
+	 */
+	@ResponseBody
+	@RequestMapping(value = "data")
+	public Map<String, Object> data(UploadImages uploadImages, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<UploadImages> page = uploadImagesService.findPage(new Page<UploadImages>(request, response), uploadImages);
+		if (Global.SYS_TYPE.equals("2")) {
+			List<UploadImages> list = page.getList();
+			for (UploadImages upload:
+				 list) {
+				upload.setPath("http://" + request.getServerName() + upload.getPath());
+			}
+		}
+		return getBootstrapData(page);
+	}
+
+
+	
+
+
+
+
+	@ResponseBody
+	@RequestMapping(value = "uploadSave")
+	public AjaxJson uploadSave(UploadImages uploadImages, Model model,String pic) throws Exception{
+		AjaxJson j = new AjaxJson();
+		/**
+		 * 后台hibernate-validation插件校验
+		 */
+		String errMsg = beanValidator(uploadImages);
+		if (StringUtils.isNotBlank(errMsg)){
+			j.setSuccess(false);
+			j.setMsg(errMsg);
+			return j;
+		}
+
+		/**
+		 * 流程审批
+		 */
+		if (StringUtils.isBlank(uploadImages.getId())){
+			uploadImages.setPath(pic);
+			uploadImages.setProcInsId(uploadImages.getAct().getTaskId());
+			uploadImages.setuId(UserUtils.getUser().getLoginName());
+			uploadImagesService.save(uploadImages);
+			//新增或编辑表单保存
+			// 启动流程
+			ProcessDefinition p = actProcessService.getProcessDefinition(uploadImages.getAct().getProcDefId());
+			String title = uploadImages.getCurrentUser().getName()+"在"+ DateUtils.getDateTime()+"发起"+p.getName();
+			actTaskService.startProcess(p.getKey(),  "xm_upolad_images", uploadImages.getId(), title);
+			j.setMsg("提交审批成功!");
+			j.getBody().put("targetUrl",  "/act/task/process/");
+		}
+
+		return j;
+	}
+	
+
+
+}

+ 2 - 2
src/main/java/com/jeeplus/modules/sys/web/FileController.java

@@ -313,8 +313,8 @@ public class FileController extends BaseController {
         int year = cal.get(Calendar.YEAR);
         int month = cal.get(Calendar.MONTH )+1;
 		SystemAuthorizingRealm.Principal principal = (SystemAuthorizingRealm.Principal) UserUtils.getPrincipal();
-		String fileUrl = Global.getAttachmentUrl()+uploadPath+"/"+year+"/"+month+"/";
-		String fileDir = Global.getAttachmentDir()+uploadPath+"/"+year+"/"+month+"/";
+		String fileUrl = Global.getAttachmentUrl2()+uploadPath+"/"+year+"/"+month+"/";
+		String fileDir = Global.getAttachmentDir2()+uploadPath+"/"+year+"/"+month+"/";
 		// 判断文件是否为空
 		if (!file.isEmpty()) {
 			// 文件保存路径

+ 8 - 0
src/main/webapp/WEB-INF/web.xml

@@ -212,6 +212,14 @@
     <servlet-name>UserfilesDownloadServlet</servlet-name>
     <url-pattern>/userfiles/*</url-pattern>
   </servlet-mapping>
+    <servlet>
+        <servlet-name>UserUploadServlet</servlet-name>
+        <servlet-class>com.jeeplus.core.servlet.UserUploadServlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>UserUploadServlet</servlet-name>
+        <url-pattern>/fileServer/*</url-pattern>
+    </servlet-mapping>
   <servlet>
     <servlet-name>ValidateCodeServlet</servlet-name>
     <servlet-class>com.jeeplus.core.servlet.ValidateCodeServlet</servlet-class>

+ 5 - 5
src/main/webapp/webpage/modules/sg/managementcenter/activiti/upload.jsp

@@ -69,7 +69,7 @@
 					</h3>
 				</div>
 				<div class="panel-body">
-					<form:form id="inputForm" modelAttribute="construction" action="${ctx}/managementcenter/divide/uploadSave" method="post" class="form-horizontal">
+					<form:form id="inputForm" modelAttribute="uploadImages" action="${ctx}/managementcenter/upload/uploadSave" method="post" class="form-horizontal">
 						<form:hidden path="id"/>
 						<form:hidden path="act.taskId"/>
 						<form:hidden path="act.taskName"/>
@@ -89,7 +89,7 @@
 								</td>
 								<td class="width-15 active"><label class="pull-right"><font color="red">*</font>文件上传:</label></td>
 								<td class="width-35">
-									<sys:fileUpload  path="pic" fileNumLimit="50" fileSizeLimit="50" value="${testPic.pic}" type="file" uploadPath="${cxt}/freemarker"></sys:fileUpload>
+									<sys:fileUpload  path="pic" fileNumLimit="50" fileSizeLimit="50" value="${testPic.pic}" type="file" uploadPath="/list"></sys:fileUpload>
 								</td>
 							</tr>
 							</tbody>
@@ -105,9 +105,9 @@
 								</div>
 						</div>
 					</form:form>
-					<c:if test="${not empty construction.id}">
-						<act:flowChart procInsId="${construction.act.procInsId}"/>
-						<act:histoicFlow procInsId="${construction.act.procInsId}" />
+					<c:if test="${not empty uploadImages.id}">
+						<act:flowChart procInsId="${uploadImages.act.procInsId}"/>
+						<act:histoicFlow procInsId="${uploadImages.act.procInsId}" />
 					</c:if>
 				</div>
 			</div>

+ 30 - 5
src/main/webapp/webpage/modules/sg/managementcenter/activiti/uploadList.js

@@ -37,7 +37,7 @@ $(document).ready(function() {
                //可供选择的每页的行数(*)    
                pageList: [10, 25, 50, 100],
                //这个接口需要处理bootstrap table传递的固定参数,并返回特定格式的json数据  
-               url: "${ctx}/managementcenter/divide/data",
+               url: "${ctx}/managementcenter/upload/data",
                //默认值为 'limit',传给服务端的参数为:limit, offset, search, sort, order Else
                //queryParamsType:'',   
                ////查询参数,每次调用是会带上这个参数,可自定义                         
@@ -80,7 +80,27 @@ $(document).ready(function() {
                	onShowSearch: function () {
 			$("#search-collapse").slideToggle();
 		},
-               columns: [{
+               columns: [/*{
+				   field: 'uId',
+				   title: '标题',
+				   sortable: true,
+				   sortName: 'uId'
+				   ,formatter:function(value, row , index){
+					   value = jp.unescapeHTML(value);
+				   <c:choose>
+					   <c:when test="${fns:hasPermission('test:pic:testPic:edit')}">
+					   return "<a href='javascript:edit(\""+row.id+"\")'>"+value+"</a>";
+				   </c:when>
+					   <c:when test="${fns:hasPermission('test:pic:testPic:view')}">
+					   return "<a href='javascript:view(\""+row.id+"\")'>"+value+"</a>";
+				   </c:when>
+					   <c:otherwise>
+					   return value;
+				   </c:otherwise>
+					   </c:choose>
+				   }
+
+			   },*/{
 		        field: 'path',
 		        title: '图片路径',
 		        sortable: true,
@@ -99,7 +119,12 @@ $(document).ready(function() {
 		        	return labelArray.join(" ");
 		        }
 		       
-		    }]
+		    },{
+				   field: 'uId',
+				   title: '删除人员',
+				   sortable: true,
+				   sortName: 'uId',
+			   }]
 		});
 		
 		  
@@ -203,14 +228,14 @@ $(document).ready(function() {
        if(id == undefined){
 	      id = getIdSelections();
 	}
-	jp.openSaveDialog('编辑图片管理', "${ctx}/test/pic/testPic/form?id=" + id, '800px', '500px');
+	jp.openSaveDialog('编辑图片管理', "${ctx}/managementcenter/upload/imagesForm?id=" + id, '800px', '500px');
   }
   
  function view(id){//没有权限时,不显示确定按钮
       if(id == undefined){
              id = getIdSelections();
       }
-        jp.openViewDialog('查看图片管理', "${ctx}/test/pic/testPic/form?id=" + id, '800px', '500px');
+        jp.openViewDialog('查看图片管理', "${ctx}/managementcenter/upload/imagesForm?id=" + id, '800px', '500px');
  }
 
 

+ 5 - 4
src/main/webapp/webpage/modules/sg/managementcenter/activiti/uploadList.jsp

@@ -20,13 +20,14 @@
 	<!-- 搜索 -->
 	<div id="search-collapse" class="collapse">
 		<div class="accordion-inner">
-			<form:form id="searchForm" modelAttribute="construction" class="form form-horizontal well clearfix">
-				<input type="hidden" value="">
+	<form:form id="searchForm" modelAttribute="uploadImages" class="form form-horizontal well clearfix">
+		<input type="text" id="procInsId" name="procInsId" value="${uploadImages.act.procInsId}"/>
+		<input type="text" id="path" name="path" value="${uploadImages.path}">
 		 <div class="col-xs-12 col-sm-6 col-md-4">
-<%--			<div style="margin-top:26px">
+			<div style="margin-top:26px">
 			  <a  id="search" class="btn btn-primary btn-rounded  btn-bordered btn-sm"><i class="fa fa-search"></i> 查询</a>
 			  <a  id="reset" class="btn btn-primary btn-rounded  btn-bordered btn-sm" ><i class="fa fa-refresh"></i> 重置</a>
-			 </div>--%>
+			 </div>
 	    </div>	
 	</form:form>
 	</div>

+ 48 - 0
src/main/webapp/webpage/modules/sg/managementcenter/activiti/uploadListForm.jsp

@@ -0,0 +1,48 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>图片管理管理</title>
+	<meta name="decorator" content="ani"/>
+	<script type="text/javascript">
+
+		$(document).ready(function() {
+
+		});
+		function save() {
+            var isValidate = jp.validateForm('#inputForm');//校验表单
+            if(!isValidate){
+                return false;
+			}else{
+                jp.loading();
+                jp.post("${ctx}/managementcenter/upload/uploadSave",$('#inputForm').serialize(),function(data){
+                    if(data.success){
+                        jp.getParent().refresh();
+                        var dialogIndex = parent.layer.getFrameIndex(window.name); // 获取窗口索引
+                        parent.layer.close(dialogIndex);
+                        jp.success(data.msg)
+                    }else{
+                        jp.error(data.msg);
+                    }
+                })
+			}
+
+        }
+	</script>
+</head>
+<body class="bg-white">
+		<form:form id="inputForm" modelAttribute="uploadImages" class="form-horizontal">
+		<form:hidden path="id"/>	
+		<table class="table table-bordered">
+		   <tbody>
+				<tr>
+					<td class="width-15 active"><label class="pull-right"><font color="red">*</font>图片路径:</label></td>
+					<td class="width-35">
+						<sys:fileUpload path="pic"  value="${uploadImages.path}" type="file" uploadPath="/list"/>
+					</td>
+				</tr>
+		 	</tbody>
+		</table>
+	</form:form>
+</body>
+</html>