瀏覽代碼

日志,会议

蔡德晨 5 年之前
父節點
當前提交
e3ac20e77f
共有 100 個文件被更改,包括 37109 次插入3 次删除
  1. 21 0
      src/main/java/com/jeeplus/common/bos/BosController.java
  2. 215 0
      src/main/java/com/jeeplus/common/utils/HttpClientUtil.java
  3. 18 0
      src/main/java/com/jeeplus/common/utils/MyX509TrustManager.java
  4. 20 0
      src/main/java/com/jeeplus/modules/projectcontroltable/entity/ProjectControlTable.java
  5. 105 2
      src/main/java/com/jeeplus/modules/projectcontroltable/service/ProjectControlTableService.java
  6. 11 0
      src/main/java/com/jeeplus/modules/projectcontroltable/web/ProjectControlTableController.java
  7. 17 0
      src/main/java/com/jeeplus/modules/worklog/dao/WorkLogDao.java
  8. 18 0
      src/main/java/com/jeeplus/modules/worklog/dao/WorkMeetingDao.java
  9. 130 0
      src/main/java/com/jeeplus/modules/worklog/entity/WorkLog.java
  10. 128 0
      src/main/java/com/jeeplus/modules/worklog/entity/WorkMeeting.java
  11. 56 0
      src/main/java/com/jeeplus/modules/worklog/service/WorkLogService.java
  12. 57 0
      src/main/java/com/jeeplus/modules/worklog/service/WorkMeetingService.java
  13. 211 0
      src/main/java/com/jeeplus/modules/worklog/web/WorkLogController.java
  14. 195 0
      src/main/java/com/jeeplus/modules/worklog/web/WorkMeetingController.java
  15. 184 0
      src/main/resources/mappings/modules/worklog/WorkLogDao.xml
  16. 186 0
      src/main/resources/mappings/modules/worklog/WorkMeetingDao.xml
  17. 1 1
      src/main/webapp/WEB-INF/tags/sys/treeselect.tag
  18. 22790 0
      src/main/webapp/static/json/city.json
  19. 15 0
      src/main/webapp/static/kindeditor/jsp/README.txt
  20. 56 0
      src/main/webapp/static/kindeditor/jsp/demo.jsp
  21. 156 0
      src/main/webapp/static/kindeditor/jsp/file_manager_json.jsp
  22. 二進制
      src/main/webapp/static/kindeditor/jsp/lib/commons-fileupload-1.2.1.jar
  23. 二進制
      src/main/webapp/static/kindeditor/jsp/lib/commons-io-1.4.jar
  24. 二進制
      src/main/webapp/static/kindeditor/jsp/lib/json_simple-1.1.jar
  25. 129 0
      src/main/webapp/static/kindeditor/jsp/upload_json.jsp
  26. 7 0
      src/main/webapp/static/kindeditor/kindeditor-all-min.js
  27. 9849 0
      src/main/webapp/static/kindeditor/kindeditor-all.js
  28. 242 0
      src/main/webapp/static/kindeditor/lang/ar.js
  29. 241 0
      src/main/webapp/static/kindeditor/lang/en.js
  30. 246 0
      src/main/webapp/static/kindeditor/lang/ko.js
  31. 242 0
      src/main/webapp/static/kindeditor/lang/ru.js
  32. 238 0
      src/main/webapp/static/kindeditor/lang/zh-CN.js
  33. 243 0
      src/main/webapp/static/kindeditor/lang/zh-TW.js
  34. 502 0
      src/main/webapp/static/kindeditor/license.txt
  35. 46 0
      src/main/webapp/static/kindeditor/plugins/anchor/anchor.js
  36. 54 0
      src/main/webapp/static/kindeditor/plugins/autoheight/autoheight.js
  37. 93 0
      src/main/webapp/static/kindeditor/plugins/baidumap/baidumap.js
  38. 83 0
      src/main/webapp/static/kindeditor/plugins/baidumap/index.html
  39. 43 0
      src/main/webapp/static/kindeditor/plugins/baidumap/map.html
  40. 29 0
      src/main/webapp/static/kindeditor/plugins/clearhtml/clearhtml.js
  41. 62 0
      src/main/webapp/static/kindeditor/plugins/code/code.js
  42. 13 0
      src/main/webapp/static/kindeditor/plugins/code/prettify.css
  43. 28 0
      src/main/webapp/static/kindeditor/plugins/code/prettify.js
  44. 129 0
      src/main/webapp/static/kindeditor/plugins/emoticons/emoticons.js
  45. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/0.gif
  46. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/1.gif
  47. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/10.gif
  48. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/100.gif
  49. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/101.gif
  50. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/102.gif
  51. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/103.gif
  52. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/104.gif
  53. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/105.gif
  54. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/106.gif
  55. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/107.gif
  56. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/108.gif
  57. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/109.gif
  58. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/11.gif
  59. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/110.gif
  60. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/111.gif
  61. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/112.gif
  62. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/113.gif
  63. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/114.gif
  64. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/115.gif
  65. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/116.gif
  66. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/117.gif
  67. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/118.gif
  68. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/119.gif
  69. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/12.gif
  70. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/120.gif
  71. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/121.gif
  72. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/122.gif
  73. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/123.gif
  74. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/124.gif
  75. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/125.gif
  76. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/126.gif
  77. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/127.gif
  78. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/128.gif
  79. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/129.gif
  80. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/13.gif
  81. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/130.gif
  82. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/131.gif
  83. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/132.gif
  84. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/133.gif
  85. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/134.gif
  86. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/14.gif
  87. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/15.gif
  88. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/16.gif
  89. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/17.gif
  90. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/18.gif
  91. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/19.gif
  92. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/2.gif
  93. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/20.gif
  94. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/21.gif
  95. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/22.gif
  96. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/23.gif
  97. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/24.gif
  98. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/25.gif
  99. 二進制
      src/main/webapp/static/kindeditor/plugins/emoticons/images/26.gif
  100. 0 0
      src/main/webapp/static/kindeditor/plugins/emoticons/images/27.gif

+ 21 - 0
src/main/java/com/jeeplus/common/bos/BosController.java

@@ -33,4 +33,25 @@ public class BosController {
         }
         return map;
     }
+
+    @RequestMapping("uploadPic")
+    @ResponseBody
+    public Map uploadPic(MultipartFile uploadFile){
+        Map map = new HashMap();
+        try {
+            String name = uploadFile.getOriginalFilename();
+            String path = "/picture/"+System.currentTimeMillis()+"/"+name;
+            BOSClientUtil bosClientUtil = new BOSClientUtil();
+            InputStream inputStream = uploadFile.getInputStream();
+            String upload = bosClientUtil.upload(path, inputStream);
+            map.put("msg","上传成功");
+            map.put("code","1");
+            map.put("url",upload);
+        }catch (Exception e){
+            map.put("msg","上传失败");
+            map.put("code","0");
+        }
+        return map;
+    }
+
 }

+ 215 - 0
src/main/java/com/jeeplus/common/utils/HttpClientUtil.java

@@ -0,0 +1,215 @@
+package com.jeeplus.common.utils;
+
+
+
+import net.sf.json.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.ParseException;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+//import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import java.io.*;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class HttpClientUtil {
+
+	protected static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
+
+
+    /**
+     * 发起https请求并获取结果
+     * 
+     * @param requestUrl 请求地址
+     * @param requestMethod 请求方式(GET、POST)
+     * @param outputStr 提交的数据
+     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
+     */
+    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
+        JSONObject jsonObject = null;
+        StringBuffer buffer = new StringBuffer();
+        try {
+                // 创建SSLContext对象,并使用我们指定的信任管理器初始化
+//                TrustManager[] tm = { new MyX509TrustManager() };
+//                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
+//                sslContext.init(null, tm, new java.security.SecureRandom());
+//                // 从上述SSLContext对象中得到SSLSocketFactory对象
+//                SSLSocketFactory ssf = sslContext.getSocketFactory();
+
+                URL url = new URL(requestUrl);
+                HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
+//                httpUrlConn.setSSLSocketFactory(ssf);
+
+                httpUrlConn.setDoOutput(true);
+                httpUrlConn.setDoInput(true);
+                httpUrlConn.setUseCaches(false);
+                // 设置请求方式(GET/POST)
+                httpUrlConn.setRequestMethod(requestMethod);
+
+                if ("GET".equalsIgnoreCase(requestMethod))
+                        httpUrlConn.connect();
+
+                // 当有数据需要提交时
+                if (null != outputStr) {
+                        OutputStream outputStream = httpUrlConn.getOutputStream();
+                        // 注意编码格式,防止中文乱码
+                        outputStream.write(outputStr.getBytes("UTF-8"));
+                        outputStream.close();
+                }
+
+                // 将返回的输入流转换成字符串
+                InputStream inputStream = httpUrlConn.getInputStream();
+                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
+                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+
+                String str = null;
+                while ((str = bufferedReader.readLine()) != null) {
+                        buffer.append(str);
+                }
+                bufferedReader.close();
+                inputStreamReader.close();
+                // 释放资源
+                inputStream.close();
+                inputStream = null;
+                httpUrlConn.disconnect();
+                jsonObject = JSONObject.fromObject(buffer.toString());
+                System.out.println(jsonObject);
+        } catch (ConnectException ce) {
+        	ce.printStackTrace();
+        } catch (Exception e) {
+        	e.printStackTrace();
+        }
+        return jsonObject;
+    }
+    
+    
+    
+    public static String post(String url, Map<String, String> params) {  
+        DefaultHttpClient httpclient = new DefaultHttpClient();
+        String body = null;  
+          
+        HttpPost post = postForm(url, params);
+          
+        body = invoke(httpclient, post);  
+          
+        httpclient.getConnectionManager().shutdown();  
+          
+        return body;  
+    }  
+      
+    public static String get(String url) {  
+        DefaultHttpClient httpclient = new DefaultHttpClient();
+        String body = null;  
+        
+        HttpGet get = new HttpGet(url);
+        body = invoke(httpclient, get);  
+          
+        httpclient.getConnectionManager().shutdown();  
+          
+        return body;  
+    }  
+          
+      
+    public static String invoke(DefaultHttpClient httpclient,
+                                HttpUriRequest httpost) {
+          
+        HttpResponse response = sendRequest(httpclient, httpost);
+        String body = paseResponse(response);  
+          
+        return body;  
+    }  
+  
+    private static String paseResponse(HttpResponse response) {
+        HttpEntity entity = response.getEntity();
+
+        String charset = "GB2312";  
+
+        String body = null;  
+        try {  
+            body = EntityUtils.toString(entity,charset);
+        } catch (ParseException e) {
+            e.printStackTrace();  
+        } catch (IOException e) {  
+            e.printStackTrace();  
+        }  
+          
+        return body;  
+    }  
+  
+    private static HttpResponse sendRequest(DefaultHttpClient httpclient,
+                                            HttpUriRequest httpost) {
+        HttpResponse response = null;
+          
+        try {  
+            response = httpclient.execute(httpost);  
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();  
+        } catch (IOException e) {  
+            e.printStackTrace();  
+        }  
+        return response;  
+    }  
+  
+    private static HttpPost postForm(String url, Map<String, String> params){
+          
+        HttpPost httpost = new HttpPost(url);
+        List<NameValuePair> nvps = new ArrayList <NameValuePair>();
+          
+        Set<String> keySet = params.keySet();  
+        for(String key : keySet) {  
+            nvps.add(new BasicNameValuePair(key, params.get(key)));
+        }  
+          
+        try { 
+            httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
+        } catch (UnsupportedEncodingException e) {  
+            e.printStackTrace();  
+        }  
+          
+        return httpost;  
+    } 
+    
+	public static String httpPostWithJSON(String url, String json) throws Exception {
+		String body="";
+		try {
+			// 将JSON进行UTF-8编码,以便传输中文
+			HttpClient httpClient = new DefaultHttpClient();
+			HttpPost httpPost = new HttpPost(url);
+			httpPost.addHeader("Content-type","application/json; charset=utf-8");  
+			httpPost.setHeader("Accept", "application/json");  
+			StringEntity se = new StringEntity(json, Charset.forName("UTF-8"));
+			httpPost.setEntity(se);
+			HttpResponse response = httpClient.execute(httpPost);
+			body = EntityUtils.toString(response.getEntity());
+		} catch (Exception e) {
+			logger.error("请求"+url+"报错,报错信息:"+e.getMessage());
+		} finally {
+			return body;
+		}
+	}
+   
+    
+}

+ 18 - 0
src/main/java/com/jeeplus/common/utils/MyX509TrustManager.java

@@ -0,0 +1,18 @@
+package com.jeeplus.common.utils;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+public class MyX509TrustManager implements X509TrustManager {
+
+	public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	}
+
+	public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	}
+
+	public X509Certificate[] getAcceptedIssuers() {
+		return null;
+	}
+}

+ 20 - 0
src/main/java/com/jeeplus/modules/projectcontroltable/entity/ProjectControlTable.java

@@ -13,6 +13,8 @@ import com.jeeplus.modules.workdevicerecord.entity.WorkDeviceXjRecord;
 import com.jeeplus.modules.workexplore.entity.WorkExplore;
 import com.jeeplus.modules.workhandbill.entity.WorkHandBill;
 import com.jeeplus.modules.workinfolist.entity.WorkInfoList;
+import com.jeeplus.modules.worklog.entity.WorkLog;
+import com.jeeplus.modules.worklog.entity.WorkMeeting;
 import com.jeeplus.modules.workprojectcalc.entity.WorkProjectCalcBuild;
 import com.jeeplus.modules.workprojectcalc.entity.WorkProjectCalcDecor;
 
@@ -39,6 +41,8 @@ public class ProjectControlTable extends DataEntity<ProjectControlTable> {
 	private List<WorkProjectCalcBuild> workProjectCalcBuildList = Lists.newArrayList();
 	private List<WorkProjectCalcDecor> workProjectCalcDecorList = Lists.newArrayList();
 	private WorkHandBill workHandBill;
+	private WorkLog  workLog;
+	private WorkMeeting workMeeting;
 
 	public ProjectControlTable() {
 		super();
@@ -153,4 +157,20 @@ public class ProjectControlTable extends DataEntity<ProjectControlTable> {
 	public void setWorkHandBill(WorkHandBill workHandBill) {
 		this.workHandBill = workHandBill;
 	}
+
+	public WorkLog getWorkLog() {
+		return workLog;
+	}
+
+	public void setWorkLog(WorkLog workLog) {
+		this.workLog = workLog;
+	}
+
+	public WorkMeeting getWorkMeeting() {
+		return workMeeting;
+	}
+
+	public void setWorkMeeting(WorkMeeting workMeeting) {
+		this.workMeeting = workMeeting;
+	}
 }

+ 105 - 2
src/main/java/com/jeeplus/modules/projectcontroltable/service/ProjectControlTableService.java

@@ -40,6 +40,10 @@ import com.jeeplus.modules.workhandbill.service.WorkHandBillService;
 import com.jeeplus.modules.workinfolist.dao.WorkInfoListDao;
 import com.jeeplus.modules.workinfolist.entity.WorkInfoList;
 import com.jeeplus.modules.workinfolist.service.WorkInfoListService;
+import com.jeeplus.modules.worklog.dao.WorkLogDao;
+import com.jeeplus.modules.worklog.dao.WorkMeetingDao;
+import com.jeeplus.modules.worklog.entity.WorkLog;
+import com.jeeplus.modules.worklog.entity.WorkMeeting;
 import com.jeeplus.modules.workprojectcalc.dao.WorkProjectCalcBuildDao;
 import com.jeeplus.modules.workprojectcalc.dao.WorkProjectCalcDecorDao;
 import com.jeeplus.modules.workprojectcalc.entity.WorkProjectCalcBuild;
@@ -108,6 +112,10 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
     private WorkProjectCalcDecorService workProjectCalcDecorService;
     @Autowired
     private WorkProjectCalcBuildService workProjectCalcBuildService;
+    @Autowired
+	private WorkLogDao workLogDao;
+    @Autowired
+	private WorkMeetingDao workMeetingDao;
 
 
 
@@ -139,6 +147,10 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
 			execproject(projectControlTable);
 		} else if ("06".equals(s)) {
 			execHandBill(projectControlTable);
+		} else if("07".equals(s)){
+            execLog(projectControlTable);
+		}  else if("08".equals(s)){
+            execMeeting(projectControlTable);
 		}
 
 		List<Workattachment> workAttachments = projectControlTable.getWorkAttachments();
@@ -159,6 +171,10 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
 						workattachment.setAttachmentFlag("92");
 					} else if ("06".equals(s)) {	// 交接单
 						workattachment.setAttachmentFlag("93");
+					} else if("07".equals(s)){      //日志
+						workattachment.setAttachmentFlag("93");
+					} else if("08".equals(s)){      //会议
+						workattachment.setAttachmentFlag("93");
 					}
 					workattachment.setAttachmentUser(UserUtils.getUser().getId());
 					if (Strings.isNullOrEmpty(workattachment.getId()) || "null".equals(workattachment.getId())) {
@@ -337,6 +353,51 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
 		}
 	}
 	/**
+	 *	日志
+	 * @param projectControlTable
+	 */
+	public void execLog(ProjectControlTable projectControlTable){
+		WorkLog workLog = projectControlTable.getWorkLog();
+		if(workLog != null){
+			if(WorkLog.DEL_FLAG_NORMAL.equals(workLog.getDelFlag())){
+				if(workLog.getIsNewRecord()){
+					workLog.setProjectId(projectControlTable.getId());
+					workLog.preInsert();
+					workLogDao.insert(workLog);
+				}else{
+					workLog.preUpdate();
+					workLogDao.update(workLog);
+				}
+			}else{
+				workLogDao.delete(workLog);
+			}
+		}
+	}
+
+	/**
+	 *	会议
+	 * @param projectControlTable
+	 */
+	public void execMeeting(ProjectControlTable projectControlTable){
+		WorkMeeting workMeeting = projectControlTable.getWorkMeeting();
+
+		if(workMeeting != null){
+			if(WorkLog.DEL_FLAG_NORMAL.equals(workMeeting.getDelFlag())){
+				if(workMeeting.getIsNewRecord()){
+					workMeeting.setProjectId(projectControlTable.getId());
+					workMeeting.preInsert();
+					workMeetingDao.insert(workMeeting);
+				}else{
+					workMeeting.preUpdate();
+					workMeetingDao.update(workMeeting);
+				}
+			}else{
+				workMeetingDao.delete(workMeeting);
+			}
+		}
+	}
+
+	/**
 	 *	交接单
 	 * @param projectControlTable
 	 */
@@ -374,6 +435,7 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
 			}
 		}
 	}
+
 	@Transactional(readOnly = false)
 	public void delete(ProjectControlTable projectControlTable) {
 		super.delete(projectControlTable);
@@ -535,6 +597,34 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
 					for (Workattachment workattachment:listOfAttachment){
 						workattachmentService.deleteFileFromAliyun(workattachment,workattachment.getUrl());
 					}
+				}else if("07".equals(s)){
+					//日志
+					WorkLog workLog = new WorkLog();
+					workLog.setProjectId(tableId);
+					int i4 = workLogDao.deleteByProId(workLog);
+					if(i4 > 0){
+						flag = true;
+					}else{
+						break;
+					}
+					List<Workattachment> listOfAttachment = workattachmentDao.getListOfAttachment(tableId, "93");
+					for (Workattachment workattachment:listOfAttachment){
+						workattachmentService.deleteFileFromAliyun(workattachment,workattachment.getUrl());
+					}
+				}else if("08".equals(s)){
+					//会议
+					WorkMeeting workMeeting = new WorkMeeting();
+					workMeeting.setProjectId(tableId);
+					int i4 = workMeetingDao.deleteByProId(workMeeting);
+					if(i4 > 0){
+						flag = true;
+					}else{
+						break;
+					}
+					List<Workattachment> listOfAttachment = workattachmentDao.getListOfAttachment(tableId, "93");
+					for (Workattachment workattachment:listOfAttachment){
+						workattachmentService.deleteFileFromAliyun(workattachment,workattachment.getUrl());
+					}
 				}
 			}
 
@@ -634,7 +724,20 @@ public class ProjectControlTableService extends CrudService<ProjectControlTableD
             workDeviceXjRecord.setWorkDeviceRecordList(listByXjId1);
             projectControlTable.setWorkDeviceXjRecord(workDeviceXjRecord);
             flag = "88";
-        }
-        return flag;
+        }else if ("07".equals(s)) {
+			WorkLog workLog = new WorkLog();
+			workLog.setProjectId(projectControlTable.getId());
+			WorkLog listByProId = workLogDao.findListByProId(workLog);
+			projectControlTable.setWorkLog(listByProId);
+			flag = "93";
+		}else if("08".equals(s)){
+			WorkMeeting workMeeting = new WorkMeeting();
+			workMeeting.setProjectId(projectControlTable.getId());
+			WorkMeeting listByProId = workMeetingDao.findListByProId(workMeeting);
+			projectControlTable.setWorkMeeting(listByProId);
+			flag = "93";
+
+		}
+		return flag;
     }
 }

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

@@ -15,6 +15,9 @@ 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.projectrecord.entity.ProjectRecords;
+import com.jeeplus.modules.projectrecord.service.ProjectRecordsService;
+import com.jeeplus.modules.sys.entity.Area;
 import com.jeeplus.modules.sys.entity.Workattachment;
 import com.jeeplus.modules.sys.service.WorkattachmentService;
 import com.jeeplus.modules.sys.utils.UserUtils;
@@ -66,6 +69,8 @@ public class ProjectControlTableController extends BaseController {
 	private ProjectControlTableService projectControlTableService;
 	@Autowired
 	private WorkattachmentService workattachmentService;
+	@Autowired
+	private ProjectRecordsService projectRecordsService;
 
 	@ModelAttribute
 	public ProjectControlTable get(@RequestParam(required=false) String id) {
@@ -101,12 +106,18 @@ public class ProjectControlTableController extends BaseController {
 			view = "modules/projectcontroltable/projectControlTableFormView";
 		}else{
 			view = "modules/projectcontroltable/projectControlTableForm";
+			if(projectControlTable.getPfId()!= null){
+				ProjectRecords projectRecords = projectRecordsService.get(projectControlTable.getPfId());
+				Area area = projectRecords.getArea();
+				model.addAttribute("area", area);
+			}
 		}
 		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;
 	}

+ 17 - 0
src/main/java/com/jeeplus/modules/worklog/dao/WorkLogDao.java

@@ -0,0 +1,17 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.worklog.entity.WorkLog;
+
+
+@MyBatisDao
+public interface WorkLogDao extends CrudDao<WorkLog> {
+
+    int deleteByProId(WorkLog workLog);
+
+    WorkLog findListByProId(WorkLog workLog);
+}

+ 18 - 0
src/main/java/com/jeeplus/modules/worklog/dao/WorkMeetingDao.java

@@ -0,0 +1,18 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.worklog.entity.WorkLog;
+import com.jeeplus.modules.worklog.entity.WorkMeeting;
+
+
+@MyBatisDao
+public interface WorkMeetingDao extends CrudDao<WorkMeeting> {
+
+    int deleteByProId(WorkMeeting workMeeting);
+
+    WorkMeeting findListByProId(WorkMeeting workMeeting);
+}

+ 130 - 0
src/main/java/com/jeeplus/modules/worklog/entity/WorkLog.java

@@ -0,0 +1,130 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.entity;
+
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.modules.sys.entity.Area;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+import java.util.Date;
+import java.util.List;
+
+
+public class WorkLog extends DataEntity<WorkLog> {
+
+	private static final long serialVersionUID = 1L;
+	private String projectId;		// 项目编号
+	private String logType;     //日志类型
+	private Date startDate;     //日期
+	private Area area;      //区域
+	private String address;   //详细地址
+	private String weather;  //天气
+	private String lowTem; //低温
+	private String highTem; //高温
+	private String theme;    //日志主题
+	private String content;   //内容
+	private String wind;
+
+	public String getWind() {
+		return wind;
+	}
+
+	public void setWind(String wind) {
+		this.wind = wind;
+	}
+
+	public String getLogType() {
+		return logType;
+	}
+
+	public void setLogType(String logType) {
+		this.logType = logType;
+	}
+
+	public Date getStartDate() {
+		return startDate;
+	}
+
+	public void setStartDate(Date startDate) {
+		this.startDate = startDate;
+	}
+
+
+
+	public String getAddress() {
+		return address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+
+	public String getWeather() {
+		return weather;
+	}
+
+	public void setWeather(String weather) {
+		this.weather = weather;
+	}
+
+	public String getLowTem() {
+		return lowTem;
+	}
+
+	public void setLowTem(String lowTem) {
+		this.lowTem = lowTem;
+	}
+
+	public String getHighTem() {
+		return highTem;
+	}
+
+	public void setHighTem(String highTem) {
+		this.highTem = highTem;
+	}
+
+	public String getTheme() {
+		return theme;
+	}
+
+	public void setTheme(String theme) {
+		this.theme = theme;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+
+	public WorkLog() {
+		super();
+	}
+
+	public WorkLog(String id){
+		super(id);
+	}
+
+
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+
+	public Area getArea() {
+		return area;
+	}
+
+	public void setArea(Area area) {
+		this.area = area;
+	}
+}

+ 128 - 0
src/main/java/com/jeeplus/modules/worklog/entity/WorkMeeting.java

@@ -0,0 +1,128 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.entity;
+
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.modules.sys.entity.Area;
+
+import java.util.Date;
+
+
+public class WorkMeeting extends DataEntity<WorkMeeting> {
+
+	private static final long serialVersionUID = 1L;
+	private String projectId;		// 项目编号
+	private String meetType;     //类型
+	private Date startDate;     //日期
+	private Area area;      //区域
+	private String address;   //详细地址
+	private String weather;  //天气
+	private String lowTem; //低温
+	private String highTem; //高温
+	private String theme;    //主题
+	private String content;   //内容
+	private String wind;
+
+
+	public String getWind() {
+		return wind;
+	}
+
+	public void setWind(String wind) {
+		this.wind = wind;
+	}
+
+	public String getMeetType() {
+		return meetType;
+	}
+
+	public void setMeetType(String meetType) {
+		this.meetType = meetType;
+	}
+
+	public Date getStartDate() {
+		return startDate;
+	}
+
+	public void setStartDate(Date startDate) {
+		this.startDate = startDate;
+	}
+
+
+
+	public String getAddress() {
+		return address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+
+	public String getWeather() {
+		return weather;
+	}
+
+	public void setWeather(String weather) {
+		this.weather = weather;
+	}
+
+	public String getLowTem() {
+		return lowTem;
+	}
+
+	public void setLowTem(String lowTem) {
+		this.lowTem = lowTem;
+	}
+
+	public String getHighTem() {
+		return highTem;
+	}
+
+	public void setHighTem(String highTem) {
+		this.highTem = highTem;
+	}
+
+	public String getTheme() {
+		return theme;
+	}
+
+	public void setTheme(String theme) {
+		this.theme = theme;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+
+	public WorkMeeting() {
+		super();
+	}
+
+	public WorkMeeting(String id){
+		super(id);
+	}
+
+
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(String projectId) {
+		this.projectId = projectId;
+	}
+
+	public Area getArea() {
+		return area;
+	}
+
+	public void setArea(Area area) {
+		this.area = area;
+	}
+}

+ 56 - 0
src/main/java/com/jeeplus/modules/worklog/service/WorkLogService.java

@@ -0,0 +1,56 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.service;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.worklog.dao.WorkLogDao;
+import com.jeeplus.modules.worklog.entity.WorkLog;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+
+@Service
+@Transactional(readOnly = true)
+public class WorkLogService extends CrudService<WorkLogDao, WorkLog> {
+
+	@Autowired
+	private WorkLogDao workLogDao;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+
+	public WorkLog get(String id) {
+		WorkLog workLog =  super.get(id);
+		return workLog;
+	}
+	
+	public List<WorkLog> findList(WorkLog workLog) {
+		return super.findList(workLog);
+	}
+	
+	public Page<WorkLog> findPage(Page<WorkLog> page, WorkLog workLog) {
+		return super.findPage(page, workLog);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkLog workLog) {
+		super.save(workLog);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(WorkLog workLog) {
+		super.delete(workLog);
+	}
+
+
+	public WorkLog findListByProId(WorkLog workLog){
+		return workLogDao.findListByProId(workLog);
+	}
+	
+}

+ 57 - 0
src/main/java/com/jeeplus/modules/worklog/service/WorkMeetingService.java

@@ -0,0 +1,57 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.service;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.worklog.dao.WorkMeetingDao;
+import com.jeeplus.modules.worklog.entity.WorkMeeting;
+import com.jeeplus.modules.worklog.dao.WorkMeetingDao;
+import com.jeeplus.modules.worklog.entity.WorkMeeting;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+
+@Service
+@Transactional(readOnly = true)
+public class WorkMeetingService extends CrudService<WorkMeetingDao, WorkMeeting> {
+
+	@Autowired
+	private WorkMeetingDao workMeetingDao;
+	@Autowired
+	private WorkClientAttachmentDao workClientAttachmentDao;
+
+	public WorkMeeting get(String id) {
+		WorkMeeting workMeeting =  super.get(id);
+		return workMeeting;
+	}
+	
+	public List<WorkMeeting> findList(WorkMeeting workMeeting) {
+		return super.findList(workMeeting);
+	}
+	
+	public Page<WorkMeeting> findPage(Page<WorkMeeting> page, WorkMeeting workMeeting) {
+		return super.findPage(page, workMeeting);
+	}
+	
+	@Transactional(readOnly = false)
+	public void save(WorkMeeting workMeeting) {
+		super.save(workMeeting);
+	}
+	
+	@Transactional(readOnly = false)
+	public void delete(WorkMeeting workMeeting) {
+		super.delete(workMeeting);
+	}
+
+
+	public WorkMeeting findListByProId(WorkMeeting workMeeting){
+		return workMeetingDao.findListByProId(workMeeting);
+	}
+	
+}

+ 211 - 0
src/main/java/com/jeeplus/modules/worklog/web/WorkLogController.java

@@ -0,0 +1,211 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.web;
+
+import com.google.common.base.Strings;
+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.HttpClientUtil;
+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.worklog.entity.WorkLog;
+import com.jeeplus.modules.worklog.service.WorkLogService;
+import net.sf.json.JSONObject;
+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
+@RequestMapping(value = "${adminPath}/worklog/workLog")
+public class WorkLogController extends BaseController {
+
+	@Autowired
+	private WorkLogService workLogService;
+	
+	@ModelAttribute
+	public WorkLog get(@RequestParam(required=false) String id) {
+		WorkLog entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = workLogService.get(id);
+		}
+		if (entity == null){
+			entity = new WorkLog();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 日志列表页面
+	 */
+//	@RequiresPermissions("worklog:worklog:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(WorkLog workLog, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<WorkLog> page = workLogService.findPage(new Page<WorkLog>(request, response), workLog); 
+		model.addAttribute("page", page);
+		return "modules/worklog/workLogList";
+	}
+
+	/**
+	 * 查看,增加,编辑表单页面
+	 */
+//	@RequiresPermissions(value={"worklog:worklog:view","worklog:worklog:add","worklog:worklog:edit"},logical=Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(WorkLog workLog,HttpServletRequest request, Model model) {
+		String view = request.getParameter("view");
+		if("view".equals(view)){
+			view = "modules/worklog/workLogFormView";
+		}else{
+			view = "modules/worklog/workLogForm";
+		}
+		if(!Strings.isNullOrEmpty(workLog.getProjectId())){
+			workLog = workLogService.get(workLog.getProjectId());
+		}
+		model.addAttribute("workLog", workLog);
+		return view;
+	}
+
+	/**
+	 * 保存记录
+	 */
+//	@RequiresPermissions(value={"worklog:worklog:add","worklog:worklog:edit"},logical=Logical.OR)
+	@RequestMapping(value = "save")
+	public String save(WorkLog workLog, HttpServletRequest request,Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, workLog)){
+			return form(workLog,request, model);
+		}
+		if(!workLog.getIsNewRecord()){//编辑表单保存
+			WorkLog t = workLogService.get(workLog.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(workLog, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			workLogService.save(t);//保存
+		}else{//新增表单保存
+			workLogService.save(workLog);//保存
+		}
+		addMessage(redirectAttributes, "保存记录成功");
+		return "redirect:"+Global.getAdminPath()+"/worklog/worklog/?repage";
+	}
+	
+
+//	@RequiresPermissions("worklog:worklog:del")
+	@RequestMapping(value = "delete")
+	public String delete(WorkLog workLog, RedirectAttributes redirectAttributes) {
+		workLogService.delete(workLog);
+		addMessage(redirectAttributes, "删除日志成功");
+		return "redirect:"+Global.getAdminPath()+"/worklog/worklog/?repage";
+	}
+	
+
+//	@RequiresPermissions("worklog:worklog:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			workLogService.delete(workLogService.get(id));
+		}
+		addMessage(redirectAttributes, "删除日志成功");
+		return "redirect:"+Global.getAdminPath()+"/worklog/worklog/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+//	@RequiresPermissions("worklog:worklog:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(WorkLog workLog, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "日志"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<WorkLog> page = workLogService.findPage(new Page<WorkLog>(request, response, -1), workLog);
+    		new ExportExcel("日志", WorkLog.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出日志失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/worklog/worklog/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+//	@RequiresPermissions("worklog:worklog: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<WorkLog> list = ei.getDataList(WorkLog.class);
+			for (WorkLog workLog : list){
+				try{
+					workLogService.save(workLog);
+					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()+"/worklog/worklog/?repage";
+    }
+	
+	/**
+	 * 下载导入现场踏勘记录数据模板
+	 */
+//	@RequiresPermissions("worklog:worklog:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "日志导入模板.xlsx";
+    		List<WorkLog> list = Lists.newArrayList(); 
+    		new ExportExcel("日志", WorkLog.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/worklog/worklog/?repage";
+    }
+
+    @ResponseBody
+	@RequestMapping(value = "getWeather")
+	public Map getWeather(String code){
+    	Map map = new HashMap();
+    	try {
+			String url = "http://t.weather.sojson.com/api/weather/city/" + code;
+			JSONObject jsonObject = HttpClientUtil.httpRequest(url, "GET", null);
+			map.put("code", 1);
+			map.put("data", jsonObject);
+		}catch (Exception e){
+    		map.put("code",0);
+		}
+
+		return map;
+	}
+	
+	
+	
+
+}

+ 195 - 0
src/main/java/com/jeeplus/modules/worklog/web/WorkMeetingController.java

@@ -0,0 +1,195 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.modules.worklog.web;
+
+import com.google.common.base.Strings;
+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.worklog.entity.WorkMeeting;
+import com.jeeplus.modules.worklog.service.WorkLogService;
+import com.jeeplus.modules.worklog.service.WorkMeetingService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+import java.util.List;
+
+
+@Controller
+@RequestMapping(value = "${adminPath}/workmeeting/workMeeting")
+public class WorkMeetingController extends BaseController {
+
+	@Autowired
+	private WorkMeetingService workMeetingService;
+	
+	@ModelAttribute
+	public WorkMeeting get(@RequestParam(required=false) String id) {
+		WorkMeeting entity = null;
+		if (StringUtils.isNotBlank(id)){
+			entity = workMeetingService.get(id);
+		}
+		if (entity == null){
+			entity = new WorkMeeting();
+		}
+		return entity;
+	}
+	
+	/**
+	 * 日志列表页面
+	 */
+//	@RequiresPermissions("workMeeting:workMeeting:list")
+	@RequestMapping(value = {"list", ""})
+	public String list(WorkMeeting workMeeting, HttpServletRequest request, HttpServletResponse response, Model model) {
+		Page<WorkMeeting> page = workMeetingService.findPage(new Page<WorkMeeting>(request, response), workMeeting); 
+		model.addAttribute("page", page);
+		return "modules/workMeeting/workMeetingList";
+	}
+
+	/**
+	 * 查看,增加,编辑表单页面
+	 */
+//	@RequiresPermissions(value={"workMeeting:workMeeting:view","workMeeting:workMeeting:add","workMeeting:workMeeting:edit"},Meetingical=Meetingical.OR)
+	@RequestMapping(value = "form")
+	public String form(WorkMeeting workMeeting,HttpServletRequest request, Model model) {
+		String view = request.getParameter("view");
+		if("view".equals(view)){
+			view = "modules/worklog/workMeetFormView";
+		}else{
+			view = "modules/worklog/workMeetingForm";
+		}
+		if(!Strings.isNullOrEmpty(workMeeting.getProjectId())){
+			workMeeting = workMeetingService.get(workMeeting.getProjectId());
+		}
+		model.addAttribute("workMeeting", workMeeting);
+		return view;
+	}
+
+	/**
+	 * 保存记录
+	 */
+//	@RequiresPermissions(value={"workMeeting:workMeeting:add","workMeeting:workMeeting:edit"},Meetingical=Meetingical.OR)
+	@RequestMapping(value = "save")
+	public String save(WorkMeeting workMeeting, HttpServletRequest request,Model model, RedirectAttributes redirectAttributes) throws Exception{
+		if (!beanValidator(model, workMeeting)){
+			return form(workMeeting,request, model);
+		}
+		if(!workMeeting.getIsNewRecord()){//编辑表单保存
+			WorkMeeting t = workMeetingService.get(workMeeting.getId());//从数据库取出记录的值
+			MyBeanUtils.copyBeanNotNull2Bean(workMeeting, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+			workMeetingService.save(t);//保存
+		}else{//新增表单保存
+			workMeetingService.save(workMeeting);//保存
+		}
+		addMessage(redirectAttributes, "保存记录成功");
+		return "redirect:"+Global.getAdminPath()+"/workMeeting/workMeeting/?repage";
+	}
+	
+
+//	@RequiresPermissions("workMeeting:workMeeting:del")
+	@RequestMapping(value = "delete")
+	public String delete(WorkMeeting workMeeting, RedirectAttributes redirectAttributes) {
+		workMeetingService.delete(workMeeting);
+		addMessage(redirectAttributes, "删除日志成功");
+		return "redirect:"+Global.getAdminPath()+"/workMeeting/workMeeting/?repage";
+	}
+	
+
+//	@RequiresPermissions("workMeeting:workMeeting:del")
+	@RequestMapping(value = "deleteAll")
+	public String deleteAll(String ids, RedirectAttributes redirectAttributes) {
+		String idArray[] =ids.split(",");
+		for(String id : idArray){
+			workMeetingService.delete(workMeetingService.get(id));
+		}
+		addMessage(redirectAttributes, "删除日志成功");
+		return "redirect:"+Global.getAdminPath()+"/workMeeting/workMeeting/?repage";
+	}
+	
+	/**
+	 * 导出excel文件
+	 */
+//	@RequiresPermissions("workMeeting:workMeeting:export")
+    @RequestMapping(value = "export", method=RequestMethod.POST)
+    public String exportFile(WorkMeeting workMeeting, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "日志"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<WorkMeeting> page = workMeetingService.findPage(new Page<WorkMeeting>(request, response, -1), workMeeting);
+    		new ExportExcel("日志", WorkMeeting.class).setDataList(page.getList()).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导出日志失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/workMeeting/workMeeting/?repage";
+    }
+
+	/**
+	 * 导入Excel数据
+
+	 */
+//	@RequiresPermissions("workMeeting:workMeeting: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<WorkMeeting> list = ei.getDataList(WorkMeeting.class);
+			for (WorkMeeting workMeeting : list){
+				try{
+					workMeetingService.save(workMeeting);
+					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()+"/workMeeting/workMeeting/?repage";
+    }
+	
+	/**
+	 * 下载导入现场踏勘记录数据模板
+	 */
+//	@RequiresPermissions("workMeeting:workMeeting:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+		try {
+            String fileName = "日志导入模板.xlsx";
+    		List<WorkMeeting> list = Lists.newArrayList(); 
+    		new ExportExcel("日志", WorkMeeting.class, 1).setDataList(list).write(response, fileName).dispose();
+    		return null;
+		} catch (Exception e) {
+			addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+		}
+		return "redirect:"+Global.getAdminPath()+"/workMeeting/workMeeting/?repage";
+    }
+	
+	
+	
+
+}

+ 184 - 0
src/main/resources/mappings/modules/worklog/WorkLogDao.xml

@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jeeplus.modules.worklog.dao.WorkLogDao">
+    
+	<sql id="infoColums">
+		a.id AS "id",
+		a.create_by AS "createBy.id",
+		a.create_date AS "createDate",
+		a.update_by AS "updateBy.id",
+		a.update_date AS "updateDate",
+		a.remarks AS "remarks",
+		a.del_flag AS "delFlag",
+		a.content AS "content",
+		a.project_id AS "projectId",
+		a.log_type as "logType",
+		a.start_date AS "startDate",
+		a.area AS "area.name",
+		a.address AS "address",
+		a.weather,
+		a.low_tem AS "lowTem",
+		a.high_tem AS "highTem",
+		a.theme,
+		a.wind
+
+	</sql>
+	
+	<sql id="workLogJoins">
+
+	</sql>
+	
+    <!--<resultMap type="WorkInfoList" id="WorkLog" autoMapping="true">-->
+    	<!--<result column="content" property="content"   typeHandler="com.jeeplus.common.mapper.ConvertBlobTypeHandler"/>-->
+    <!--</resultMap>-->
+    
+	<select id="get" resultType="WorkLog" >
+		SELECT 
+			<include refid="infoColums"/>
+		FROM work_log a
+		<include refid="workLogJoins"/>
+		WHERE a.id = #{id}
+	</select>
+	
+	<select id="findList" resultType="WorkLog" >
+		SELECT 
+			<include refid="infoColums"/>
+		FROM work_log a
+		<include refid="workLogJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+		</where>
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+	
+	<select id="findAllList" resultType="WorkLog" >
+		SELECT 
+			<include refid="infoColums"/>
+		FROM work_log a
+		<include refid="workLogJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+		</where>		
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+	
+	<insert id="insert">
+		INSERT INTO work_log(
+			id,
+			create_by,
+			create_date,
+			update_by,
+			update_date,
+			remarks,
+			del_flag,
+			content,
+			project_id,
+			log_type ,
+		    start_date,
+		    area,
+		    address,
+		    weather,
+		    low_tem,
+		    high_tem,
+		    theme,
+		    wind
+		) VALUES (
+			#{id},
+			#{createBy.id},
+			#{createDate},
+			#{updateBy.id},
+			#{updateDate},
+			#{remarks},
+			#{delFlag},
+			#{content},
+			#{projectId},
+			#{logType},
+			#{startDate},
+			#{area.name},
+			#{address},
+			#{weather},
+			#{lowTem},
+			#{highTem},
+			#{theme},
+			#{wind}
+		)
+	</insert>
+	
+	<update id="update">
+		UPDATE work_log SET 	
+			update_by = #{updateBy.id},
+			update_date = #{updateDate},
+			remarks = #{remarks},
+			content = #{content},
+			project_id = #{projectId},
+			log_type = #{logType},
+			start_date = #{startDate},
+			area = #{area.id},
+			address= #{address},
+			weather = #{weather},
+			low_tem = #{lowTem},
+			high_tem = #{highTem},
+			theme = #{theme},
+		WHERE id = #{id}
+	</update>
+	
+	
+	<!--物理删除-->
+	<update id="delete">
+		DELETE FROM work_log
+		WHERE id = #{id}
+	</update>
+	
+	<!--逻辑删除-->
+	<update id="deleteByLogic">
+		UPDATE work_log SET 
+			del_flag = #{DEL_FLAG_DELETE}
+		WHERE id = #{id}
+	</update>
+	
+	
+	<!-- 根据实体名称和字段名称和字段值获取唯一记录 -->
+	<select id="findUniqueByProperty" resultType="WorkInfoList" statementType="STATEMENT">
+		select * FROM work_log  where ${propertyName} = '${value}'
+	</select>
+
+	<!-- 删除关联所有文件 -->
+	<delete id="deleteByProId">
+		DELETE FROM work_log
+		WHERE project_id = #{projectId}
+	</delete>
+
+	<!-- 获取实体 -->
+	<select id="findListByProId" resultType="WorkLog" >
+		SELECT
+		<include refid="infoColums"/>
+		FROM work_log a
+		<include refid="workLogJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+			and a.project_id = #{projectId}
+		</where>
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+</mapper>

+ 186 - 0
src/main/resources/mappings/modules/worklog/WorkMeetingDao.xml

@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jeeplus.modules.worklog.dao.WorkMeetingDao">
+    
+	<sql id="infoColums">
+		a.id AS "id",
+		a.create_by AS "createBy.id",
+		a.create_date AS "createDate",
+		a.update_by AS "updateBy.id",
+		a.update_date AS "updateDate",
+		a.remarks AS "remarks",
+		a.del_flag AS "delFlag",
+		a.content AS "content",
+		a.project_id AS "projectId",
+		a.meet_type as "meetType",
+		a.start_date AS "startDate",
+		a.area AS "area.name",
+		a.address AS "address",
+		a.weather,
+		a.low_tem AS "lowTem",
+		a.high_tem AS "highTem",
+		a.theme,
+		wind
+	</sql>
+
+
+
+	<sql id="workMeetingJoins">
+
+	</sql>
+
+	
+    <!--<resultMap type="WorkInfoList" id="WorkMeeting" autoMapping="true">-->
+    	<!--<result column="content" property="content"   typeHandler="com.jeeplus.common.mapper.ConvertBlobTypeHandler"/>-->
+    <!--</resultMap>-->
+    
+	<select id="get" resultType="WorkMeeting" >
+		SELECT 
+			<include refid="infoColums"/>
+		FROM work_meeting a
+		<include refid="workMeetingJoins"/>
+		WHERE a.id = #{id}
+	</select>
+	
+	<select id="findList" resultType="WorkMeeting" >
+		SELECT 
+			<include refid="infoColums"/>
+		FROM work_meeting a
+		<include refid="workMeetingJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+		</where>
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+	
+	<select id="findAllList" resultType="WorkMeeting" >
+		SELECT 
+			<include refid="infoColums"/>
+		FROM work_meeting a
+		<include refid="workMeetingJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+		</where>		
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+	
+	<insert id="insert">
+		INSERT INTO work_meeting(
+			id,
+			create_by,
+			create_date,
+			update_by,
+			update_date,
+			remarks,
+			del_flag,
+			content,
+			project_id,
+			meet_type ,
+		    start_date,
+		    area ,
+		    address,
+		    weather,
+		    low_tem,
+		    high_tem,
+		    theme,
+		    wind
+		) VALUES (
+			#{id},
+			#{createBy.id},
+			#{createDate},
+			#{updateBy.id},
+			#{updateDate},
+			#{remarks},
+			#{delFlag},
+			#{content},
+			#{projectId},
+			#{meetType},
+			#{startDate},
+			#{area.name},
+			#{address},
+			#{weather},
+			#{lowTem},
+			#{highTem},
+			#{theme},
+			#{wind}
+		)
+	</insert>
+	
+	<update id="update">
+		UPDATE work_meeting SET 	
+			update_by = #{updateBy.id},
+			update_date = #{updateDate},
+			remarks = #{remarks},
+			content = #{content},
+			project_id = #{projectId},
+			meet_type = #{meetType},
+			start_date = #{startDate},
+			area = #{area.id},
+			address= #{address},
+			weather = #{weather},
+			low_tem = #{lowTem},
+			high_tem = #{highTem},
+			theme = #{theme},
+		WHERE id = #{id}
+	</update>
+	
+	
+	<!--物理删除-->
+	<update id="delete">
+		DELETE FROM work_meeting
+		WHERE id = #{id}
+	</update>
+	
+	<!--逻辑删除-->
+	<update id="deleteByMeetingic">
+		UPDATE work_meeting SET 
+			del_flag = #{DEL_FLAG_DELETE}
+		WHERE id = #{id}
+	</update>
+	
+	
+	<!-- 根据实体名称和字段名称和字段值获取唯一记录 -->
+	<select id="findUniqueByProperty" resultType="WorkInfoList" statementType="STATEMENT">
+		select * FROM work_meeting  where ${propertyName} = '${value}'
+	</select>
+
+	<!-- 删除关联所有文件 -->
+	<delete id="deleteByProId">
+		DELETE FROM work_meeting
+		WHERE project_id = #{projectId}
+	</delete>
+
+	<!-- 获取实体 -->
+	<select id="findListByProId" resultType="WorkMeeting" >
+		SELECT
+		<include refid="infoColums"/>
+		FROM work_meeting a
+		<include refid="workMeetingJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+			and a.project_id = #{projectId}
+		</where>
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+</mapper>

+ 1 - 1
src/main/webapp/WEB-INF/tags/sys/treeselect.tag

@@ -85,7 +85,7 @@
 							break; // 如果为非复选框选择,则返回第一个选择  </c:if>
 						}
 						$("#${id}Id").val(ids.join(",").replace(/u_/ig,"")).change();
-						$("#${id}Name").val(names.join(","));
+						$("#${id}Name").val(names.join(",")).change();
 						$("#${id}Name").focus();
 						var rule="${rule}";
 						var id="${id}";

文件差異過大導致無法顯示
+ 22790 - 0
src/main/webapp/static/json/city.json


+ 15 - 0
src/main/webapp/static/kindeditor/jsp/README.txt

@@ -0,0 +1,15 @@
+KindEditor JSP
+
+本JSP程序是演示程序,建议不要直接在实际项目中使用。
+如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。
+ 
+使用方法:
+
+1. 解压zip文件,将所有文件复制到Tomcat的webapps/kindeditor目录下。
+
+2. 将kindeditor/jsp/lib目录下的3个jar文件复制到Tomcat的lib目录下,并重新启动Tomcat。
+	* commons-fileupload-1.2.1.jar
+	* commons-io-1.4.jar
+	* json_simple-1.1.jar
+
+3. 打开浏览器,输入http://localhost:[P0RT]/kindeditor/jsp/demo.jsp。

+ 56 - 0
src/main/webapp/static/kindeditor/jsp/demo.jsp

@@ -0,0 +1,56 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%
+request.setCharacterEncoding("UTF-8");
+String htmlData = request.getParameter("content1") != null ? request.getParameter("content1") : "";
+%>
+<!doctype html>
+<html>
+<head>
+	<meta charset="utf-8" />
+	<title>KindEditor JSP</title>
+	<link rel="stylesheet" href="../themes/default/default.css" />
+	<link rel="stylesheet" href="../plugins/code/prettify.css" />
+	<script charset="utf-8" src="../kindeditor.js"></script>
+	<script charset="utf-8" src="../lang/zh-CN.js"></script>
+	<script charset="utf-8" src="../plugins/code/prettify.js"></script>
+	<script>
+		KindEditor.ready(function(K) {
+			var editor1 = K.create('textarea[name="content1"]', {
+				cssPath : '../plugins/code/prettify.css',
+				uploadJson : '../jsp/upload_json.jsp',
+				fileManagerJson : '../jsp/file_manager_json.jsp',
+				allowFileManager : true,
+				afterCreate : function() {
+					var self = this;
+					K.ctrl(document, 13, function() {
+						self.sync();
+						document.forms['example'].submit();
+					});
+					K.ctrl(self.edit.doc, 13, function() {
+						self.sync();
+						document.forms['example'].submit();
+					});
+				}
+			});
+			prettyPrint();
+		});
+	</script>
+</head>
+<body>
+	<%=htmlData%>
+	<form name="example" method="post" action="demo.jsp">
+		<textarea name="content1" cols="100" rows="8" style="width:700px;height:200px;visibility:hidden;"><%=htmlspecialchars(htmlData)%></textarea>
+		<br />
+		<input type="submit" name="button" value="提交内容" /> (提交快捷键: Ctrl + Enter)
+	</form>
+</body>
+</html>
+<%!
+private String htmlspecialchars(String str) {
+	str = str.replaceAll("&", "&amp;");
+	str = str.replaceAll("<", "&lt;");
+	str = str.replaceAll(">", "&gt;");
+	str = str.replaceAll("\"", "&quot;");
+	return str;
+}
+%>

+ 156 - 0
src/main/webapp/static/kindeditor/jsp/file_manager_json.jsp

@@ -0,0 +1,156 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ page import="java.util.*,java.io.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.json.simple.*" %>
+<%@ page import="com.alibaba.fastjson.JSONObject" %>
+<%
+
+/**
+ * KindEditor JSP
+ *
+ * 本JSP程序是演示程序,建议不要直接在实际项目中使用。
+ * 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。
+ *
+ */
+
+//根目录路径,可以指定绝对路径,比如 /var/www/attached/
+String rootPath = pageContext.getServletContext().getRealPath("/") + "attached/";
+//根目录URL,可以指定绝对路径,比如 http://www.yoursite.com/attached/
+String rootUrl  = request.getContextPath() + "/attached/";
+//图片扩展名
+String[] fileTypes = new String[]{"gif", "jpg", "jpeg", "png", "bmp"};
+
+String dirName = request.getParameter("dir");
+if (dirName != null) {
+	if(!Arrays.<String>asList(new String[]{"image", "flash", "media", "file"}).contains(dirName)){
+		out.println("Invalid Directory name.");
+		return;
+	}
+	rootPath += dirName + "/";
+	rootUrl += dirName + "/";
+	File saveDirFile = new File(rootPath);
+	if (!saveDirFile.exists()) {
+		saveDirFile.mkdirs();
+	}
+}
+//根据path参数,设置各路径和URL
+String path = request.getParameter("path") != null ? request.getParameter("path") : "";
+String currentPath = rootPath + path;
+String currentUrl = rootUrl + path;
+String currentDirPath = path;
+String moveupDirPath = "";
+if (!"".equals(path)) {
+	String str = currentDirPath.substring(0, currentDirPath.length() - 1);
+	moveupDirPath = str.lastIndexOf("/") >= 0 ? str.substring(0, str.lastIndexOf("/") + 1) : "";
+}
+
+//排序形式,name or size or type
+String order = request.getParameter("order") != null ? request.getParameter("order").toLowerCase() : "name";
+
+//不允许使用..移动到上一级目录
+if (path.indexOf("..") >= 0) {
+	out.println("Access is not allowed.");
+	return;
+}
+//最后一个字符不是/
+if (!"".equals(path) && !path.endsWith("/")) {
+	out.println("Parameter is not valid.");
+	return;
+}
+//目录不存在或不是目录
+File currentPathFile = new File(currentPath);
+if(!currentPathFile.isDirectory()){
+	out.println("Directory does not exist.");
+	return;
+}
+
+//遍历目录取的文件信息
+List<Hashtable> fileList = new ArrayList<Hashtable>();
+if(currentPathFile.listFiles() != null) {
+	for (File file : currentPathFile.listFiles()) {
+		Hashtable<String, Object> hash = new Hashtable<String, Object>();
+		String fileName = file.getName();
+		if(file.isDirectory()) {
+			hash.put("is_dir", true);
+			hash.put("has_file", (file.listFiles() != null));
+			hash.put("filesize", 0L);
+			hash.put("is_photo", false);
+			hash.put("filetype", "");
+		} else if(file.isFile()){
+			String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
+			hash.put("is_dir", false);
+			hash.put("has_file", false);
+			hash.put("filesize", file.length());
+			hash.put("is_photo", Arrays.<String>asList(fileTypes).contains(fileExt));
+			hash.put("filetype", fileExt);
+		}
+		hash.put("filename", fileName);
+		hash.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified()));
+		fileList.add(hash);
+	}
+}
+
+if ("size".equals(order)) {
+	Collections.sort(fileList, new SizeComparator());
+} else if ("type".equals(order)) {
+	Collections.sort(fileList, new TypeComparator());
+} else {
+	Collections.sort(fileList, new NameComparator());
+}
+JSONObject result = new JSONObject();
+result.put("moveup_dir_path", moveupDirPath);
+result.put("current_dir_path", currentDirPath);
+result.put("current_url", currentUrl);
+result.put("total_count", fileList.size());
+result.put("file_list", fileList);
+
+response.setContentType("application/json; charset=UTF-8");
+out.println(result.toJSONString());
+%>
+<%!
+public class NameComparator implements Comparator {
+	public int compare(Object a, Object b) {
+		Hashtable hashA = (Hashtable)a;
+		Hashtable hashB = (Hashtable)b;
+		if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {
+			return -1;
+		} else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {
+			return 1;
+		} else {
+			return ((String)hashA.get("filename")).compareTo((String)hashB.get("filename"));
+		}
+	}
+}
+public class SizeComparator implements Comparator {
+	public int compare(Object a, Object b) {
+		Hashtable hashA = (Hashtable)a;
+		Hashtable hashB = (Hashtable)b;
+		if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {
+			return -1;
+		} else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {
+			return 1;
+		} else {
+			if (((Long)hashA.get("filesize")) > ((Long)hashB.get("filesize"))) {
+				return 1;
+			} else if (((Long)hashA.get("filesize")) < ((Long)hashB.get("filesize"))) {
+				return -1;
+			} else {
+				return 0;
+			}
+		}
+	}
+}
+public class TypeComparator implements Comparator {
+	public int compare(Object a, Object b) {
+		Hashtable hashA = (Hashtable)a;
+		Hashtable hashB = (Hashtable)b;
+		if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {
+			return -1;
+		} else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {
+			return 1;
+		} else {
+			return ((String)hashA.get("filetype")).compareTo((String)hashB.get("filetype"));
+		}
+	}
+}
+%>

二進制
src/main/webapp/static/kindeditor/jsp/lib/commons-fileupload-1.2.1.jar


二進制
src/main/webapp/static/kindeditor/jsp/lib/commons-io-1.4.jar


二進制
src/main/webapp/static/kindeditor/jsp/lib/json_simple-1.1.jar


+ 129 - 0
src/main/webapp/static/kindeditor/jsp/upload_json.jsp

@@ -0,0 +1,129 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ page import="java.util.*,java.io.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.apache.commons.fileupload.*" %>
+<%@ page import="org.apache.commons.fileupload.disk.*" %>
+<%@ page import="org.apache.commons.fileupload.servlet.*" %>
+<%@ page import="org.json.simple.*" %>
+<%@ page import="com.alibaba.fastjson.JSONObject" %>
+<%@ page import="com.jeeplus.common.bos.BOSClientUtil" %>
+<%
+
+/**
+ * KindEditor JSP
+ * 
+ * 本JSP程序是演示程序,建议不要直接在实际项目中使用。
+ * 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。
+ * 
+ */
+
+////文件保存目录路径
+//String savePath = pageContext.getServletContext().getRealPath("/") + "local_upload/article_picture/";
+//
+////文件保存目录URL
+//String saveUrl  = request.getContextPath() + "/local_upload/article_picture/";
+
+//定义允许上传的文件扩展名
+HashMap<String, String> extMap = new HashMap<String, String>();
+extMap.put("image", "gif,jpg,jpeg,png,bmp");
+extMap.put("flash", "swf,flv");
+extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
+extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
+
+//最大文件大小
+long maxSize = 1000000;
+
+response.setContentType("text/html; charset=UTF-8");
+
+if(!ServletFileUpload.isMultipartContent(request)){
+	out.println(getError("请选择文件。"));
+	return;
+}
+//检查目录
+//File uploadDir = new File(savePath);
+//if(!uploadDir.isDirectory()){
+//	out.println(getError("上传目录不存在。"));
+//	return;
+//}
+//检查目录写权限
+//if(!uploadDir.canWrite()){
+//	out.println(getError("上传目录没有写权限。"));
+//	return;
+//}
+
+//String dirName = request.getParameter("dir");
+//if (dirName == null) {
+//	dirName = "image";
+//}
+//if(!extMap.containsKey(dirName)){
+//	out.println(getError("目录名不正确。"));
+//	return;
+//}
+//创建文件夹
+//savePath += dirName + "/";
+//saveUrl += dirName + "/";
+//File saveDirFile = new File(savePath);
+//if (!saveDirFile.exists()) {
+//	saveDirFile.mkdirs();
+//}
+//SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+//String ymd = sdf.format(new Date());
+//savePath += ymd + "/";
+//saveUrl += ymd + "/";
+//File dirFile = new File(savePath);
+//if (!dirFile.exists()) {
+//	dirFile.mkdirs();
+//}
+
+FileItemFactory factory = new DiskFileItemFactory();
+ServletFileUpload upload = new ServletFileUpload(factory);
+upload.setHeaderEncoding("UTF-8");
+List items = upload.parseRequest(request);
+Iterator itr = items.iterator();
+while (itr.hasNext()) {
+	FileItem item = (FileItem) itr.next();
+	String fileName = item.getName();
+	InputStream inputStream = item.getInputStream();
+	long fileSize = item.getSize();
+	if (!item.isFormField()) {
+		//检查文件大小
+		if(item.getSize() > maxSize){
+			out.println(getError("上传文件大小超过限制。"));
+			return;
+		}
+		//检查扩展名
+		String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
+//		if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
+//			out.println(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。"));
+//			return;
+//		}
+
+		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
+		String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
+		try{
+//			File uploadedFile = new File(savePath, newFileName);
+			String path = "/picture/"+System.currentTimeMillis()+"/"+newFileName;
+			BOSClientUtil bosClientUtil = new BOSClientUtil();
+			String upload1 = bosClientUtil.upload(path, inputStream);
+			JSONObject obj = new JSONObject();
+			obj.put("error", 0);
+			obj.put("url", upload1);
+			out.println(obj.toJSONString());
+//			item.write(uploadedFile);
+		}catch(Exception e){
+			out.println(getError("上传文件失败。"));
+			return;
+		}
+
+
+	}
+}
+%>
+<%!
+private String getError(String message) {
+	JSONObject obj = new JSONObject();
+	obj.put("error", 1);
+	obj.put("message", message);
+	return obj.toJSONString();
+}
+%>

文件差異過大導致無法顯示
+ 7 - 0
src/main/webapp/static/kindeditor/kindeditor-all-min.js


文件差異過大導致無法顯示
+ 9849 - 0
src/main/webapp/static/kindeditor/kindeditor-all.js


+ 242 - 0
src/main/webapp/static/kindeditor/lang/ar.js

@@ -0,0 +1,242 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+* Arabic Translation By daif alotaibi (http://daif.net/)
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'عرض المصدر',
+	preview : 'معاينة الصفحة',
+	undo : 'تراجع(Ctrl+Z)',
+	redo : 'إعادة التراجع(Ctrl+Y)',
+	cut : 'قص(Ctrl+X)',
+	copy : 'نسخ(Ctrl+C)',
+	paste : 'لصق(Ctrl+V)',
+	plainpaste : 'لصق كنص عادي',
+	wordpaste : 'لصق من مايكروسفت ورد',
+	selectall : 'تحديد الكل',
+	justifyleft : 'محاذاه لليسار',
+	justifycenter : 'محاذاه للوسط',
+	justifyright : 'محاذاه لليمين',
+	justifyfull : 'محاذاه تلقائية',
+	insertorderedlist : 'قائمة مرقمه',
+	insertunorderedlist : 'قائمة نقطية',
+	indent : 'إزاحه النص',
+	outdent : 'إلغاء الازاحة',
+	subscript : 'أسفل النص',
+	superscript : 'أعلى النص',
+	formatblock : 'Paragraph format',
+	fontname : 'نوع الخط',
+	fontsize : 'حجم الخط',
+	forecolor : 'لون النص',
+	hilitecolor : 'لون خلفية النص',
+	bold : 'عريض(Ctrl+B)',
+	italic : 'مائل(Ctrl+I)',
+	underline : 'خط تحت النص(Ctrl+U)',
+	strikethrough : 'خط على النص',
+	removeformat : 'إزالة التنسيق',
+	image : 'إدراج صورة',
+	multiimage : 'Multi image',
+	flash : 'إدراج فلاش',
+	media : 'إدراج وسائط متعددة',
+	table : 'إدراج جدول',
+	tablecell : 'خلية',
+	hr : 'إدراج خط أفقي',
+	emoticons : 'إدراج وجه ضاحك',
+	link : 'رابط',
+	unlink : 'إزالة الرابط',
+	fullscreen : 'محرر ملئ الشاشة',
+	about : 'حول',
+	print : 'طباعة',
+	filemanager : 'مدير الملفات',
+	code : 'إدراج نص برمجي',
+	map : 'خرائط قووقل',
+	baidumap : 'خرائط قووقل',
+	lineheight : 'إرتفاع السطر',
+	clearhtml : 'مسح كود HTML',
+	pagebreak : 'إدراج فاصل صفحات',
+	quickformat : 'تنسيق سريع',
+	insertfile : 'إدراج ملف',
+	template : 'إدراج قالب',
+	anchor : 'رابط',
+	yes : 'موافق',
+	no : 'إلغاء',
+	close : 'إغلاق',
+	editImage : 'خصائص الصورة',
+	deleteImage : 'حذفالصورة',
+	editFlash : 'خصائص الفلاش',
+	deleteFlash : 'حذف الفلاش',
+	editMedia : 'خصائص الوسائط',
+	deleteMedia : 'حذف الوسائط',
+	editLink : 'خصائص الرابط',
+	deleteLink : 'إزالة الرابط',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : 'خصائص الجدول',
+	tablecellprop : 'خصائص الخلية',
+	tableinsert : 'إدراج جدول',
+	tabledelete : 'حذف جدول',
+	tablecolinsertleft : 'إدراج عمود لليسار',
+	tablecolinsertright : 'إدراج عمود لليسار',
+	tablerowinsertabove : 'إدراج صف للأعلى',
+	tablerowinsertbelow : 'إدراج صف للأسفل',
+	tablerowmerge : 'دمج للأسفل',
+	tablecolmerge : 'دمج لليمين',
+	tablerowsplit : 'تقسم الصف',
+	tablecolsplit : 'تقسيم العمود',
+	tablecoldelete : 'حذف العمود',
+	tablerowdelete : 'حذف الصف',
+	noColor : 'إفتراضي',
+	pleaseSelectFile : 'Please select file.',
+	invalidImg : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: jpg,gif,bmp,png",
+	invalidMedia : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
+	invalidWidth : "العرض يجب أن يكون رقم.",
+	invalidHeight : "الإرتفاع يجب أن يكون رقم.",
+	invalidBorder : "عرض الحد يجب أن يكون رقم.",
+	invalidUrl : "الرجاء إدخال رابط حيح.",
+	invalidRows : 'صفوف غير صحيح.',
+	invalidCols : 'أعمدة غير صحيحة.',
+	invalidPadding : 'The padding must be number.',
+	invalidSpacing : 'The spacing must be number.',
+	invalidJson : 'Invalid JSON string.',
+	uploadSuccess : 'تم رفع الملف بنجاح.',
+	cutError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+X).',
+	copyError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+C).',
+	pasteError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+V).',
+	ajaxLoading : 'Loading ...',
+	uploadLoading : 'Uploading ...',
+	uploadError : 'Upload Error',
+	'plainpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.',
+	'wordpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : 'الرابط',
+	'link.linkType' : 'الهدف',
+	'link.newWindow' : 'نافذة جديدة',
+	'link.selfWindow' : 'نفس النافذة',
+	'flash.url' : 'الرابط',
+	'flash.width' : 'العرض',
+	'flash.height' : 'الإرتفاع',
+	'flash.upload' : 'رفع',
+	'flash.viewServer' : 'أستعراض',
+	'media.url' : 'الرابط',
+	'media.width' : 'العرض',
+	'media.height' : 'الإرتفاع',
+	'media.autostart' : 'تشغيل تلقائي',
+	'media.upload' : 'رفع',
+	'media.viewServer' : 'أستعراض',
+	'image.remoteImage' : 'إدراج الرابط',
+	'image.localImage' : 'رفع',
+	'image.remoteUrl' : 'الرابط',
+	'image.localUrl' : 'الملف',
+	'image.size' : 'الحجم',
+	'image.width' : 'العرض',
+	'image.height' : 'الإرتفاع',
+	'image.resetSize' : 'إستعادة الأبعاد',
+	'image.align' : 'محاذاة',
+	'image.defaultAlign' : 'الإفتراضي',
+	'image.leftAlign' : 'اليسار',
+	'image.rightAlign' : 'اليمين',
+	'image.imgTitle' : 'العنوان',
+	'image.upload' : 'أستعراض',
+	'image.viewServer' : 'أستعراض',
+	'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Start upload',
+	'multiimage.clearAll' : 'Clear all',
+	'multiimage.insertAll' : 'Insert all',
+	'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
+	'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
+	'multiimage.zeroByteFile' : 'Zero byte file.',
+	'multiimage.invalidFiletype' : 'Invalid file type.',
+	'multiimage.unknownError' : 'Unknown upload error.',
+	'multiimage.pending' : 'Pending ...',
+	'multiimage.uploadError' : 'Upload error',
+	'filemanager.emptyFolder' : 'فارغ',
+	'filemanager.moveup' : 'المجلد الأب',
+	'filemanager.viewType' : 'العرض: ',
+	'filemanager.viewImage' : 'مصغرات',
+	'filemanager.listImage' : 'قائمة',
+	'filemanager.orderType' : 'الترتيب: ',
+	'filemanager.fileName' : 'بالإسم',
+	'filemanager.fileSize' : 'بالحجم',
+	'filemanager.fileType' : 'بالنوع',
+	'insertfile.url' : 'الرابط',
+	'insertfile.title' : 'العنوان',
+	'insertfile.upload' : 'رفع',
+	'insertfile.viewServer' : 'أستعراض',
+	'table.cells' : 'خلايا',
+	'table.rows' : 'صفوف',
+	'table.cols' : 'أعمدة',
+	'table.size' : 'الأبعاد',
+	'table.width' : 'العرض',
+	'table.height' : 'الإرتفاع',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : 'الخارج',
+	'table.padding' : 'الداخل',
+	'table.spacing' : 'الفراغات',
+	'table.align' : 'محاذاه',
+	'table.textAlign' : 'افقى',
+	'table.verticalAlign' : 'رأسي',
+	'table.alignDefault' : 'إفتراضي',
+	'table.alignLeft' : 'يسار',
+	'table.alignCenter' : 'وسط',
+	'table.alignRight' : 'يمين',
+	'table.alignTop' : 'أعلى',
+	'table.alignMiddle' : 'منتصف',
+	'table.alignBottom' : 'أسفل',
+	'table.alignBaseline' : 'Baseline',
+	'table.border' : 'الحدود',
+	'table.borderWidth' : 'العرض',
+	'table.borderColor' : 'اللون',
+	'table.backgroundColor' : 'الخلفية',
+	'map.address' : 'العنوان: ',
+	'map.search' : 'بحث',
+	'baidumap.address' : 'العنوان: ',
+	'baidumap.search' : 'بحث',
+	'baidumap.insertDynamicMap' : 'Dynamic Map',
+	'anchor.name' : 'إسم الرابط',
+	'formatblock.formatBlock' : {
+		h1 : 'عنوان 1',
+		h2 : 'عنوان 2',
+		h3 : 'عنوان 3',
+		h4 : 'عنوان 4',
+		p : 'عادي'
+	},
+	'fontname.fontName' : {
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : 'إرتفاع السطر 1'},
+		{'1.5' : 'إرتفاع السطر 1.5'},
+		{'2' : 'إرتفاع السطر 2'},
+		{'2.5' : 'إرتفاع السطر 2.5'},
+		{'3' : 'إرتفاع السطر 3'}
+	],
+	'template.selectTemplate' : 'قالب',
+	'template.replaceContent' : 'إستبدال المحتوى الحالي',
+	'template.fileList' : {
+		'1.html' : 'صورة ونص',
+		'2.html' : 'جدول',
+		'3.html' : 'قائمة'
+	}
+}, 'ar');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'ar';

+ 241 - 0
src/main/webapp/static/kindeditor/lang/en.js

@@ -0,0 +1,241 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'Source',
+	preview : 'Preview',
+	undo : 'Undo(Ctrl+Z)',
+	redo : 'Redo(Ctrl+Y)',
+	cut : 'Cut(Ctrl+X)',
+	copy : 'Copy(Ctrl+C)',
+	paste : 'Paste(Ctrl+V)',
+	plainpaste : 'Paste as plain text',
+	wordpaste : 'Paste from Word',
+	selectall : 'Select all',
+	justifyleft : 'Align left',
+	justifycenter : 'Align center',
+	justifyright : 'Align right',
+	justifyfull : 'Align full',
+	insertorderedlist : 'Ordered list',
+	insertunorderedlist : 'Unordered list',
+	indent : 'Increase indent',
+	outdent : 'Decrease indent',
+	subscript : 'Subscript',
+	superscript : 'Superscript',
+	formatblock : 'Paragraph format',
+	fontname : 'Font family',
+	fontsize : 'Font size',
+	forecolor : 'Text color',
+	hilitecolor : 'Highlight color',
+	bold : 'Bold(Ctrl+B)',
+	italic : 'Italic(Ctrl+I)',
+	underline : 'Underline(Ctrl+U)',
+	strikethrough : 'Strikethrough',
+	removeformat : 'Remove format',
+	image : 'Image',
+	multiimage : 'Multi image',
+	flash : 'Flash',
+	media : 'Embeded media',
+	table : 'Table',
+	tablecell : 'Cell',
+	hr : 'Insert horizontal line',
+	emoticons : 'Insert emoticon',
+	link : 'Link',
+	unlink : 'Unlink',
+	fullscreen : 'Toggle fullscreen mode',
+	about : 'About',
+	print : 'Print',
+	filemanager : 'File Manager',
+	code : 'Insert code',
+	map : 'Google Maps',
+	baidumap : 'Baidu Maps',
+	lineheight : 'Line height',
+	clearhtml : 'Clear HTML code',
+	pagebreak : 'Insert Page Break',
+	quickformat : 'Quick Format',
+	insertfile : 'Insert file',
+	template : 'Insert Template',
+	anchor : 'Anchor',
+	yes : 'OK',
+	no : 'Cancel',
+	close : 'Close',
+	editImage : 'Image properties',
+	deleteImage : 'Delete image',
+	editFlash : 'Flash properties',
+	deleteFlash : 'Delete flash',
+	editMedia : 'Media properties',
+	deleteMedia : 'Delete media',
+	editLink : 'Link properties',
+	deleteLink : 'Unlink',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : 'Table properties',
+	tablecellprop : 'Cell properties',
+	tableinsert : 'Insert table',
+	tabledelete : 'Delete table',
+	tablecolinsertleft : 'Insert column left',
+	tablecolinsertright : 'Insert column right',
+	tablerowinsertabove : 'Insert row above',
+	tablerowinsertbelow : 'Insert row below',
+	tablerowmerge : 'Merge down',
+	tablecolmerge : 'Merge right',
+	tablerowsplit : 'Split row',
+	tablecolsplit : 'Split column',
+	tablecoldelete : 'Delete column',
+	tablerowdelete : 'Delete row',
+	noColor : 'Default',
+	pleaseSelectFile : 'Please select file.',
+	invalidImg : "Please type valid URL.\nAllowed file extension: jpg,gif,bmp,png",
+	invalidMedia : "Please type valid URL.\nAllowed file extension: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
+	invalidWidth : "The width must be number.",
+	invalidHeight : "The height must be number.",
+	invalidBorder : "The border must be number.",
+	invalidUrl : "Please type valid URL.",
+	invalidRows : 'Invalid rows.',
+	invalidCols : 'Invalid columns.',
+	invalidPadding : 'The padding must be number.',
+	invalidSpacing : 'The spacing must be number.',
+	invalidJson : 'Invalid JSON string.',
+	uploadSuccess : 'Upload success.',
+	cutError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+X) instead.',
+	copyError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+C) instead.',
+	pasteError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+V) instead.',
+	ajaxLoading : 'Loading ...',
+	uploadLoading : 'Uploading ...',
+	uploadError : 'Upload Error',
+	'plainpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.',
+	'wordpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : 'URL',
+	'link.linkType' : 'Target',
+	'link.newWindow' : 'New window',
+	'link.selfWindow' : 'Same window',
+	'flash.url' : 'URL',
+	'flash.width' : 'Width',
+	'flash.height' : 'Height',
+	'flash.upload' : 'Upload',
+	'flash.viewServer' : 'Browse',
+	'media.url' : 'URL',
+	'media.width' : 'Width',
+	'media.height' : 'Height',
+	'media.autostart' : 'Auto start',
+	'media.upload' : 'Upload',
+	'media.viewServer' : 'Browse',
+	'image.remoteImage' : 'Insert URL',
+	'image.localImage' : 'Upload',
+	'image.remoteUrl' : 'URL',
+	'image.localUrl' : 'File',
+	'image.size' : 'Size',
+	'image.width' : 'Width',
+	'image.height' : 'Height',
+	'image.resetSize' : 'Reset dimensions',
+	'image.align' : 'Align',
+	'image.defaultAlign' : 'Default',
+	'image.leftAlign' : 'Left',
+	'image.rightAlign' : 'Right',
+	'image.imgTitle' : 'Title',
+	'image.upload' : 'Browse',
+	'image.viewServer' : 'Browse',
+	'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Start upload',
+	'multiimage.clearAll' : 'Clear all',
+	'multiimage.insertAll' : 'Insert all',
+	'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
+	'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
+	'multiimage.zeroByteFile' : 'Zero byte file.',
+	'multiimage.invalidFiletype' : 'Invalid file type.',
+	'multiimage.unknownError' : 'Unknown upload error.',
+	'multiimage.pending' : 'Pending ...',
+	'multiimage.uploadError' : 'Upload error',
+	'filemanager.emptyFolder' : 'Blank',
+	'filemanager.moveup' : 'Parent folder',
+	'filemanager.viewType' : 'Display: ',
+	'filemanager.viewImage' : 'Thumbnails',
+	'filemanager.listImage' : 'List',
+	'filemanager.orderType' : 'Sorting: ',
+	'filemanager.fileName' : 'By name',
+	'filemanager.fileSize' : 'By size',
+	'filemanager.fileType' : 'By type',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : 'Title',
+	'insertfile.upload' : 'Upload',
+	'insertfile.viewServer' : 'Browse',
+	'table.cells' : 'Cells',
+	'table.rows' : 'Rows',
+	'table.cols' : 'Columns',
+	'table.size' : 'Dimensions',
+	'table.width' : 'Width',
+	'table.height' : 'Height',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : 'Space',
+	'table.padding' : 'Padding',
+	'table.spacing' : 'Spacing',
+	'table.align' : 'Align',
+	'table.textAlign' : 'Horizontal',
+	'table.verticalAlign' : 'Vertical',
+	'table.alignDefault' : 'Default',
+	'table.alignLeft' : 'Left',
+	'table.alignCenter' : 'Center',
+	'table.alignRight' : 'Right',
+	'table.alignTop' : 'Top',
+	'table.alignMiddle' : 'Middle',
+	'table.alignBottom' : 'Bottom',
+	'table.alignBaseline' : 'Baseline',
+	'table.border' : 'Border',
+	'table.borderWidth' : 'Width',
+	'table.borderColor' : 'Color',
+	'table.backgroundColor' : 'Background',
+	'map.address' : 'Address: ',
+	'map.search' : 'Search',
+	'baidumap.address' : 'Address: ',
+	'baidumap.search' : 'Search',
+	'baidumap.insertDynamicMap' : 'Dynamic Map',
+	'anchor.name' : 'Anchor name',
+	'formatblock.formatBlock' : {
+		h1 : 'Heading 1',
+		h2 : 'Heading 2',
+		h3 : 'Heading 3',
+		h4 : 'Heading 4',
+		p : 'Normal'
+	},
+	'fontname.fontName' : {
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : 'Line height 1'},
+		{'1.5' : 'Line height 1.5'},
+		{'2' : 'Line height 2'},
+		{'2.5' : 'Line height 2.5'},
+		{'3' : 'Line height 3'}
+	],
+	'template.selectTemplate' : 'Template',
+	'template.replaceContent' : 'Replace current content',
+	'template.fileList' : {
+		'1.html' : 'Image and Text',
+		'2.html' : 'Table',
+		'3.html' : 'List'
+	}
+}, 'en');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'en';

+ 246 - 0
src/main/webapp/static/kindeditor/lang/ko.js

@@ -0,0 +1,246 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Composite <ukjinplant@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : '소스',
+	preview : '미리보기',
+	undo : '작업취소(Ctrl+Z)',
+	redo : '작업재개(Ctrl+Y)',
+	cut : '잘라내기(Ctrl+X)',
+	copy : '복사(Ctrl+C)',
+	paste : '붙여넣기(Ctrl+V)',
+	plainpaste : '일반 텍스트로 붙여넣기',
+	wordpaste : '워드 문서로 붙여넣기',
+	selectall : '전체 선택',
+	justifyleft : '왼쪽 정렬',
+	justifycenter : '가운데 정렬',
+	justifyright : '오른쪽 정렬',
+	justifyfull : '양쪽 정렬',
+	insertorderedlist : '순서 목록',
+	insertunorderedlist : '비순서 목록',
+	indent : '들여쓰기',
+	outdent : '내어쓰기',
+	subscript : '아랫첨자',
+	superscript : '윗첨자',
+	formatblock : '문단 형식',
+	fontname : '글꼴',
+	fontsize : '글자 크기',
+	forecolor : '글자색',
+	hilitecolor : '강조색',
+	bold : '굵게(Ctrl+B)',
+	italic : '이텔릭(Ctrl+I)',
+	underline : '빝줄(Ctrl+U)',
+	strikethrough : '취소선',
+	removeformat : '형식 제거',
+	image : '이미지 추가',
+	multiimage : '여러 이미지 추가',
+	flash : '플래시 추가',
+	media : '미디어 추가',
+	table : '표',
+	tablecell : '열',
+	hr : '구분선 추가',
+	emoticons : '이모티콘 추가',
+	link : '링크',
+	unlink : '링크 제거',
+	fullscreen : '전체 화면 모드',
+	about : '이 에디터는...',
+	print : '인쇄',
+	filemanager : '파일 관리자',
+	code : '코드 추가',
+	map : '구글 맵 추가',
+	baidumap : '바이두 맵 추가',
+	lineheight : '행 간격',
+	clearhtml : 'HTML 코드 정리',
+	pagebreak : '페이지 구분 추가',
+	quickformat : '빠른 형식',
+	insertfile : '파일 추가',
+	template : '템플릿 추가',
+	anchor : '책갈피',
+	yes : '확인',
+	no : '취소',
+	close : '닫기',
+	editImage : '이미지 속성',
+	deleteImage : '이미지 삭제',
+	editFlash : '플래시 속성',
+	deleteFlash : '플래시 삭제',
+	editMedia : '미디어 속성',
+	deleteMedia : '미디어 삭제',
+	editLink : '링크 속성',
+	deleteLink : '링크 삭제',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : '표 속성',
+	tablecellprop : '열 속성',
+	tableinsert : '표 추가',
+	tabledelete : '표 삭제',
+	tablecolinsertleft : '왼쪽으로 열 추가',
+	tablecolinsertright : '오른쪽으로 열 추가',
+	tablerowinsertabove : '위쪽으로 열 추가',
+	tablerowinsertbelow : '아래쪽으로 열 추가',
+	tablerowmerge : '아래로 병합',
+	tablecolmerge : '오른쪽으로 병합',
+	tablerowsplit : '행 나누기',
+	tablecolsplit : '열 나누기',
+	tablecoldelete : '열 삭제',
+	tablerowdelete : '행 삭제',
+	noColor : '기본색',
+	pleaseSelectFile : '파일 선택',
+	invalidImg : "올바른 주소를 입력하세요.\njpg,gif,bmp,png 형식이 가능합니다.",
+	invalidMedia : "올바른 주소를 입력하세요.\nswf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb 형식이 가능합니다.",
+	invalidWidth : "넓이 값은 숫자여야 합니다.",
+	invalidHeight : "높이 값은 숫자여야 합니다.",
+	invalidBorder : "굵기 값은 숫자여야 합니다.",
+	invalidUrl : "올바른 주소를 입력하세요.",
+	invalidRows : '올바른 행이 아닙니다.',
+	invalidCols : '올바른 열이 아닙니다.',
+	invalidPadding : '안쪽 여백 값은 숫자여야 합니다.',
+	invalidSpacing : '간격 길이 값은 숫자여야 합니다.',
+	invalidJson : '올바른 JSON 형식이 아닙니다.',
+	uploadSuccess : '업로드가 완료되었습니다.',
+	cutError : '브라우저가 잘라내기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
+	copyError : '브라우저가 복사 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
+	pasteError : '브라우저가 붙여넣기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
+	ajaxLoading : '불러오는 중 ...',
+	uploadLoading : '업로드 중 ...',
+	uploadError : '업로드 오류',
+	'plainpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 텍스트를 붙여넣으세요.',
+	'wordpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 워드 텍스트를 붙여넣으세요.',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : '주소',
+	'link.linkType' : '창',
+	'link.newWindow' : '새 창',
+	'link.selfWindow' : '현재 창',
+	'flash.url' : '주소',
+	'flash.width' : '넓이',
+	'flash.height' : '높이',
+	'flash.upload' : '업로드',
+	'flash.viewServer' : '찾아보기',
+	'media.url' : '주소',
+	'media.width' : '넓이',
+	'media.height' : '높이',
+	'media.autostart' : '자동 시작',
+	'media.upload' : '업로드',
+	'media.viewServer' : '찾아보기',
+	'image.remoteImage' : '외부 이미지',
+	'image.localImage' : '내부 이미지',
+	'image.remoteUrl' : '주소',
+	'image.localUrl' : '파일',
+	'image.size' : '크기',
+	'image.width' : '넓이',
+	'image.height' : '높이',
+	'image.resetSize' : '기본 크기로',
+	'image.align' : '정렬',
+	'image.defaultAlign' : '기본',
+	'image.leftAlign' : '왼쪽',
+	'image.rightAlign' : '오른쪽',
+	'image.imgTitle' : '제목',
+	'image.upload' : '찾아보기',
+	'image.viewServer' : '찾아보기',
+	'multiimage.uploadDesc' : '최대 이미지 개수: <%=uploadLimit%>개, 개당 이미지 크기: <%=sizeLimit%>',
+	'multiimage.startUpload' : '업로드 시작',
+	'multiimage.clearAll' : '모두 삭제',
+	'multiimage.insertAll' : '모두 삽입',
+	'multiimage.queueLimitExceeded' : '업로드 개수가 초과되었습니다.',
+	'multiimage.fileExceedsSizeLimit' : '업로드 크기가 초과되었습니다.',
+	'multiimage.zeroByteFile' : '파일 크기가 없습니다.',
+	'multiimage.invalidFiletype' : '올바른 이미지가 아닙니다.',
+	'multiimage.unknownError' : '알 수 없는 업로드 오류가 발생하였습니다.',
+	'multiimage.pending' : '처리 중 ...',
+	'multiimage.uploadError' : '업로드 오류',
+	'filemanager.emptyFolder' : '빈 폴더',
+	'filemanager.moveup' : '위로',
+	'filemanager.viewType' : '보기 방식: ',
+	'filemanager.viewImage' : '미리 보기',
+	'filemanager.listImage' : '목록',
+	'filemanager.orderType' : '정렬 방식: ',
+	'filemanager.fileName' : '이름별',
+	'filemanager.fileSize' : '크기별',
+	'filemanager.fileType' : '종류별',
+	'insertfile.url' : '주소',
+	'insertfile.title' : '제목',
+	'insertfile.upload' : '업로드',
+	'insertfile.viewServer' : '찾아보기',
+	'table.cells' : '열',
+	'table.rows' : '행',
+	'table.cols' : '열',
+	'table.size' : '표 크기',
+	'table.width' : '넓이',
+	'table.height' : '높이',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '간격',
+	'table.padding' : '안쪽여백',
+	'table.spacing' : '간격',
+	'table.align' : '정렬',
+	'table.textAlign' : '수직',
+	'table.verticalAlign' : '수평',
+	'table.alignDefault' : '기본',
+	'table.alignLeft' : '왼쪽',
+	'table.alignCenter' : '가운데',
+	'table.alignRight' : '오른쪽',
+	'table.alignTop' : '위쪽',
+	'table.alignMiddle' : '중간',
+	'table.alignBottom' : '아래쪽',
+	'table.alignBaseline' : '글자기준',
+	'table.border' : '테두리',
+	'table.borderWidth' : '크기',
+	'table.borderColor' : '색상',
+	'table.backgroundColor' : '배경',
+	'map.address' : '주소: ',
+	'map.search' : '검색',
+	'baidumap.address' : '주소: ',
+	'baidumap.search' : '검색',
+	'baidumap.insertDynamicMap' : '동적 지도',
+	'anchor.name' : '책갈피명',
+	'formatblock.formatBlock' : {
+		h1 : '제목 1',
+		h2 : '제목 2',
+		h3 : '제목 3',
+		h4 : '제목 4',
+		p : '본문'
+	},
+	'fontname.fontName' : {
+		'Gulim' : '굴림',
+		'Dotum' : '돋움',
+		'Batang' : '바탕',
+		'Gungsuh' : '궁서',
+		'Malgun Gothic' : '맑은 고딕',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '행간 1'},
+		{'1.5' : '행간 1.5'},
+		{'2' : '행간 2'},
+		{'2.5' : '행간 2.5'},
+		{'3' : '행간 3'}
+	],
+	'template.selectTemplate' : '템플릿',
+	'template.replaceContent' : '내용 바꾸기',
+	'template.fileList' : {
+		'1.html' : '이미지와 텍스트',
+		'2.html' : '표',
+		'3.html' : '목록'
+	}
+}, 'ko');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'ko';

+ 242 - 0
src/main/webapp/static/kindeditor/lang/ru.js

@@ -0,0 +1,242 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+* Translated to Russian by Valery Votintsev (http://codersclub.org/)
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'Source',
+	preview : 'Preview',
+	undo : 'Отмена(Ctrl+Z)',
+	redo : 'Повтор(Ctrl+Y)',
+	cut : 'Вырезать(Ctrl+X)',
+	copy : 'Копировать(Ctrl+C)',
+	paste : 'Вставить(Ctrl+V)',
+	plainpaste : 'Вставить как простой текст',
+	wordpaste : 'Вставить из Word',
+	selectall : 'Выбрать все',
+	justifyleft : 'Выравнивание влево',
+	justifycenter : 'Выравнивание по центру',
+	justifyright : 'Выравнивание вправо',
+	justifyfull : 'Выравнивание по обеим сторонам',
+	insertorderedlist : 'Нумерованый список',
+	insertunorderedlist : 'Ненумерованый список',
+	indent : 'Добавить отступ',
+	outdent : 'Убрать отступ',
+	subscript : 'Надстрочный',
+	superscript : 'Подстрочный',
+	formatblock : 'Формат параграфа',
+	fontname : 'Шрифт',
+	fontsize : 'Размер',
+	forecolor : 'Цвет текста',
+	hilitecolor : 'Цвет фона',
+	bold : 'Жирный(Ctrl+B)',
+	italic : 'Наклонный(Ctrl+I)',
+	underline : 'Подчёркнутый(Ctrl+U)',
+	strikethrough : 'Перечёркнутый',
+	removeformat : 'Удалить формат',
+	image : 'Изображение',
+	multiimage : 'Мульти-загрузка',
+	flash : 'Flash',
+	media : 'Встроенные данные',
+	table : 'Таблица',
+	tablecell : 'Ячейка',
+	hr : 'Горизонтальный разделитель',
+	emoticons : 'Смайл',
+	link : 'Ссылка',
+	unlink : 'Убрать ссылку',
+	fullscreen : 'На весь экран',
+	about : 'О программе',
+	print : 'Печать',
+	filemanager : 'Файлы',
+	code : 'Код',
+	map : 'Карта Google',
+	baidumap : 'Карта Baidu',
+	lineheight : 'Межстрочный интервал',
+	clearhtml : 'Очистить HTML код',
+	pagebreak : 'Разрыв страницы',
+	quickformat : 'Быстрый формат',
+	insertfile : 'Вставить файл',
+	template : 'Вставить шаблон',
+	anchor : 'Якорь',
+	yes : 'OK',
+	no : 'Отмена',
+	close : 'Закрыть',
+	editImage : 'Свойства изображения',
+	deleteImage : 'Удалить изображение',
+	editFlash : 'Свойства Flash',
+	deleteFlash : 'Удалить Flash',
+	editMedia : 'Свойства Media',
+	deleteMedia : 'Удалить Media',
+	editLink : 'Свойства ссылки',
+	deleteLink : 'Удалить ссылку',
+	editAnchor : 'Anchor properties',
+	deleteAnchor : 'Delete Anchor',
+	tableprop : 'Свойства таблицы',
+	tablecellprop : 'Свойства ячейки',
+	tableinsert : 'Вставить таблицу',
+	tabledelete : 'Удалить таблицу',
+	tablecolinsertleft : 'Добавить столбец слева',
+	tablecolinsertright : 'Добавить столбец справа',
+	tablerowinsertabove : 'Добавить строку выше',
+	tablerowinsertbelow : 'Добавить строку ниже',
+	tablerowmerge : 'Объединить вниз',
+	tablecolmerge : 'Объединить вправо',
+	tablerowsplit : 'Разделить строку',
+	tablecolsplit : 'Разделить столбец',
+	tablecoldelete : 'Удалить столбец',
+	tablerowdelete : 'Удалить строку',
+	noColor : 'По умолчанию',
+	pleaseSelectFile : 'Выберите файл.',
+	invalidImg : "Укажите корректный URL изображения.\nРазрешённые форматы: jpg,gif,bmp,png",
+	invalidMedia : "Укажите корректный тип медиа-объекта.\nРазрешённые типы: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
+	invalidWidth : "Ширина должна быть числом.",
+	invalidHeight : "Высота должна быть числом.",
+	invalidBorder : "Ширина рамки должна быть числом.",
+	invalidUrl : "Укажите корректный URL.",
+	invalidRows : 'Неверные строки.',
+	invalidCols : 'Неверные столбцы.',
+	invalidPadding : 'padding должен быть числом.',
+	invalidSpacing : 'spacing должен быть числом.',
+	invalidJson : 'Неверная JSON строка.',
+	uploadSuccess : 'Загрузка завершена.',
+	cutError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+X).',
+	copyError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+C).',
+	pasteError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+V).',
+	ajaxLoading : 'Загрузка ...',
+	uploadLoading : 'Загрузка ...',
+	uploadError : 'Сбой загрузки',
+	'plainpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).',
+	'wordpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).',
+	'code.pleaseInput' : 'Введите код.',
+	'link.url' : 'URL',
+	'link.linkType' : 'Открывать ссылку',
+	'link.newWindow' : 'в новом окне',
+	'link.selfWindow' : 'в том же окне',
+	'flash.url' : 'URL',
+	'flash.width' : 'Ширина',
+	'flash.height' : 'Высота',
+	'flash.upload' : 'Загрузить',
+	'flash.viewServer' : 'Выбрать',
+	'media.url' : 'URL',
+	'media.width' : 'Ширина',
+	'media.height' : 'Высота',
+	'media.autostart' : 'Автостарт',
+	'media.upload' : 'Загрузить',
+	'media.viewServer' : 'Выбрать',
+	'image.remoteImage' : 'Вставить URL изображения',
+	'image.localImage' : 'Загрузить',
+	'image.remoteUrl' : 'URL',
+	'image.localUrl' : 'Файл',
+	'image.size' : 'Размер',
+	'image.width' : 'Ширина',
+	'image.height' : 'Высота',
+	'image.resetSize' : 'Сбросить размеры',
+	'image.align' : 'Выравнивание',
+	'image.defaultAlign' : 'По умолчанию',
+	'image.leftAlign' : 'Влево',
+	'image.rightAlign' : 'Вправо',
+	'image.imgTitle' : 'Название',
+	'image.upload' : 'Загрузить',
+	'image.viewServer' : 'Выбрать',
+	'multiimage.uploadDesc' : 'Максимальное кол-во изображений: <%=uploadLimit%>, Максимальный размер одного изображения: <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Начать загрузку',
+	'multiimage.clearAll' : 'Очистить все',
+	'multiimage.insertAll' : 'Вставить все',
+	'multiimage.queueLimitExceeded' : 'Превышен лимит очереди.',
+	'multiimage.fileExceedsSizeLimit' : 'Превышен максимальный размер файла.',
+	'multiimage.zeroByteFile' : 'Файл нулевой длины.',
+	'multiimage.invalidFiletype' : 'Недопустимый тип файла.',
+	'multiimage.unknownError' : 'Непредвиденная ошибка загрузки.',
+	'multiimage.pending' : 'Ожидает ...',
+	'multiimage.uploadError' : 'Ошибка загрузки',
+	'filemanager.emptyFolder' : 'Папка пуста',
+	'filemanager.moveup' : 'Наверх',
+	'filemanager.viewType' : 'Тип показа: ',
+	'filemanager.viewImage' : 'Превьюшки',
+	'filemanager.listImage' : 'Список',
+	'filemanager.orderType' : 'Сортировка: ',
+	'filemanager.fileName' : 'По имени',
+	'filemanager.fileSize' : 'По размеру',
+	'filemanager.fileType' : 'По типу',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : 'Название',
+	'insertfile.upload' : 'Загрузить',
+	'insertfile.viewServer' : 'Выбрать',
+	'table.cells' : 'Ячейки',
+	'table.rows' : 'Строки',
+	'table.cols' : 'Столбцы',
+	'table.size' : 'Размеры',
+	'table.width' : 'Ширина',
+	'table.height' : 'Высота',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : 'Space',
+	'table.padding' : 'Padding',
+	'table.spacing' : 'Spacing',
+	'table.align' : 'Выравнивание',
+	'table.textAlign' : 'По горизонтали',
+	'table.verticalAlign' : 'По вертикали',
+	'table.alignDefault' : 'По умолчанию',
+	'table.alignLeft' : 'Влево',
+	'table.alignCenter' : 'По центру',
+	'table.alignRight' : 'Вправо',
+	'table.alignTop' : 'Вверх',
+	'table.alignMiddle' : 'Посередине',
+	'table.alignBottom' : 'Вниз',
+	'table.alignBaseline' : 'По базовой линии',
+	'table.border' : 'Рамка',
+	'table.borderWidth' : 'Ширина',
+	'table.borderColor' : 'Цвет',
+	'table.backgroundColor' : 'Цвет фона',
+	'map.address' : 'Адрес: ',
+	'map.search' : 'Поиск',
+	'baidumap.address' : 'Адрес: ',
+	'baidumap.search' : 'Поиск',
+	'baidumap.insertDynamicMap' : 'Динамическая карта',
+	'anchor.name' : 'Имя якоря',
+	'formatblock.formatBlock' : {
+		h1 : 'Заголовок 1',
+		h2 : 'Заголовок 2',
+		h3 : 'Заголовок 3',
+		h4 : 'Заголовок 4',
+		p : 'Обычный текст'
+	},
+	'fontname.fontName' : {
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Comic Sans MS' : 'Comic Sans MS',
+		'Courier New' : 'Courier New',
+		'Garamond' : 'Garamond',
+		'Georgia' : 'Georgia',
+		'Tahoma' : 'Tahoma',
+		'Times New Roman' : 'Times New Roman',
+		'Trebuchet MS' : 'Trebuchet MS',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '1'},
+		{'1.5' : '1.5'},
+		{'2' : '2'},
+		{'2.5' : '2.5'},
+		{'3' : '3'}
+	],
+	'template.selectTemplate' : 'Шаблон',
+	'template.replaceContent' : 'Заменить текущий шаблон',
+	'template.fileList' : {
+		'1.html' : 'Текст и изображения',
+		'2.html' : 'Таблица',
+		'3.html' : 'Список'
+	}
+}, 'en');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'ru';

+ 238 - 0
src/main/webapp/static/kindeditor/lang/zh-CN.js

@@ -0,0 +1,238 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : 'HTML代码',
+	preview : '预览',
+	undo : '后退(Ctrl+Z)',
+	redo : '前进(Ctrl+Y)',
+	cut : '剪切(Ctrl+X)',
+	copy : '复制(Ctrl+C)',
+	paste : '粘贴(Ctrl+V)',
+	plainpaste : '粘贴为无格式文本',
+	wordpaste : '从Word粘贴',
+	selectall : '全选(Ctrl+A)',
+	justifyleft : '左对齐',
+	justifycenter : '居中',
+	justifyright : '右对齐',
+	justifyfull : '两端对齐',
+	insertorderedlist : '编号',
+	insertunorderedlist : '项目符号',
+	indent : '增加缩进',
+	outdent : '减少缩进',
+	subscript : '下标',
+	superscript : '上标',
+	formatblock : '段落',
+	fontname : '字体',
+	fontsize : '文字大小',
+	forecolor : '文字颜色',
+	hilitecolor : '文字背景',
+	bold : '粗体(Ctrl+B)',
+	italic : '斜体(Ctrl+I)',
+	underline : '下划线(Ctrl+U)',
+	strikethrough : '删除线',
+	removeformat : '删除格式',
+	image : '图片',
+	multiimage : '批量图片上传',
+	flash : 'Flash',
+	media : '视音频',
+	table : '表格',
+	tablecell : '单元格',
+	hr : '插入横线',
+	emoticons : '插入表情',
+	link : '超级链接',
+	unlink : '取消超级链接',
+	fullscreen : '全屏显示',
+	about : '关于',
+	print : '打印(Ctrl+P)',
+	filemanager : '文件空间',
+	code : '插入程序代码',
+	map : 'Google地图',
+	baidumap : '百度地图',
+	lineheight : '行距',
+	clearhtml : '清理HTML代码',
+	pagebreak : '插入分页符',
+	quickformat : '一键排版',
+	insertfile : '插入文件',
+	template : '插入模板',
+	anchor : '锚点',
+	yes : '确定',
+	no : '取消',
+	close : '关闭',
+	editImage : '图片属性',
+	deleteImage : '删除图片',
+	editFlash : 'Flash属性',
+	deleteFlash : '删除Flash',
+	editMedia : '视音频属性',
+	deleteMedia : '删除视音频',
+	editLink : '超级链接属性',
+	deleteLink : '取消超级链接',
+	editAnchor : '锚点属性',
+	deleteAnchor : '删除锚点',
+	tableprop : '表格属性',
+	tablecellprop : '单元格属性',
+	tableinsert : '插入表格',
+	tabledelete : '删除表格',
+	tablecolinsertleft : '左侧插入列',
+	tablecolinsertright : '右侧插入列',
+	tablerowinsertabove : '上方插入行',
+	tablerowinsertbelow : '下方插入行',
+	tablerowmerge : '向下合并单元格',
+	tablecolmerge : '向右合并单元格',
+	tablerowsplit : '拆分行',
+	tablecolsplit : '拆分列',
+	tablecoldelete : '删除列',
+	tablerowdelete : '删除行',
+	noColor : '无颜色',
+	pleaseSelectFile : '请选择文件。',
+	invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",
+	invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
+	invalidWidth : "宽度必须为数字。",
+	invalidHeight : "高度必须为数字。",
+	invalidBorder : "边框必须为数字。",
+	invalidUrl : "请输入有效的URL地址。",
+	invalidRows : '行数为必选项,只允许输入大于0的数字。',
+	invalidCols : '列数为必选项,只允许输入大于0的数字。',
+	invalidPadding : '边距必须为数字。',
+	invalidSpacing : '间距必须为数字。',
+	invalidJson : '服务器发生故障。',
+	uploadSuccess : '上传成功。',
+	cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。',
+	copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。',
+	pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。',
+	ajaxLoading : '加载中,请稍候 ...',
+	uploadLoading : '上传中,请稍候 ...',
+	uploadError : '上传错误',
+	'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
+	'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
+	'code.pleaseInput' : '请输入程序代码。',
+	'link.url' : 'URL',
+	'link.linkType' : '打开类型',
+	'link.newWindow' : '新窗口',
+	'link.selfWindow' : '当前窗口',
+	'flash.url' : 'URL',
+	'flash.width' : '宽度',
+	'flash.height' : '高度',
+	'flash.upload' : '上传',
+	'flash.viewServer' : '文件空间',
+	'media.url' : 'URL',
+	'media.width' : '宽度',
+	'media.height' : '高度',
+	'media.autostart' : '自动播放',
+	'media.upload' : '上传',
+	'media.viewServer' : '文件空间',
+	'image.remoteImage' : '网络图片',
+	'image.localImage' : '本地上传',
+	'image.remoteUrl' : '图片地址',
+	'image.localUrl' : '上传文件',
+	'image.size' : '图片大小',
+	'image.width' : '宽',
+	'image.height' : '高',
+	'image.resetSize' : '重置大小',
+	'image.align' : '对齐方式',
+	'image.defaultAlign' : '默认方式',
+	'image.leftAlign' : '左对齐',
+	'image.rightAlign' : '右对齐',
+	'image.imgTitle' : '图片说明',
+	'image.upload' : '浏览...',
+	'image.viewServer' : '图片空间',
+	'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>',
+	'multiimage.startUpload' : '开始上传',
+	'multiimage.clearAll' : '全部清空',
+	'multiimage.insertAll' : '全部插入',
+	'multiimage.queueLimitExceeded' : '文件数量超过限制。',
+	'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。',
+	'multiimage.zeroByteFile' : '无法上传空文件。',
+	'multiimage.invalidFiletype' : '文件类型不正确。',
+	'multiimage.unknownError' : '发生异常,无法上传。',
+	'multiimage.pending' : '等待上传',
+	'multiimage.uploadError' : '上传失败',
+	'filemanager.emptyFolder' : '空文件夹',
+	'filemanager.moveup' : '移到上一级文件夹',
+	'filemanager.viewType' : '显示方式:',
+	'filemanager.viewImage' : '缩略图',
+	'filemanager.listImage' : '详细信息',
+	'filemanager.orderType' : '排序方式:',
+	'filemanager.fileName' : '名称',
+	'filemanager.fileSize' : '大小',
+	'filemanager.fileType' : '类型',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : '文件说明',
+	'insertfile.upload' : '上传',
+	'insertfile.viewServer' : '文件空间',
+	'table.cells' : '单元格数',
+	'table.rows' : '行数',
+	'table.cols' : '列数',
+	'table.size' : '大小',
+	'table.width' : '宽度',
+	'table.height' : '高度',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '边距间距',
+	'table.padding' : '边距',
+	'table.spacing' : '间距',
+	'table.align' : '对齐方式',
+	'table.textAlign' : '水平对齐',
+	'table.verticalAlign' : '垂直对齐',
+	'table.alignDefault' : '默认',
+	'table.alignLeft' : '左对齐',
+	'table.alignCenter' : '居中',
+	'table.alignRight' : '右对齐',
+	'table.alignTop' : '顶部',
+	'table.alignMiddle' : '中部',
+	'table.alignBottom' : '底部',
+	'table.alignBaseline' : '基线',
+	'table.border' : '边框',
+	'table.borderWidth' : '边框',
+	'table.borderColor' : '颜色',
+	'table.backgroundColor' : '背景颜色',
+	'map.address' : '地址: ',
+	'map.search' : '搜索',
+	'baidumap.address' : '地址: ',
+	'baidumap.search' : '搜索',
+	'baidumap.insertDynamicMap' : '插入动态地图',
+	'anchor.name' : '锚点名称',
+	'formatblock.formatBlock' : {
+		h1 : '标题 1',
+		h2 : '标题 2',
+		h3 : '标题 3',
+		h4 : '标题 4',
+		p : '正 文'
+	},
+	'fontname.fontName' : {
+		'SimSun' : '宋体',
+		'NSimSun' : '新宋体',
+		'FangSong_GB2312' : '仿宋_GB2312',
+		'KaiTi_GB2312' : '楷体_GB2312',
+		'SimHei' : '黑体',
+		'Microsoft YaHei' : '微软雅黑',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Times New Roman' : 'Times New Roman',
+		'Courier New' : 'Courier New',
+		'Tahoma' : 'Tahoma',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '单倍行距'},
+		{'1.5' : '1.5倍行距'},
+		{'2' : '2倍行距'},
+		{'2.5' : '2.5倍行距'},
+		{'3' : '3倍行距'}
+	],
+	'template.selectTemplate' : '可选模板',
+	'template.replaceContent' : '替换当前内容',
+	'template.fileList' : {
+		'1.html' : '图片和文字',
+		'2.html' : '表格',
+		'3.html' : '项目编号'
+	}
+}, 'zh-CN');
+
+KindEditor.options.langType = 'zh-CN';

+ 243 - 0
src/main/webapp/static/kindeditor/lang/zh-TW.js

@@ -0,0 +1,243 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.lang({
+	source : '原始碼',
+	preview : '預覽',
+	undo : '復原(Ctrl+Z)',
+	redo : '重複(Ctrl+Y)',
+	cut : '剪下(Ctrl+X)',
+	copy : '複製(Ctrl+C)',
+	paste : '貼上(Ctrl+V)',
+	plainpaste : '貼為純文字格式',
+	wordpaste : '自Word貼上',
+	selectall : '全選(Ctrl+A)',
+	justifyleft : '靠左對齊',
+	justifycenter : '置中',
+	justifyright : '靠右對齊',
+	justifyfull : '左右對齊',
+	insertorderedlist : '編號清單',
+	insertunorderedlist : '項目清單',
+	indent : '增加縮排',
+	outdent : '減少縮排',
+	subscript : '下標',
+	superscript : '上標',
+	formatblock : '標題',
+	fontname : '字體',
+	fontsize : '文字大小',
+	forecolor : '文字顏色',
+	hilitecolor : '背景顏色',
+	bold : '粗體(Ctrl+B)',
+	italic : '斜體(Ctrl+I)',
+	underline : '底線(Ctrl+U)',
+	strikethrough : '刪除線',
+	removeformat : '清除格式',
+	image : '影像',
+	multiimage : '批量影像上傳',
+	flash : 'Flash',
+	media : '多媒體',
+	table : '表格',
+	tablecell : '儲存格',
+	hr : '插入水平線',
+	emoticons : '插入表情',
+	link : '超連結',
+	unlink : '移除超連結',
+	fullscreen : '最大化',
+	about : '關於',
+	print : '列印(Ctrl+P)',
+	filemanager : '瀏覽伺服器',
+	code : '插入程式代碼',
+	map : 'Google地圖',
+	baidumap : 'Baidu地圖',
+	lineheight : '行距',
+	clearhtml : '清理HTML代碼',
+	pagebreak : '插入分頁符號',
+	quickformat : '快速排版',
+	insertfile : '插入文件',
+	template : '插入樣板',
+	anchor : '錨點',
+	yes : '確定',
+	no : '取消',
+	close : '關閉',
+	editImage : '影像屬性',
+	deleteImage : '刪除影像',
+	editFlash : 'Flash屬性',
+	deleteFlash : '删除Flash',
+	editMedia : '多媒體屬性',
+	deleteMedia : '删除多媒體',
+	editLink : '超連結屬性',
+	deleteLink : '移除超連結',
+	editAnchor : '锚点属性',
+	deleteAnchor : '删除锚点',
+	tableprop : '表格屬性',
+	tablecellprop : '儲存格屬性',
+	tableinsert : '插入表格',
+	tabledelete : '刪除表格',
+	tablecolinsertleft : '向左插入列',
+	tablecolinsertright : '向右插入列',
+	tablerowinsertabove : '向上插入欄',
+	tablerowinsertbelow : '下方插入欄',
+	tablerowmerge : '向下合併單元格',
+	tablecolmerge : '向右合併單元格',
+	tablerowsplit : '分割欄',
+	tablecolsplit : '分割列',
+	tablecoldelete : '删除列',
+	tablerowdelete : '删除欄',
+	noColor : '自動',
+	pleaseSelectFile : '請選擇文件。',
+	invalidImg : "請輸入有效的URL。\n只允許jpg,gif,bmp,png格式。",
+	invalidMedia : "請輸入有效的URL。\n只允許swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
+	invalidWidth : "寬度必須是數字。",
+	invalidHeight : "高度必須是數字。",
+	invalidBorder : "邊框必須是數字。",
+	invalidUrl : "請輸入有效的URL。",
+	invalidRows : '欄數是必須輸入項目,只允許輸入大於0的數字。',
+	invalidCols : '列數是必須輸入項目,只允許輸入大於0的數字。',
+	invalidPadding : '內距必須是數字。',
+	invalidSpacing : '間距必須是數字。',
+	invalidJson : '伺服器發生故障。',
+	uploadSuccess : '上傳成功。',
+	cutError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+X)完成。',
+	copyError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+C)完成。',
+	pasteError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+V)完成。',
+	ajaxLoading : '加載中,請稍候 ...',
+	uploadLoading : '上傳中,請稍候 ...',
+	uploadError : '上傳錯誤',
+	'plainpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。',
+	'wordpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。',
+	'code.pleaseInput' : 'Please input code.',
+	'link.url' : 'URL',
+	'link.linkType' : '打開類型',
+	'link.newWindow' : '新窗口',
+	'link.selfWindow' : '本頁窗口',
+	'flash.url' : 'URL',
+	'flash.width' : '寬度',
+	'flash.height' : '高度',
+	'flash.upload' : '上傳',
+	'flash.viewServer' : '瀏覽',
+	'media.url' : 'URL',
+	'media.width' : '寬度',
+	'media.height' : '高度',
+	'media.autostart' : '自動播放',
+	'media.upload' : '上傳',
+	'media.viewServer' : '瀏覽',
+	'image.remoteImage' : '網絡影像',
+	'image.localImage' : '上傳影像',
+	'image.remoteUrl' : '影像URL',
+	'image.localUrl' : '影像URL',
+	'image.size' : '影像大小',
+	'image.width' : '寬度',
+	'image.height' : '高度',
+	'image.resetSize' : '原始大小',
+	'image.align' : '對齊方式',
+	'image.defaultAlign' : '未設定',
+	'image.leftAlign' : '向左對齊',
+	'image.rightAlign' : '向右對齊',
+	'image.imgTitle' : '影像說明',
+	'image.upload' : '瀏覽...',
+	'image.viewServer' : '瀏覽...',
+	'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
+	'multiimage.startUpload' : 'Start upload',
+	'multiimage.clearAll' : 'Clear all',
+	'multiimage.insertAll' : 'Insert all',
+	'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
+	'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
+	'multiimage.zeroByteFile' : 'Zero byte file.',
+	'multiimage.invalidFiletype' : 'Invalid file type.',
+	'multiimage.unknownError' : 'Unknown upload error.',
+	'multiimage.pending' : 'Pending ...',
+	'multiimage.uploadError' : 'Upload error',
+	'filemanager.emptyFolder' : '空文件夾',
+	'filemanager.moveup' : '至上一級文件夾',
+	'filemanager.viewType' : '顯示方式:',
+	'filemanager.viewImage' : '縮略圖',
+	'filemanager.listImage' : '詳細信息',
+	'filemanager.orderType' : '排序方式:',
+	'filemanager.fileName' : '名稱',
+	'filemanager.fileSize' : '大小',
+	'filemanager.fileType' : '類型',
+	'insertfile.url' : 'URL',
+	'insertfile.title' : '文件說明',
+	'insertfile.upload' : '上傳',
+	'insertfile.viewServer' : '瀏覽',
+	'table.cells' : '儲存格數',
+	'table.rows' : '欄數',
+	'table.cols' : '列數',
+	'table.size' : '表格大小',
+	'table.width' : '寬度',
+	'table.height' : '高度',
+	'table.percent' : '%',
+	'table.px' : 'px',
+	'table.space' : '內距間距',
+	'table.padding' : '內距',
+	'table.spacing' : '間距',
+	'table.align' : '對齊方式',
+	'table.textAlign' : '水平對齊',
+	'table.verticalAlign' : '垂直對齊',
+	'table.alignDefault' : '未設定',
+	'table.alignLeft' : '向左對齊',
+	'table.alignCenter' : '置中',
+	'table.alignRight' : '向右對齊',
+	'table.alignTop' : '靠上',
+	'table.alignMiddle' : '置中',
+	'table.alignBottom' : '靠下',
+	'table.alignBaseline' : '基線',
+	'table.border' : '表格邊框',
+	'table.borderWidth' : '邊框',
+	'table.borderColor' : '顏色',
+	'table.backgroundColor' : '背景顏色',
+	'map.address' : '住所: ',
+	'map.search' : '尋找',
+	'baidumap.address' : '住所: ',
+	'baidumap.search' : '尋找',
+	'baidumap.insertDynamicMap' : '插入動態地圖',
+	'anchor.name' : '錨點名稱',
+	'formatblock.formatBlock' : {
+		h1 : '標題 1',
+		h2 : '標題 2',
+		h3 : '標題 3',
+		h4 : '標題 4',
+		p : '一般'
+	},
+	'fontname.fontName' : {
+		'MingLiU' : '細明體',
+		'PMingLiU' : '新細明體',
+		'DFKai-SB' : '標楷體',
+		'SimSun' : '宋體',
+		'NSimSun' : '新宋體',
+		'FangSong' : '仿宋體',
+		'Arial' : 'Arial',
+		'Arial Black' : 'Arial Black',
+		'Times New Roman' : 'Times New Roman',
+		'Courier New' : 'Courier New',
+		'Tahoma' : 'Tahoma',
+		'Verdana' : 'Verdana'
+	},
+	'lineheight.lineHeight' : [
+		{'1' : '单倍行距'},
+		{'1.5' : '1.5倍行距'},
+		{'2' : '2倍行距'},
+		{'2.5' : '2.5倍行距'},
+		{'3' : '3倍行距'}
+	],
+	'template.selectTemplate' : '可選樣板',
+	'template.replaceContent' : '取代當前內容',
+	'template.fileList' : {
+		'1.html' : '影像和文字',
+		'2.html' : '表格',
+		'3.html' : '项目清單'
+	}
+}, 'zh-TW');
+
+KindEditor.each(KindEditor.options.items, function(i, name) {
+	if (name == 'baidumap') {
+		KindEditor.options.items[i] = 'map';
+	}
+});
+KindEditor.options.langType = 'zh-TW';

+ 502 - 0
src/main/webapp/static/kindeditor/license.txt

@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!

+ 46 - 0
src/main/webapp/static/kindeditor/plugins/anchor/anchor.js

@@ -0,0 +1,46 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('anchor', function(K) {
+	var self = this, name = 'anchor', lang = self.lang(name + '.');
+	self.plugin.anchor = {
+		edit : function() {
+			var html = ['<div style="padding:20px;">',
+					'<div class="ke-dialog-row">',
+					'<label for="keName">' + lang.name + '</label>',
+					'<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />',
+					'</div>',
+					'</div>'].join('');
+			var dialog = self.createDialog({
+				name : name,
+				width : 300,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus();
+					}
+				}
+			});
+			var div = dialog.div,
+				nameBox = K('input[name="name"]', div);
+			var img = self.plugin.getSelectedAnchor();
+			if (img) {
+				nameBox.val(unescape(img.attr('data-ke-name')));
+			}
+			nameBox[0].focus();
+			nameBox[0].select();
+		},
+		'delete' : function() {
+			self.plugin.getSelectedAnchor().remove();
+		}
+	};
+	self.clickToolbar(name, self.plugin.anchor.edit);
+});

+ 54 - 0
src/main/webapp/static/kindeditor/plugins/autoheight/autoheight.js

@@ -0,0 +1,54 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('autoheight', function(K) {
+	var self = this;
+
+	if (!self.autoHeightMode) {
+		return;
+	}
+
+	var minHeight;
+
+	function hideScroll() {
+		var edit = self.edit;
+		var body = edit.doc.body;
+		edit.iframe[0].scroll = 'no';
+		body.style.overflowY = 'hidden';
+	}
+
+	function resetHeight() {
+		var edit = self.edit;
+		var body = edit.doc.body;
+		edit.iframe.height(minHeight);
+		self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight));
+	}
+
+	function init() {
+		minHeight = K.removeUnit(self.height);
+
+		self.edit.afterChange(resetHeight);
+		hideScroll();
+		resetHeight();
+	}
+
+	if (self.isCreated) {
+		init();
+	} else {
+		self.afterCreate(init);
+	}
+});
+
+/*
+* 如何实现真正的自动高度?
+* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。
+* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。
+* 由此就实现了真正的自动高度
+* 测试:chrome、firefox、IE9、IE8
+* */

+ 93 - 0
src/main/webapp/static/kindeditor/plugins/baidumap/baidumap.js

@@ -0,0 +1,93 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+// Baidu Maps: http://dev.baidu.com/wiki/map/index.php?title=%E9%A6%96%E9%A1%B5
+
+KindEditor.plugin('baidumap', function(K) {
+	var self = this, name = 'baidumap', lang = self.lang(name + '.');
+	var mapWidth = K.undef(self.mapWidth, 558);
+	var mapHeight = K.undef(self.mapHeight, 360);
+	self.clickToolbar(name, function() {
+		var html = ['<div style="padding:10px 20px;">',
+			'<div class="ke-header">',
+			// left start
+			'<div class="ke-left">',
+			lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ',
+			'<span class="ke-button-common ke-button-outer">',
+			'<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />',
+			'</span>',
+			'</div>',
+			// right start
+			'<div class="ke-right">',
+			'<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>',
+			'</div>',
+			'<div class="ke-clearfix"></div>',
+			'</div>',
+			'<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>',
+			'</div>'].join('');
+		var dialog = self.createDialog({
+			name : name,
+			width : mapWidth + 42,
+			title : self.lang(name),
+			body : html,
+			yesBtn : {
+				name : self.lang('yes'),
+				click : function(e) {
+					var map = win.map;
+					var centerObj = map.getCenter();
+					var center = centerObj.lng + ',' + centerObj.lat;
+					var zoom = map.getZoom();
+					var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage',
+						'?center=' + encodeURIComponent(center),
+						'&zoom=' + encodeURIComponent(zoom),
+						'&width=' + mapWidth,
+						'&height=' + mapHeight,
+						'&markers=' + encodeURIComponent(center),
+						'&markerStyles=' + encodeURIComponent('l,A')].join('');
+					if (checkbox[0].checked) {
+						self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>');
+					} else {
+						self.exec('insertimage', url);
+					}
+					self.hideDialog().focus();
+				}
+			},
+			beforeRemove : function() {
+				searchBtn.remove();
+				if (doc) {
+					doc.write('');
+				}
+				iframe.remove();
+			}
+		});
+		var div = dialog.div,
+			addressBox = K('[name="address"]', div),
+			searchBtn = K('[name="searchBtn"]', div),
+			checkbox = K('[name="insertDynamicMap"]', dialog.div),
+			win, doc;
+		var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>');
+		function ready() {
+			win = iframe[0].contentWindow;
+			doc = K.iframeDoc(iframe);
+		}
+		iframe.bind('load', function() {
+			iframe.unbind('load');
+			if (K.IE) {
+				ready();
+			} else {
+				setTimeout(ready, 0);
+			}
+		});
+		K('.ke-map', div).replaceWith(iframe);
+		// search map
+		searchBtn.click(function() {
+			win.search(addressBox.val());
+		});
+	});
+});

+ 83 - 0
src/main/webapp/static/kindeditor/plugins/baidumap/index.html

@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta charset="utf-8" />
+<meta name="keywords" content="百度地图,百度地图API,百度地图自定义工具,百度地图所见即所得工具" />
+<meta name="description" content="百度地图API自定义地图,帮助用户在可视化操作下生成百度地图" />
+<title>百度地图API自定义地图</title>
+<!--引用百度地图API-->
+<style type="text/css">
+	html,body{margin:0;padding:0;}
+	.iw_poi_title {color:#CC5522;font-size:14px;font-weight:bold;overflow:hidden;padding-right:13px;white-space:nowrap}
+	.iw_poi_content {font:12px arial,sans-serif;overflow:visible;padding-top:4px;white-space:-moz-pre-wrap;word-wrap:break-word}
+</style>
+<script type="text/javascript" src="http://api.map.baidu.com/api?key=&v=1.1&services=true"></script>
+</head>
+
+<body onload="initMap();">
+  <!--百度地图容器-->
+  <div style="width:697px;height:550px;border:#ccc solid 1px;" id="dituContent"></div>
+</body>
+<script type="text/javascript">
+	function getParam(name) {
+		return location.href.match(new RegExp('[?&]' + name + '=([^?&]+)', 'i')) ? decodeURIComponent(RegExp.$1) : '';
+	}
+	var centerParam = getParam('center');
+	var zoomParam = getParam('zoom');
+	var widthParam = getParam('width');
+	var heightParam = getParam('height');
+	var markersParam = getParam('markers');
+	var markerStylesParam = getParam('markerStyles');
+
+	//创建和初始化地图函数:
+	function initMap(){
+		// [FF]切换模式后报错
+		if (!window.BMap) {
+			return;
+		}
+		var dituContent = document.getElementById('dituContent');
+		dituContent.style.width = widthParam + 'px';
+		dituContent.style.height = heightParam + 'px';
+
+		createMap();//创建地图
+		setMapEvent();//设置地图事件
+		addMapControl();//向地图添加控件
+
+		// 创建标注
+		var markersArr = markersParam.split(',');
+		var point = new BMap.Point(markersArr[0], markersArr[1]);
+		var marker = new BMap.Marker(point);
+		map.addOverlay(marker); // 将标注添加到地图中
+	}
+
+	//创建地图函数:
+	function createMap(){
+		var map = new BMap.Map("dituContent");//在百度地图容器中创建一个地图
+		var centerArr = centerParam.split(',');
+		var point = new BMap.Point(centerArr[0], centerArr[1]);//定义一个中心点坐标
+		map.centerAndZoom(point, zoomParam);//设定地图的中心点和坐标并将地图显示在地图容器中
+		window.map = map;//将map变量存储在全局
+	}
+
+	//地图事件设置函数:
+	function setMapEvent(){
+		map.enableDragging();//启用地图拖拽事件,默认启用(可不写)
+		map.enableScrollWheelZoom();//启用地图滚轮放大缩小
+		map.enableDoubleClickZoom();//启用鼠标双击放大,默认启用(可不写)
+		map.enableKeyboard();//启用键盘上下左右键移动地图
+	}
+
+	//地图控件添加函数:
+	function addMapControl(){
+		//向地图中添加缩放控件
+	var ctrl_nav = new BMap.NavigationControl({anchor:BMAP_ANCHOR_TOP_LEFT,type:BMAP_NAVIGATION_CONTROL_LARGE});
+	map.addControl(ctrl_nav);
+		//向地图中添加缩略图控件
+	var ctrl_ove = new BMap.OverviewMapControl({anchor:BMAP_ANCHOR_BOTTOM_RIGHT,isOpen:1});
+	map.addControl(ctrl_ove);
+		//向地图中添加比例尺控件
+	var ctrl_sca = new BMap.ScaleControl({anchor:BMAP_ANCHOR_BOTTOM_LEFT});
+	map.addControl(ctrl_sca);
+	}
+</script>
+</html>

+ 43 - 0
src/main/webapp/static/kindeditor/plugins/baidumap/map.html

@@ -0,0 +1,43 @@
+<!doctype html>
+<html>
+	<head>
+		<meta charset="utf-8" />
+		<title>Baidu Maps</title>
+		<style>
+			html { height: 100% }
+			body { height: 100%; margin: 0; padding: 0; background-color: #FFF }
+		</style>
+		<script charset="utf-8" src="http://api.map.baidu.com/api?v=1.3"></script>
+		<script>
+			var map, geocoder;
+			function initialize() {
+				map = new BMap.Map('map_canvas');
+				var point = new BMap.Point(121.473704, 31.230393);
+				map.centerAndZoom(point, 11);
+				map.addControl(new BMap.NavigationControl());
+				map.enableScrollWheelZoom();
+
+				var gc = new BMap.Geocoder();
+				gc.getLocation(point, function(rs){
+					var addComp = rs.addressComponents;
+					var address = [addComp.city].join('');
+					parent.document.getElementById("kindeditor_plugin_map_address").value = address;
+				});
+			}
+			function search(address) {
+				if (!map) return;
+				var local = new BMap.LocalSearch(map, {
+					renderOptions: {
+						map: map,
+						autoViewport: true,
+						selectFirstResult: false
+					}
+				});
+				local.search(address);
+			}
+		</script>
+	</head>
+	<body onload="initialize();">
+		<div id="map_canvas" style="width:100%; height:100%"></div>
+	</body>
+</html>

+ 29 - 0
src/main/webapp/static/kindeditor/plugins/clearhtml/clearhtml.js

@@ -0,0 +1,29 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('clearhtml', function(K) {
+	var self = this, name = 'clearhtml';
+	self.clickToolbar(name, function() {
+		self.focus();
+		var html = self.html();
+		html = html.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/ig, '');
+		html = html.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/ig, '');
+		html = K.formatHtml(html, {
+			a : ['href', 'target'],
+			embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'],
+			img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'],
+			table : ['border'],
+			'td,th' : ['rowspan', 'colspan'],
+			'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : []
+		});
+		self.html(html);
+		self.cmd.selection(true);
+		self.addBookmark();
+	});
+});

+ 62 - 0
src/main/webapp/static/kindeditor/plugins/code/code.js

@@ -0,0 +1,62 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+// google code prettify: http://google-code-prettify.googlecode.com/
+// http://google-code-prettify.googlecode.com/
+
+KindEditor.plugin('code', function(K) {
+	var self = this, name = 'code';
+	self.clickToolbar(name, function() {
+		var lang = self.lang(name + '.'),
+			html = ['<div style="padding:10px 20px;">',
+				'<div class="ke-dialog-row">',
+				'<select class="ke-code-type">',
+				'<option value="js">JavaScript</option>',
+				'<option value="html">HTML</option>',
+				'<option value="css">CSS</option>',
+				'<option value="php">PHP</option>',
+				'<option value="pl">Perl</option>',
+				'<option value="py">Python</option>',
+				'<option value="rb">Ruby</option>',
+				'<option value="java">Java</option>',
+				'<option value="vb">ASP/VB</option>',
+				'<option value="cpp">C/C++</option>',
+				'<option value="cs">C#</option>',
+				'<option value="xml">XML</option>',
+				'<option value="bsh">Shell</option>',
+				'<option value="">Other</option>',
+				'</select>',
+				'</div>',
+				'<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>',
+				'</div>'].join(''),
+			dialog = self.createDialog({
+				name : name,
+				width : 450,
+				title : self.lang(name),
+				body : html,
+				yesBtn : {
+					name : self.lang('yes'),
+					click : function(e) {
+						var type = K('.ke-code-type', dialog.div).val(),
+							code = textarea.val(),
+							cls = type === '' ? '' :  ' lang-' + type,
+							html = '<pre class="prettyprint' + cls + '">\n' + K.escape(code) + '</pre> ';
+						if (K.trim(code) === '') {
+							alert(lang.pleaseInput);
+							textarea[0].focus();
+							return;
+						}
+						self.insertHtml(html).hideDialog().focus();
+					}
+				}
+			}),
+			textarea = K('textarea', dialog.div);
+		textarea[0].focus();
+	});
+});

文件差異過大導致無法顯示
+ 13 - 0
src/main/webapp/static/kindeditor/plugins/code/prettify.css


文件差異過大導致無法顯示
+ 28 - 0
src/main/webapp/static/kindeditor/plugins/code/prettify.js


+ 129 - 0
src/main/webapp/static/kindeditor/plugins/emoticons/emoticons.js

@@ -0,0 +1,129 @@
+/*******************************************************************************
+* KindEditor - WYSIWYG HTML Editor for Internet
+* Copyright (C) 2006-2011 kindsoft.net
+*
+* @author Roddy <luolonghao@gmail.com>
+* @site http://www.kindsoft.net/
+* @licence http://www.kindsoft.net/license.php
+*******************************************************************************/
+
+KindEditor.plugin('emoticons', function(K) {
+	var self = this, name = 'emoticons',
+		path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'),
+		allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons,
+		currentPageNum = 1;
+	self.clickToolbar(name, function() {
+		var rows = 5, cols = 9, total = 135, startNum = 0,
+			cells = rows * cols, pages = Math.ceil(total / cells),
+			colsHalf = Math.floor(cols / 2),
+			wrapperDiv = K('<div class="ke-plugin-emoticons"></div>'),
+			elements = [],
+			menu = self.createMenu({
+				name : name,
+				beforeRemove : function() {
+					removeEvent();
+				}
+			});
+		menu.div.append(wrapperDiv);
+		var previewDiv, previewImg;
+		if (allowPreview) {
+			previewDiv = K('<div class="ke-preview"></div>').css('right', 0);
+			previewImg = K('<img class="ke-preview-img" src="' + path + startNum + '.gif" />');
+			wrapperDiv.append(previewDiv);
+			previewDiv.append(previewImg);
+		}
+		function bindCellEvent(cell, j, num) {
+			if (previewDiv) {
+				cell.mouseover(function() {
+					if (j > colsHalf) {
+						previewDiv.css('left', 0);
+						previewDiv.css('right', '');
+					} else {
+						previewDiv.css('left', '');
+						previewDiv.css('right', 0);
+					}
+					previewImg.attr('src', path + num + '.gif');
+					K(this).addClass('ke-on');
+				});
+			} else {
+				cell.mouseover(function() {
+					K(this).addClass('ke-on');
+				});
+			}
+			cell.mouseout(function() {
+				K(this).removeClass('ke-on');
+			});
+			cell.click(function(e) {
+				self.insertHtml('<img src="' + path + num + '.gif" border="0" alt="" />').hideMenu().focus();
+				e.stop();
+			});
+		}
+		function createEmoticonsTable(pageNum, parentDiv) {
+			var table = document.createElement('table');
+			parentDiv.append(table);
+			if (previewDiv) {
+				K(table).mouseover(function() {
+					previewDiv.show('block');
+				});
+				K(table).mouseout(function() {
+					previewDiv.hide();
+				});
+				elements.push(K(table));
+			}
+			table.className = 'ke-table';
+			table.cellPadding = 0;
+			table.cellSpacing = 0;
+			table.border = 0;
+			var num = (pageNum - 1) * cells + startNum;
+			for (var i = 0; i < rows; i++) {
+				var row = table.insertRow(i);
+				for (var j = 0; j < cols; j++) {
+					var cell = K(row.insertCell(j));
+					cell.addClass('ke-cell');
+					bindCellEvent(cell, j, num);
+					var span = K('<span class="ke-img"></span>')
+						.css('background-position', '-' + (24 * num) + 'px 0px')
+						.css('background-image', 'url(' + path + 'static.gif)');
+					cell.append(span);
+					elements.push(cell);
+					num++;
+				}
+			}
+			return table;
+		}
+		var table = createEmoticonsTable(currentPageNum, wrapperDiv);
+		function removeEvent() {
+			K.each(elements, function() {
+				this.unbind();
+			});
+		}
+		var pageDiv;
+		function bindPageEvent(el, pageNum) {
+			el.click(function(e) {
+				removeEvent();
+				table.parentNode.removeChild(table);
+				pageDiv.remove();
+				table = createEmoticonsTable(pageNum, wrapperDiv);
+				createPageTable(pageNum);
+				currentPageNum = pageNum;
+				e.stop();
+			});
+		}
+		function createPageTable(currentPageNum) {
+			pageDiv = K('<div class="ke-page"></div>');
+			wrapperDiv.append(pageDiv);
+			for (var pageNum = 1; pageNum <= pages; pageNum++) {
+				if (currentPageNum !== pageNum) {
+					var a = K('<a href="javascript:;">[' + pageNum + ']</a>');
+					bindPageEvent(a, pageNum);
+					pageDiv.append(a);
+					elements.push(a);
+				} else {
+					pageDiv.append(K('@[' + pageNum + ']'));
+				}
+				pageDiv.append(K('@&nbsp;'));
+			}
+		}
+		createPageTable(currentPageNum);
+	});
+});

二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/0.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/1.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/10.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/100.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/101.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/102.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/103.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/104.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/105.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/106.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/107.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/108.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/109.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/11.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/110.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/111.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/112.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/113.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/114.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/115.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/116.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/117.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/118.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/119.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/12.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/120.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/121.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/122.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/123.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/124.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/125.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/126.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/127.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/128.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/129.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/13.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/130.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/131.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/132.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/133.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/134.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/14.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/15.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/16.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/17.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/18.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/19.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/2.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/20.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/21.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/22.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/23.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/24.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/25.gif


二進制
src/main/webapp/static/kindeditor/plugins/emoticons/images/26.gif


+ 0 - 0
src/main/webapp/static/kindeditor/plugins/emoticons/images/27.gif


部分文件因文件數量過多而無法顯示