浏览代码

部分代码优化

luoshi 6 年之前
父节点
当前提交
fd5ad5dfc6

+ 1 - 10
stmms-web/pom.xml

@@ -18,10 +18,6 @@
 			<groupId>cn.com.qmth.stmms</groupId>
 			<artifactId>stmms-biz</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>javax.servlet</groupId>
-			<artifactId>javax.servlet-api</artifactId>
-		</dependency>
 		<dependency>
 			<groupId>org.springframework</groupId>
 			<artifactId>spring-webmvc</artifactId>
@@ -41,6 +37,7 @@
 		<dependency>
 			<groupId>javax.servlet</groupId>
 			<artifactId>javax.servlet-api</artifactId>
+			<scope>provided</scope>
 		</dependency>
 		<dependency>
 			<groupId>javax.validation</groupId>
@@ -75,8 +72,6 @@
 					<webApp>
 						<contextPath>/</contextPath>
 					</webApp>
-					<stopKey>stmms</stopKey>
-					<stopPort>9999</stopPort>
 					<connectors>
 						<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
 							<port>8090</port>
@@ -92,10 +87,6 @@
 							<name>app.home</name>
 							<value>/Users/luoshi/develop/data/stmms-gx</value>
 						</systemProperty>
-						<systemProperty>
-							<name>local.ip</name>
-							<value>192.168.1.100</value>
-						</systemProperty>
 					</systemProperties>
 				</configuration>
 			</plugin>

+ 37 - 20
stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/LoginController.java

@@ -13,12 +13,14 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.servlet.ModelAndView;
 
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.model.Marker;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
 import cn.com.qmth.stmms.biz.exam.service.MarkerService;
 import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.biz.user.service.UserService;
 import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.MarkStatus;
 import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.session.model.StmmsSession;
 import cn.com.qmth.stmms.common.utils.Md5EncryptUtils;
@@ -38,7 +40,7 @@ public class LoginController {
 
     @Value("${index.logo}")
     private String indexLogo;
-    
+
     private static final String LOGIN_TYPE_KEY = "loginType";
 
     @RequestMapping("/")
@@ -48,8 +50,8 @@ public class LoginController {
 
     @RequestMapping(value = "/login", method = RequestMethod.GET)
     public ModelAndView login(HttpServletRequest request) {
-    	StmmsSession session = RequestUtils.getSession(request);
-        session.setParameter(LOGIN_TYPE_KEY,null);
+        StmmsSession session = RequestUtils.getSession(request);
+        session.setParameter(LOGIN_TYPE_KEY, null);
         ModelAndView view = new ModelAndView("modules/sys/login");
         view.addObject("indexLogo", indexLogo);
         view.addObject("showType", "admin-login");
@@ -57,10 +59,11 @@ public class LoginController {
     }
 
     @RequestMapping(value = "/login", method = RequestMethod.POST)
-    public ModelAndView login(User user, @RequestParam(required=false)String showType, HttpServletRequest request, HttpServletResponse response) {
-    	StmmsSession session = RequestUtils.getSession(request);
+    public ModelAndView login(User user, @RequestParam(required = false) String showType, HttpServletRequest request,
+            HttpServletResponse response) {
+        StmmsSession session = RequestUtils.getSession(request);
         String loginType = session.getParameter(LOGIN_TYPE_KEY);
-    	if ("admin-login".equals(showType)||"admin-login".equals(loginType)) {
+        if ("admin-login".equals(showType) || "admin-login".equals(loginType)) {
             User u = userService.findByLoginName(user.getLoginName());
             if (u != null) {
                 if (u.getPassword().equals(Md5EncryptUtils.md5(user.getPassword()))) {
@@ -95,7 +98,7 @@ public class LoginController {
                 modelAndView.addObject("indexLogo", indexLogo);
                 return modelAndView;
             }
-        } else if ("mark-login".equals(showType)||"mark-login".equals(loginType)) {
+        } else if ("mark-login".equals(showType) || "mark-login".equals(loginType)) {
             Marker marker = markerService.findByLoginName(user.getLoginName());
             if (marker != null) {
                 ModelAndView modelAndView = new ModelAndView("modules/sys/login");
@@ -111,6 +114,20 @@ public class LoginController {
                     modelAndView.addObject("indexLogo", indexLogo);
                     return modelAndView;
                 }
+                MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(),
+                        marker.getGroupNumber());
+                if (group == null) {
+                    modelAndView.addObject("message", "大题不存在");
+                    modelAndView.addObject("showType", showType);
+                    modelAndView.addObject("indexLogo", indexLogo);
+                    return modelAndView;
+                }
+                if (group.getStatus() == MarkStatus.FINISH) {
+                    modelAndView.addObject("message", "评卷已结束");
+                    modelAndView.addObject("showType", showType);
+                    modelAndView.addObject("indexLogo", indexLogo);
+                    return modelAndView;
+                }
 
                 new WebUser(marker.getId(), Role.MARKER).writeToSession(RequestUtils.getSession(request));
 
@@ -139,19 +156,19 @@ public class LoginController {
 
     @RequestMapping(value = "/admin-login", method = RequestMethod.GET)
     public ModelAndView adminIndex(HttpServletRequest request) {
-    	StmmsSession session = RequestUtils.getSession(request);
-    	session.setParameter(LOGIN_TYPE_KEY, "admin-login");
-    	ModelAndView view = new ModelAndView("modules/sys/login");
+        StmmsSession session = RequestUtils.getSession(request);
+        session.setParameter(LOGIN_TYPE_KEY, "admin-login");
+        ModelAndView view = new ModelAndView("modules/sys/login");
         view.addObject(LOGIN_TYPE_KEY, "admin-login");
         view.addObject("indexLogo", indexLogo);
         return view;
     }
-    
+
     @RequestMapping(value = "/mark-login", method = RequestMethod.GET)
     public ModelAndView markIndex(HttpServletRequest request) {
-    	StmmsSession session = RequestUtils.getSession(request);
-    	session.setParameter(LOGIN_TYPE_KEY, "mark-login");
-    	ModelAndView view = new ModelAndView("modules/sys/login");
+        StmmsSession session = RequestUtils.getSession(request);
+        session.setParameter(LOGIN_TYPE_KEY, "mark-login");
+        ModelAndView view = new ModelAndView("modules/sys/login");
         view.addObject(LOGIN_TYPE_KEY, "mark-login");
         view.addObject("indexLogo", indexLogo);
         return view;
@@ -170,12 +187,12 @@ public class LoginController {
         StmmsSession session = RequestUtils.getSession(request);
         String loginType = session.getParameter(LOGIN_TYPE_KEY);
         RequestUtils.getSession(request).setInvalid(true);
-        if("admin-login".equals(loginType)){
-        	return new ModelAndView("redirect:/admin-login");
-        }else if("mark-login".equals(loginType)){
-        	return new ModelAndView("redirect:/mark-login");
-        }else{
-        	return new ModelAndView("redirect:/login");
+        if ("admin-login".equals(loginType)) {
+            return new ModelAndView("redirect:/admin-login");
+        } else if ("mark-login".equals(loginType)) {
+            return new ModelAndView("redirect:/mark-login");
+        } else {
+            return new ModelAndView("redirect:/login");
         }
     }
 

+ 0 - 26
stmms-web/src/main/java/cn/com/qmth/stmms/common/utils/Start.java

@@ -1,26 +0,0 @@
-package cn.com.qmth.stmms.common.utils;
-
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
-
-public class Start {
-
-    public static void main(String[] args) throws Exception {
-        Server server = new Server();
-
-        SelectChannelConnector connector = new SelectChannelConnector();
-        connector.setPort(8090);
-        server.addConnector(connector);
-
-        WebAppContext context = new WebAppContext();
-
-        context.setContextPath("/");
-        context.setDescriptor("src/main/webapp/WEB-INF/web.xml");
-        context.setResourceBase("src/main/webapp");
-        server.setHandler(context);
-
-        server.start();
-
-    }
-}

+ 1 - 1
stmms-web/src/main/webapp/WEB-INF/application.properties

@@ -1,7 +1,7 @@
 #jdbc config
 driverClassName=com.mysql.jdbc.Driver
 #jdbc config
-url=jdbc:mysql://192.168.10.30:3306/stmms_ft_online?useUnicode=true&characterEncoding=UTF-8
+url=jdbc:mysql://localhost:3306/stmms_ft?useUnicode=true&characterEncoding=UTF-8
 username=root
 password=root
 

+ 11 - 40
stmms-web/src/main/webapp/WEB-INF/views/include/trialDetail.jsp

@@ -1,11 +1,12 @@
 <%@ page contentType="text/html;charset=UTF-8"%>
 <link rel="stylesheet" type="text/css" href="${ctxStatic}/jBox/Source/jBox.css">
 <script type="text/javascript" src="${ctxStatic}/jBox/Source/jBox.min.js"></script>
+<script type="text/javascript" src="${ctxStatic}/easy-canvas/easy-canvas.js"></script>
 
 <div id="trial-detail-content" class="container-fluid" style="display:none">
 <div class="row-fluid">
-    <div id="trial-left-div" class="span7">
-        <canvas id="trial-canvas" style="width:100%"></canvas>
+    <div id="trial-left-div" class="span7" style="overflow-y:scroll">
+        <canvas id="trial-canvas"></canvas>
     </div>
     <div id="trial-right-div" class="span5">
         <table id="contentTable" class="table table-striped table-bordered table-condensed">
@@ -26,9 +27,10 @@
 
 <script type="text/javascript">
 var trailDetailModal = new jBox('Modal');
+var trialCanvas = new EasyCanvas({canvas: document.getElementById('trial-canvas')});
 
 $(document).ready(function() {
-    //$('#trial-left-div').height($(window).height()*0.83);
+    $('#trial-left-div').height($(window).height()*0.83);
 });
 
 function initTrialDetailPopover(title, libraryId) {
@@ -36,11 +38,13 @@ function initTrialDetailPopover(title, libraryId) {
 	trailDetailModal.setWidth($(window).width()*0.9);
 	trailDetailModal.setHeight($(window).height()*0.85);
 	trailDetailModal.setTitle(title);
+	trailDetailModal.setContent($('#trial-detail-content'));
 	trailDetailModal.open();
 }
 
 function initTrialDetailContent(libraryId){
 	$('#trial-history').empty();
+	trialCanvas.clear();
 	$.ajax({
         type:"GET",
         url:'${ctx}/admin/exam/trial/detail?libraryId='+libraryId,  
@@ -51,11 +55,7 @@ function initTrialDetailContent(libraryId){
 	                var history = data.historyList[i];
 	                $('#trial-history').append('<tr><td>'+history.loginName+'</td><td>'+history.name+'</td><td>'+history.score+'</td><td>'+history.time+'</td></tr>');
 	            }
-	            var canvas = document.getElementById('trial-canvas');
-	            var ctx = canvas.getContext('2d');
-	            buildImages(data.imageServer, data.urls, data.pictureConfig, canvas, ctx, function(){
-	                trailDetailModal.setContent($('#trial-detail-content'));
-	            });
+	            buildImages(data.imageServer, data.urls, data.pictureConfig);
 	        }else {
 	            trailDetailModal.setTitle('加载失败')
 	        }
@@ -63,7 +63,7 @@ function initTrialDetailContent(libraryId){
     });
 }
 
-function buildImages(imageServer, picUrls, config, canvas, ctx, callback) {
+function buildImages(imageServer, picUrls, config) {
     var indexSet = {};
     for(var i=0;i<config.length;i++){
         indexSet[config[i].i-1] = true;
@@ -71,37 +71,8 @@ function buildImages(imageServer, picUrls, config, canvas, ctx, callback) {
     //调用图片预加载函数,实现回调函数
     var imageObjects = [];
     loadImages(imageObjects, imageServer, indexSet, picUrls, 0, function(images) {
-        var maxWidth = 0;
-        var totalHeight = 0;
-        for (var i = 0; i < config.length; i++) {
-            //计算最大宽度与合计高度
-            if(config[i].w<=0){
-                config[i].w=images[config[i].i-1].width;
-            }
-            if(config[i].h<=0){
-                config[i].h=images[config[i].i-1].height;
-            }
-            maxWidth = Math.max(maxWidth, config[i].w);
-            totalHeight += config[i].h;
-        }
-        if (maxWidth > 0 && totalHeight > 0) {
-            //设置画布大小及背景颜色
-            canvas.width = maxWidth;
-            canvas.height = totalHeight;
-            //ctx.fillStyle = "#FFFFFF";
-            //ctx.fillRect(0, 0, maxWidth, totalHeight);
-            //绘画到画布
-            var height = 0;
-            for (var i = 0; i < config.length; i++) {
-                var image = images[config[i].i-1];
-                ctx.drawImage(image, config[i].x, config[i].y, config[i].w, config[i].h, 0, height, config[i].w, config[i].h);
-                height += config[i].h;
-            }
-        }else {
-            canvas.width=1;
-            canvas.height=1;
-        }
-        callback();
+        trialCanvas.setMaxWidth($('#trial-left-div').width()*0.95);
+        trialCanvas.drawImages(images, config);
     });
 }
 

+ 6 - 5
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/trialList.jsp

@@ -33,10 +33,9 @@
                 </c:forEach>
             </select>
             <label>准考证号</label>
-            <input type="text" name="examNumber" value="${query.examNumber}" maxlength="20" class="input-medium"/>
-			&nbsp;
+            <input type="text" name="examNumber" value="${query.examNumber}" maxlength="20" class="input-small"/>
 			<label>考生编号</label>
-            <input type="text" name="studentId" value="${query.studentId}" maxlength="20" class="input-medium"/>
+            <input type="text" name="studentId" value="${query.studentId}" maxlength="20" class="input-small"/>
             &nbsp;
 			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
 		</div>
@@ -48,7 +47,8 @@
 				<th>科目代码</th>
 				<th>大题号</th>
 				<th>准考证号</th>
-				<th>已评人数</th>
+				<th>考生编号</th>
+				<th>评卷员</th>
 				<th>操作</th>
 			</tr>
 		</thead>
@@ -58,6 +58,7 @@
 				<td>${result.subjectCode}</td>
 				<td>${result.groupNumber}</td>
 				<td>${result.examNumber}</td>
+				<td>${result.studentId}</td>
 				<td>${result.markCount}</td>
 				<td>
 				    <c:if test="${result.markCount>0}">
@@ -76,7 +77,7 @@
 	<%@include file="/WEB-INF/views/include/trialDetail.jsp" %>
 <script type="text/javascript">
 $('.reset-link').click(function(){
-	if(!confirm('确定要重置该评任务吗?')){
+	if(!confirm('确定要重置该评任务吗?')){
 	    return;
 	}
 	$.post('${ctx}/admin/exam/trial/reset', {libraryId: $(this).attr('data-id')}, function(result){

+ 87 - 82
stmms-web/src/main/webapp/WEB-INF/web.xml

@@ -1,83 +1,88 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
-	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-	id="WebApp_ID" version="2.5">
-	<display-name>stmms-web</display-name>
-	<session-config>
-		<session-timeout>300</session-timeout>
-	</session-config>
-
-	<listener>
-		<description>spring监听器</description>
-		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
-	</listener>
-	<listener>
-		<description>Introspector缓存清除监听器</description>
-		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
-	</listener>
-
-	<filter>
-		<description>字符集过滤器</description>
-		<filter-name>encodingFilter</filter-name>
-		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
-		<init-param>
-			<description>字符集编码</description>
-			<param-name>encoding</param-name>
-			<param-value>UTF-8</param-value>
-		</init-param>
-	</filter>
-	<filter>
-		<filter-name>sessionCookieFilter</filter-name>
-		<filter-class>cn.com.qmth.stmms.common.filter.SessionFilter</filter-class>
-		<init-param>
-			<param-name>excludeURI</param-name>
-			<param-value>/api,/static,/file</param-value>
-		</init-param>
-	</filter>
-	<filter>
-		<filter-name>characterEncodingFilter</filter-name>
-		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
-		<init-param>
-			<param-name>encoding</param-name>
-			<param-value>utf-8</param-value>
-		</init-param>
-	</filter>
-	<filter>
-		<filter-name>sitemeshFilter</filter-name>
-		<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
-	</filter>
-
-  
-	<filter-mapping>
-		<filter-name>characterEncodingFilter</filter-name>
-		<servlet-name>stmms-web</servlet-name>
-	</filter-mapping>
-	<filter-mapping>
-		<filter-name>encodingFilter</filter-name>
-		<servlet-name>stmms-web</servlet-name>
-	</filter-mapping>
-	<filter-mapping>
-		<filter-name>sessionCookieFilter</filter-name>
-		<servlet-name>stmms-web</servlet-name>
-	</filter-mapping>
-	<filter-mapping>
-		<filter-name>sitemeshFilter</filter-name>
-		<servlet-name>stmms-web</servlet-name>
-	</filter-mapping>
-	
-	<servlet>
-		<servlet-name>stmms-web</servlet-name>
-		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-		<init-param>
-			<param-name>contextConfigLocation</param-name>
-			<param-value>/WEB-INF/spring-mvc.xml</param-value>
-		</init-param>
-		<load-on-startup>1</load-on-startup>
-	</servlet>
-	<servlet-mapping>
-		<servlet-name>stmms-web</servlet-name>
-		<url-pattern>/</url-pattern>
-	</servlet-mapping>
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns="http://java.sun.com/xml/ns/javaee"
+	xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
+	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+	id="WebApp_ID" version="2.5">
+	<display-name>stmms-web</display-name>
+	<session-config>
+		<session-timeout>300</session-timeout>
+	</session-config>
+
+	<listener>
+		<description>spring监听器</description>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+	<listener>
+		<description>Introspector缓存清除监听器</description>
+		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
+	</listener>
+
+	<filter>
+		<description>字符集过滤器</description>
+		<filter-name>encodingFilter</filter-name>
+		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
+		<init-param>
+			<description>字符集编码</description>
+			<param-name>encoding</param-name>
+			<param-value>UTF-8</param-value>
+		</init-param>
+	</filter>
+	<filter>
+		<filter-name>sessionCookieFilter</filter-name>
+		<filter-class>cn.com.qmth.stmms.common.filter.SessionFilter</filter-class>
+		<init-param>
+			<param-name>excludeURI</param-name>
+			<param-value>/api,/static,/file</param-value>
+		</init-param>
+	</filter>
+	<filter>
+		<filter-name>characterEncodingFilter</filter-name>
+		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
+		<init-param>
+			<param-name>encoding</param-name>
+			<param-value>utf-8</param-value>
+		</init-param>
+	</filter>
+	<filter>
+		<filter-name>sitemeshFilter</filter-name>
+		<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
+	</filter>
+
+
+	<filter-mapping>
+		<filter-name>characterEncodingFilter</filter-name>
+		<servlet-name>stmms-web</servlet-name>
+	</filter-mapping>
+	<filter-mapping>
+		<filter-name>encodingFilter</filter-name>
+		<servlet-name>stmms-web</servlet-name>
+	</filter-mapping>
+	<filter-mapping>
+		<filter-name>sessionCookieFilter</filter-name>
+		<servlet-name>stmms-web</servlet-name>
+	</filter-mapping>
+	<filter-mapping>
+		<filter-name>sitemeshFilter</filter-name>
+		<servlet-name>stmms-web</servlet-name>
+	</filter-mapping>
+
+	<servlet>
+		<servlet-name>stmms-web</servlet-name>
+		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+		<init-param>
+			<param-name>contextConfigLocation</param-name>
+			<param-value>/WEB-INF/spring-mvc.xml</param-value>
+		</init-param>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>stmms-web</servlet-name>
+		<url-pattern>/</url-pattern>
+	</servlet-mapping>
+
+	<welcome-file-list>
+		<welcome-file></welcome-file>
+	</welcome-file-list>
 </web-app>

+ 120 - 0
stmms-web/src/main/webapp/static/easy-canvas/easy-canvas.js

@@ -0,0 +1,120 @@
+function EasyCanvas(option) {
+    this.canvas = option.canvas
+    this.context = this.canvas.getContext("2d")
+    this.ratio = this.getPixelRatio()
+    this.originSize = {}
+
+    if (option.maxWidth != undefined && option.maxWidth > 0) {
+        this.maxWidth = option.maxWidth
+    } else if (option.maxHeight != undefined && option.maxHeight > 0) {
+        this.maxHeight = option.maxHeight
+    }
+}
+
+EasyCanvas.prototype.setMaxWidth = function(width) {
+    if (width != undefined) {
+        this.maxWidth = width
+        this.maxHeight = undefined
+        this.onSizeChange()
+    }
+}
+
+EasyCanvas.prototype.setMaxHeight = function(height) {
+    if (height != undefined) {
+        this.maxHeight = height
+        this.maxWidth = undefined
+        this.onSizeChange()
+    }
+}
+
+EasyCanvas.prototype.getPixelRatio = function() {
+    let backingStore = this.context.backingStorePixelRatio ||
+        this.context.webkitBackingStorePixelRatio ||
+        this.context.mozBackingStorePixelRatio ||
+        this.context.msBackingStorePixelRatio ||
+        this.context.oBackingStorePixelRatio ||
+        this.context.backingStorePixelRatio || 1;
+    return (window.devicePixelRatio || 1) / backingStore;
+}
+
+EasyCanvas.prototype.clear = function() {
+    this.context.clearRect(0, 0, this.canvas.width, this.canvas.heigth)
+}
+
+EasyCanvas.prototype.resize = function(width, height) {
+    this.originSize = {
+        width: width || 0,
+        height: height || 0
+    }
+    this.canvas.width = this.originSize.width * this.ratio
+    this.canvas.height = this.originSize.height * this.ratio
+    this.context.scale(this.ratio, this.ratio)
+    this.clear()
+    this.onSizeChange()
+}
+
+EasyCanvas.prototype.onSizeChange = function() {
+    let width, height
+    if (this.originSize.width == 0 || this.originSize.height == 0) {
+        width = 0
+        height = 0
+    } else if (this.maxWidth != undefined) {
+        width = Math.min(this.originSize.width, this.maxWidth)
+        height = width * this.originSize.heigth / this.originSize.width
+    } else if (this.maxHeigth != undefined) {
+        height = Math.min(this.originSize.height, this.maxHeight)
+        width = width * this.originSize.heigth / this.originSize.width
+    } else {
+        width = this.originSize.width
+        height = this.originSize.height
+    }
+    this.canvas.style.width = width + 'px'
+    this.canvas.style.height = height + 'px'
+}
+
+EasyCanvas.prototype.drawImages = function(images, configs) {
+    let indexSet = {}
+    if (configs == undefined || configs.length == 0) {
+        //不指定拼接配置时,默认按顺序显示所有图片
+        configs = []
+        for (let i = 0; i < images.length; i++) {
+            configs.push({
+                i: i + 1,
+                x: 0,
+                y: 0,
+                w: 0,
+                h: 0
+            })
+            indexSet[i] = true
+        }
+    } else {
+        for (let i = 0; i < configs.length; i++) {
+            indexSet[configs[i].i - 1] = true;
+        }
+    }
+    let maxWidth = 0;
+    let totalHeight = 0;
+    for (let i = 0; i < configs.length; i++) {
+        //计算最大宽度与合计高度
+        if (configs[i].w <= 0) {
+            configs[i].w = images[configs[i].i - 1].width;
+        }
+        if (configs[i].h <= 0) {
+            configs[i].h = images[configs[i].i - 1].height;
+        }
+        maxWidth = Math.max(maxWidth, configs[i].w);
+        totalHeight += configs[i].h;
+    }
+    if (maxWidth > 0 && totalHeight > 0) {
+        //设置画布大小
+        this.resize(maxWidth, totalHeight)
+        //绘画到画布
+        let height = 0;
+        for (let i = 0; i < configs.length; i++) {
+            this.context.drawImage(images[configs[i].i - 1], configs[i].x, configs[i].y, configs[i].w, configs[i].h, 0, height, configs[i].w, configs[i].h);
+            height += configs[i].h;
+        }
+    } else {
+        this.resize()
+    }
+}