├── .gitattributes ├── pic ├── druid.png ├── addkemu.png ├── denglu.png ├── guanli.png ├── sahngchuan.png └── qq-connect-sdk4J.jar ├── src ├── main │ ├── webapp │ │ ├── favicon.ico │ │ ├── img │ │ │ ├── bg.jpg │ │ │ ├── favicon.ico │ │ │ ├── headdefault.jpg │ │ │ └── backgroundimg.jpeg │ │ ├── weblib │ │ │ ├── fileinput │ │ │ │ ├── img │ │ │ │ │ ├── loading.gif │ │ │ │ │ └── loading-sm.gif │ │ │ │ ├── js │ │ │ │ │ ├── plugins │ │ │ │ │ │ ├── canvas-to-blob.min.js │ │ │ │ │ │ └── canvas-to-blob.js │ │ │ │ │ └── locales │ │ │ │ │ │ └── zh.js │ │ │ │ ├── themes │ │ │ │ │ ├── fa │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ └── theme.js │ │ │ │ │ ├── gly │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ └── theme.js │ │ │ │ │ └── explorer │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ ├── theme.js │ │ │ │ │ │ ├── theme.min.css │ │ │ │ │ │ └── theme.css │ │ │ │ └── css │ │ │ │ │ └── fileinput.min.css │ │ │ ├── bootstrap │ │ │ │ ├── fonts │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ │ ├── js │ │ │ │ │ └── npm.js │ │ │ │ └── css │ │ │ │ │ └── bootstrap-datetimepicker.min.css │ │ │ └── moment │ │ │ │ └── zh-cn.js │ │ ├── css │ │ │ ├── subject.css │ │ │ └── base.css │ │ ├── js │ │ │ ├── base.js │ │ │ ├── canvas-nest.min.js │ │ │ ├── filterurl.js │ │ │ └── canvas-nest.js │ │ ├── jsp │ │ │ ├── footer.jsp │ │ │ ├── error.jsp │ │ │ ├── error_500.jsp │ │ │ ├── addsubjectui.jsp │ │ │ ├── upfileui.jsp │ │ │ ├── subjectui.jsp │ │ │ ├── downfileui.jsp │ │ │ ├── editsubjectui.jsp │ │ │ ├── BindQQ.jsp │ │ │ ├── cpasswd.jsp │ │ │ ├── firstpd.jsp │ │ │ └── login.jsp │ │ ├── index.jsp │ │ └── WEB-INF │ │ │ └── web.xml │ ├── resources │ │ ├── context.properties │ │ ├── mybatis.xml │ │ ├── logback.xml │ │ ├── qqconnectconfig.properties │ │ ├── HistoryMapper.xml │ │ ├── UserMapper.xml │ │ ├── springmvc.xml │ │ ├── OrderInfoMapper.xml │ │ └── applicationContext.xml │ └── java │ │ └── com │ │ └── ning │ │ ├── exception │ │ ├── file │ │ │ └── FileException.java │ │ ├── login │ │ │ └── LoginException.java │ │ └── defaults │ │ │ ├── DefaultException.java │ │ │ └── ExceptionResolver.java │ │ ├── util │ │ ├── qqlogin │ │ │ └── QQLoginUtil.java │ │ └── properties │ │ │ └── PropertiesUtil.java │ │ ├── file │ │ ├── dao │ │ │ ├── OrderInfoDao.java │ │ │ └── HistoryDao.java │ │ ├── entity │ │ │ ├── OrderInfo.java │ │ │ └── History.java │ │ ├── service │ │ │ ├── FileService.java │ │ │ └── impl │ │ │ │ └── FileServiceImpl.java │ │ └── action │ │ │ └── FileAction.java │ │ ├── admin │ │ ├── service │ │ │ ├── AdminService.java │ │ │ └── impl │ │ │ │ └── AdminServiceImpl.java │ │ └── action │ │ │ └── AdminAction.java │ │ └── login │ │ ├── dao │ │ └── UserDao.java │ │ ├── service │ │ ├── UserService.java │ │ ├── impl │ │ │ └── UserServiceImpl.java │ │ └── CustomRealm.java │ │ ├── entity │ │ └── User.java │ │ └── action │ │ └── Login.java └── test │ └── java │ └── top │ └── itning │ └── ta │ └── LogTest.java ├── .gitignore ├── install-qq-connect-dependency.bat ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=java -------------------------------------------------------------------------------- /pic/druid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/pic/druid.png -------------------------------------------------------------------------------- /pic/addkemu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/pic/addkemu.png -------------------------------------------------------------------------------- /pic/denglu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/pic/denglu.png -------------------------------------------------------------------------------- /pic/guanli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/pic/guanli.png -------------------------------------------------------------------------------- /pic/sahngchuan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/pic/sahngchuan.png -------------------------------------------------------------------------------- /pic/qq-connect-sdk4J.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/pic/qq-connect-sdk4J.jar -------------------------------------------------------------------------------- /src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /src/main/webapp/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/img/bg.jpg -------------------------------------------------------------------------------- /src/main/webapp/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/img/favicon.ico -------------------------------------------------------------------------------- /src/main/webapp/img/headdefault.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/img/headdefault.jpg -------------------------------------------------------------------------------- /src/main/webapp/img/backgroundimg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/img/backgroundimg.jpeg -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/weblib/fileinput/img/loading.gif -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/img/loading-sm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/weblib/fileinput/img/loading-sm.gif -------------------------------------------------------------------------------- /src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/Student-Homework-Management-System/HEAD/src/main/webapp/weblib/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/main/webapp/css/subject.css: -------------------------------------------------------------------------------- 1 | .input-group { 2 | padding-left: 15px !important; 3 | padding-right: 15px !important; 4 | } 5 | 6 | .form-horizontal { 7 | padding-left: 15px !important; 8 | padding-right: 15px !important; 9 | } -------------------------------------------------------------------------------- /src/main/resources/context.properties: -------------------------------------------------------------------------------- 1 | driverClass=com.mysql.cj.jdbc.Driver 2 | jdbcUrl=jdbc:mysql://localhost:3306/shw?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=0&serverTimezone=UTC 3 | dbuser=root 4 | dbpassword=root 5 | globalSessionTimeout=1800000 6 | maxAge=2592000 7 | maxUploadSize=209715200 8 | upLoadFilePath=/data/hwupload/ -------------------------------------------------------------------------------- /src/main/webapp/css/base.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Microsoft YaHei UI", serif; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | 8 | 9 | /*@media (max-width: 992px) {*/ 10 | .background { 11 | background: url("../img/bg.jpg") fixed center; 12 | background-size: cover; 13 | } 14 | /*}*/ 15 | 16 | .blur { 17 | background: rgba(233, 233, 233, .6); 18 | border-radius: 10px; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | .idea/ 24 | Shw.iml 25 | target/ 26 | Student-Homework-Management-System.iml 27 | -------------------------------------------------------------------------------- /install-qq-connect-dependency.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo author itning 3 | set ROOT_DIR=%~dp0 4 | set JAR_DIR=%ROOT_DIR%pic\ 5 | set INSTALL_VERSION=2.0.0.RELEASE 6 | if not exist %JAR_DIR%qq-connect-sdk4J.jar call:file_not_found_func qq-connect-sdk4J.jar 7 | call mvn install:install-file -Dfile=%JAR_DIR%qq-connect-sdk4J.jar -DgroupId=com.qq.connect -DartifactId=qq-connect -Dversion=%INSTALL_VERSION% -Dpackaging=jar 8 | pause 9 | exit 10 | 11 | :file_not_found_func 12 | echo file %~1 not found !!! 13 | pause 14 | exit 15 | goto:eof -------------------------------------------------------------------------------- /src/main/webapp/weblib/bootstrap/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /src/main/java/com/ning/exception/file/FileException.java: -------------------------------------------------------------------------------- 1 | package com.ning.exception.file; 2 | 3 | /** 4 | * 文件相关异常 5 | * 6 | * @author wangn 7 | * @date 2017/5/20 8 | */ 9 | public class FileException extends Exception { 10 | private String errorMessage; 11 | 12 | public FileException(String message) { 13 | super(message); 14 | this.errorMessage = message; 15 | } 16 | 17 | public String getErrorMessage() { 18 | return errorMessage; 19 | } 20 | 21 | public void setErrorMessage(String errorMessage) { 22 | this.errorMessage = errorMessage; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/ning/exception/login/LoginException.java: -------------------------------------------------------------------------------- 1 | package com.ning.exception.login; 2 | 3 | /** 4 | * 登陆相关异常 5 | * 6 | * @author wangn 7 | * @date 2017/5/19 8 | */ 9 | public class LoginException extends Exception { 10 | private String errorMessage; 11 | 12 | public LoginException(String message) { 13 | super(message); 14 | this.errorMessage = message; 15 | } 16 | 17 | public String getErrorMessage() { 18 | return errorMessage; 19 | } 20 | 21 | public void setErrorMessage(String errorMessage) { 22 | this.errorMessage = errorMessage; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/ning/exception/defaults/DefaultException.java: -------------------------------------------------------------------------------- 1 | package com.ning.exception.defaults; 2 | 3 | /** 4 | * 默认异常 5 | * 6 | * @author wangn 7 | * @date 2017/5/19 8 | */ 9 | public class DefaultException extends Exception { 10 | private String errorMessage; 11 | 12 | public DefaultException(String message) { 13 | super(message); 14 | this.errorMessage = message; 15 | } 16 | 17 | public String getErrorMessage() { 18 | return errorMessage; 19 | } 20 | 21 | public void setErrorMessage(String errorMessage) { 22 | this.errorMessage = errorMessage; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/top/itning/ta/LogTest.java: -------------------------------------------------------------------------------- 1 | package top.itning.ta; 2 | 3 | import ch.qos.logback.classic.LoggerContext; 4 | import ch.qos.logback.core.util.StatusPrinter; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class LogTest { 10 | private static final Logger logger = LoggerFactory.getLogger(LogTest.class); 11 | 12 | @Test 13 | public void logTest() { 14 | // LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 15 | // StatusPrinter.print(lc); 16 | logger.debug("debug"); 17 | logger.info("info"); 18 | logger.error("error"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/mybatis.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /src/main/webapp/js/base.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by wangn on 2017/5/23. 3 | */ 4 | $(function () { 5 | function getProPath() { 6 | //获取当前网址,如: http://localhost:8083/proj/meun.jsp 7 | var curWwwPath = window.document.location.href; 8 | //获取主机地址之后的目录,如: proj/meun.jsp 9 | var pathName = window.document.location.pathname; 10 | var pos = curWwwPath.indexOf(pathName); 11 | //获取主机地址,如: http://localhost:8083 12 | var localhostPath = curWwwPath.substring(0, pos); 13 | //获取带"/"的项目名,如:/proj 14 | var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1); 15 | return localhostPath + projectName; 16 | } 17 | 18 | var width = $(window).width(); 19 | if (width > 992) { 20 | $("body").append(""); 21 | } 22 | }); -------------------------------------------------------------------------------- /src/main/webapp/jsp/footer.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: tom 4 | Date: 2019/8/24 5 | Time: 下午11:56 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 21 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/error.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 您访问的页面不存在-404 13 | 14 | 15 | 16 | 17 | <%-- 18 | http://www.qq.com/404/ 19 | --%> 20 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/js/plugins/canvas-to-blob.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;h 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 9 | utf8 10 | 11 | 12 | 13 | 14 | ${LOG_HOME} 15 | 16 | logback.%d{yyyy-MM-dd}.log 17 | 18 | 30 19 | 20 | 1GB 21 | 22 | 23 | %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n 24 | 25 | 26 |     27 |       28 |   29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/fa/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Font Awesome icon theme configuration for bootstrap-fileinput. Requires font awesome assets to be loaded. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(a){"use strict";a.fn.fileinputThemes.fa={fileActionSettings:{removeIcon:'',uploadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:''},layoutTemplates:{fileIcon:' '},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:'',removeIcon:'',cancelIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}(window.jQuery); -------------------------------------------------------------------------------- /src/main/resources/qqconnectconfig.properties: -------------------------------------------------------------------------------- 1 | app_ID=101405996 2 | app_KEY=8ea3c205618d20d34d3aaf2fa4c31ced 3 | redirect_URI=http://shw.itning.top/qqLoginAfter 4 | scope=get_user_info,add_topic,add_one_blog,add_album,upload_pic,list_album,add_share,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idollist,add_idol,del_ido,get_tenpay_addr 5 | baseURL=https://graph.qq.com/ 6 | getUserInfoURL=https://graph.qq.com/user/get_user_info 7 | accessTokenURL=https://graph.qq.com/oauth2.0/token 8 | authorizeURL=https://graph.qq.com/oauth2.0/authorize 9 | getOpenIDURL=https://graph.qq.com/oauth2.0/me 10 | addTopicURL=https://graph.qq.com/shuoshuo/add_topic 11 | addBlogURL=https://graph.qq.com/blog/add_one_blog 12 | addAlbumURL=https://graph.qq.com/photo/add_album 13 | uploadPicURL=https://graph.qq.com/photo/upload_pic 14 | listAlbumURL=https://graph.qq.com/photo/list_album 15 | addShareURL=https://graph.qq.com/share/add_share 16 | checkPageFansURL=https://graph.qq.com/user/check_page_fans 17 | addTURL=https://graph.qq.com/t/add_t 18 | addPicTURL=https://graph.qq.com/t/add_pic_t 19 | delTURL=https://graph.qq.com/t/del_t 20 | getWeiboUserInfoURL=https://graph.qq.com/user/get_info 21 | getWeiboOtherUserInfoURL=https://graph.qq.com/user/get_other_info 22 | getFansListURL=https://graph.qq.com/relation/get_fanslist 23 | getIdolsListURL=https://graph.qq.com/relation/get_idollist 24 | addIdolURL=https://graph.qq.com/relation/add_idol 25 | delIdolURL=https://graph.qq.com/relation/del_idol 26 | getTenpayAddrURL=https://graph.qq.com/cft_info/get_tenpay_addr 27 | getRepostListURL=https://graph.qq.com/t/get_repost_list 28 | version=2.0.0.0 -------------------------------------------------------------------------------- /src/main/java/com/ning/file/dao/OrderInfoDao.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.dao; 2 | 3 | import com.ning.file.entity.OrderInfo; 4 | 5 | import java.util.Date; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * 作业名称DAO 11 | * 12 | * @author wangn 13 | * @date 2017/5/21 14 | */ 15 | public interface OrderInfoDao { 16 | /** 17 | * 根据作业名查找已经开启的所有作业 18 | * 19 | * @param oName 作业名 20 | * @return 已经开启的所有作业的集合 21 | */ 22 | List getONameBySubject(String oName); 23 | 24 | /** 25 | * 根据作业名查找所有作业 26 | * 27 | * @param oName 作业名 28 | * @return 所有作业的集合 29 | */ 30 | List getONameBySubjectOfAll(String oName); 31 | 32 | /** 33 | * 查找所有作业信息 34 | * 35 | * @return 所有作业信息集合 36 | */ 37 | List getOrderInfoEntity(); 38 | 39 | /** 40 | * 根据作业ID查找作业 41 | * 42 | * @param oid 作业名称ID 43 | * @return 作业名称信息 44 | */ 45 | OrderInfo getOrderInfoEntityByOID(Integer oid); 46 | 47 | 48 | void updateDeadlineByOID(Map map); 49 | 50 | void updateOrderByOID(Map map); 51 | 52 | /** 53 | * 更新作业名称信息 54 | * Map中的KEY可有的值 55 | * oname 56 | * osubject 57 | * ostate 58 | * 59 | * @param map 根据键更新值 60 | */ 61 | void changeKeyByOID(Map map); 62 | 63 | /** 64 | * 新增作业名称 65 | * 66 | * @param orderInfo {@link OrderInfo} 67 | */ 68 | void addOrderInfo(OrderInfo orderInfo); 69 | 70 | /** 71 | * 根据作业名称ID删除作业名称 72 | * 73 | * @param oid 作业名称ID 74 | */ 75 | void delOrderinfoByOID(Integer oid); 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/ning/admin/service/AdminService.java: -------------------------------------------------------------------------------- 1 | package com.ning.admin.service; 2 | 3 | import com.ning.file.entity.History; 4 | import com.ning.file.entity.OrderInfo; 5 | 6 | import java.util.Date; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * 管理员服务接口 12 | * 13 | * @author wangn 14 | * @date 2017/5/24 15 | */ 16 | public interface AdminService { 17 | /** 18 | * 获取所有的已上传文件实体集合 19 | * 20 | * @param hoid {@link History }实体的ID 21 | * @return 上传历史集合 22 | * @see History 23 | */ 24 | List findFileListByHoid(Integer hoid); 25 | 26 | /** 27 | * 获取所有课程名称信息 28 | * 29 | * @return 所有课程名称信息集合 30 | */ 31 | List getOrderInfoEntity(); 32 | 33 | 34 | 35 | void updateDeadlineByOID(Map map); 36 | 37 | /** 38 | * 更新状态 39 | * 40 | * @param map map 41 | */ 42 | void changeKeyByOID(Map map); 43 | 44 | void updateOrderByOID(Map map); 45 | 46 | /** 47 | * 添加课程名称 48 | * 49 | * @param orderInfo 课程名称实体 50 | */ 51 | void addOrderInfo(OrderInfo orderInfo); 52 | 53 | /** 54 | * 删除课程名称 55 | * 56 | * @param oid 课程名称ID 57 | */ 58 | void delOrderinfoByOID(Integer oid); 59 | 60 | /** 61 | * 根据作业ID查找所有的已上传文件实体集合 62 | * 63 | * @param hoid 作业ID 64 | * @return 上传历史集合 65 | */ 66 | List getAllUploadedByHoid(int hoid); 67 | 68 | /** 69 | * 根据名称ID删除名称 70 | * 71 | * @param oid 名称ID 72 | * @throws Exception Exception 73 | */ 74 | void delOrderInfosAndFilesByOID(int oid) throws Exception; 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/ning/file/dao/HistoryDao.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.dao; 2 | 3 | import com.ning.file.entity.History; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 课程名称DAO 10 | * 11 | * @author wangn 12 | * @date 2017/5/22 13 | */ 14 | public interface HistoryDao { 15 | /** 16 | * 新增课程名称 17 | * 18 | * @param history {@link History} 19 | */ 20 | void insertDataByEntity(History history); 21 | 22 | /** 23 | * 根据用户ID获取用户上传的文件历史 24 | * 25 | * @param huid 用户ID 26 | * @return 文件历史集合 27 | */ 28 | List getUpListByUID(String huid); 29 | 30 | /** 31 | * 根据ID删除上传历史 32 | * 33 | * @param delHid 历史ID 34 | */ 35 | void delEntityByHID(String delHid); 36 | 37 | /** 38 | * 根据ID获取上传历史 39 | * 40 | * @param hid 历史ID 41 | * @return 上传历史记录 42 | */ 43 | History getEntityByHID(String hid); 44 | 45 | /** 46 | * 根据作业ID和用户ID查找上传历史
47 | * map.put("hoid", user.getUserSelectOid());
48 | * map.put("huid", user.getUid()); 49 | * 50 | * @param hoidhuid 作业ID和用户ID 51 | * @return 上传历史记录,可能为null 52 | */ 53 | History findHuidExists(Map hoidhuid); 54 | 55 | /** 56 | * 更新上传历史 57 | * 58 | * @param history {@link History} 59 | */ 60 | void upHistoryData(History history); 61 | 62 | /** 63 | * 根据作业名称ID获取上传文件历史 64 | * 65 | * @param hoid ID 66 | * @return 上传历史集合 67 | */ 68 | List findFileListByHoid(Integer hoid); 69 | 70 | /** 71 | * 根据作业名称ID删除上传历史 72 | * 73 | * @param hoid 作业名称ID 74 | */ 75 | void delEntityByHoId(Integer hoid); 76 | } 77 | -------------------------------------------------------------------------------- /src/main/webapp/js/canvas-nest.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: v1.0.1 5 | * GitHub: https://github.com/hustcc/canvas-nest.js 6 | **/ 7 | !function(){function n(n,e,t){return n.getAttribute(e)||t}function e(n){return document.getElementsByTagName(n)}function t(){var t=e("script"),o=t.length,i=t[o-1];return{l:o,z:n(i,"zIndex",-1),o:n(i,"opacity",.5),c:n(i,"color","0,0,0"),n:n(i,"count",99)}}function o(){a=m.width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,c=m.height=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}function i(){r.clearRect(0,0,a,c);var n,e,t,o,m,l;s.forEach(function(i,x){for(i.x+=i.xa,i.y+=i.ya,i.xa*=i.x>a||i.x<0?-1:1,i.ya*=i.y>c||i.y<0?-1:1,r.fillRect(i.x-.5,i.y-.5,1,1),e=x+1;e=n.max/2&&(i.x-=.03*o,i.y-=.03*m),t=(n.max-l)/n.max,r.beginPath(),r.lineWidth=t/2,r.strokeStyle="rgba("+d.c+","+(t+.2)+")",r.moveTo(i.x,i.y),r.lineTo(n.x,n.y),r.stroke()))}),x(i)}var a,c,u,m=document.createElement("canvas"),d=t(),l="c_n"+d.l,r=m.getContext("2d"),x=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(n){window.setTimeout(n,1e3/45)},w=Math.random,y={x:null,y:null,max:2e4};m.id=l,m.style.cssText="position:fixed;top:0;left:0;z-index:"+d.z+";opacity:"+d.o,e("body")[0].appendChild(m),o(),window.onresize=o,window.onmousemove=function(n){n=n||window.event,y.x=n.clientX,y.y=n.clientY},window.onmouseout=function(){y.x=null,y.y=null};for(var s=[],f=0;d.n>f;f++){var h=w()*a,g=w()*c,v=2*w()-1,p=2*w()-1;s.push({x:h,y:g,xa:v,ya:p,max:6e3})}u=s.concat([y]),setTimeout(function(){i()},100)}(); -------------------------------------------------------------------------------- /src/main/java/com/ning/exception/defaults/ExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package com.ning.exception.defaults; 2 | 3 | import com.ning.exception.file.FileException; 4 | import com.ning.exception.login.LoginException; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.web.servlet.HandlerExceptionResolver; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | import javax.servlet.ServletException; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | 15 | /** 16 | * 异常解析 17 | * 18 | * @author wangn 19 | * @date 2017/5/19 20 | */ 21 | public class ExceptionResolver implements HandlerExceptionResolver { 22 | private static final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class); 23 | 24 | @Override 25 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { 26 | logger.error(e.getMessage(), e); 27 | String errorMessage; 28 | if (e instanceof LoginException) { 29 | errorMessage = ((LoginException) e).getErrorMessage(); 30 | } else if (e instanceof FileException) { 31 | errorMessage = ((FileException) e).getErrorMessage(); 32 | } else { 33 | errorMessage = new DefaultException(e.getMessage()).getErrorMessage(); 34 | } 35 | request.setAttribute("errorMessage", errorMessage); 36 | try { 37 | //转发到错误页面 38 | request.getRequestDispatcher("/jsp/error_500.jsp").forward(request, response); 39 | } catch (ServletException | IOException e1) { 40 | e1.printStackTrace(); 41 | } 42 | return new ModelAndView(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/gly/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Glyphicon (default) theme configuration for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(i){"use strict";i.fn.fileinputThemes.gly={fileActionSettings:{removeIcon:'',uploadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:''},layoutTemplates:{fileIcon:''},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:' ',removeIcon:'',cancelIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}(window.jQuery); -------------------------------------------------------------------------------- /src/main/java/com/ning/login/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.ning.login.dao; 2 | 3 | import com.ning.login.entity.User; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 用户DAO 10 | * 11 | * @author wangn 12 | * @date 2017/5/19 13 | */ 14 | public interface UserDao { 15 | /** 16 | * 根据用户名获取密码 17 | * 18 | * @param username 用户名 19 | * @return 密码 20 | */ 21 | String getPasswd(String username); 22 | 23 | /** 24 | * 根据ID获取密码 25 | * 26 | * @param uid 用户ID 27 | * @return 密码 28 | */ 29 | String getPasswdById(String uid); 30 | 31 | /** 32 | * 获取是否为第一次登陆 33 | * 34 | * @param uid 用户ID 35 | * @return 第一次登陆返回true,否则返回false 36 | */ 37 | boolean isFirstLogin(String uid); 38 | 39 | /** 40 | * 根据用户名获取用户信息 41 | * 42 | * @param username 用户名 43 | * @return 用户信息 44 | */ 45 | User getUserEntity(String username); 46 | 47 | /** 48 | * 根据用户ID修改密码 49 | * 50 | * @param map 用户ID,新密码 51 | */ 52 | void setUserPasswd(Map map); 53 | 54 | /** 55 | * 根据用户ID设置登陆标记 56 | * 57 | * @param firstLogin 是第一次登陆 58 | */ 59 | void setFirstLogin(Map firstLogin); 60 | 61 | /** 62 | * 根据用户ID返回用户信息 63 | * 64 | * @param uid 用户ID 65 | * @return 用户信息 66 | */ 67 | User getUserEntityByID(String uid); 68 | 69 | /** 70 | * 获取所有用户 71 | * 72 | * @return 用户集合 73 | */ 74 | List getUserList(); 75 | 76 | /** 77 | * 根据OPEN ID获取用户 78 | * 79 | * @param userOpenID OPEN ID 80 | * @return 用户信息 81 | */ 82 | User getUserEntityByOpenID(String userOpenID); 83 | 84 | /** 85 | * 根据用户ID插入用户OPEN ID 86 | * 87 | * @param user {@link User} 88 | */ 89 | void insertQQIDByUID(User user); 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/ning/login/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.ning.login.service; 2 | 3 | import com.ning.login.entity.User; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 用户服务 10 | * 11 | * @author wangn 12 | * @date 2017/5/19 13 | */ 14 | public interface UserService { 15 | /** 16 | * 根据用户名获取密码 17 | * 18 | * @param username 用户名 19 | * @return 密码 20 | */ 21 | String getPasswd(String username); 22 | 23 | /** 24 | * 根据ID获取密码 25 | * 26 | * @param uid 用户ID 27 | * @return 密码 28 | */ 29 | String getPasswdById(String uid); 30 | 31 | /** 32 | * 获取是否为第一次登陆 33 | * 34 | * @param uid 用户ID 35 | * @return 第一次登陆返回true,否则返回false 36 | */ 37 | boolean isFirstLogin(String uid); 38 | 39 | /** 40 | * 根据用户名获取用户信息 41 | * 42 | * @param username 用户名 43 | * @return 用户信息 44 | */ 45 | User getUserEntity(String username); 46 | 47 | /** 48 | * 根据用户ID修改密码 49 | * 50 | * @param map 用户ID,新密码 51 | */ 52 | void setUserPasswd(Map map); 53 | 54 | /** 55 | * 根据用户ID设置登陆标记 56 | * 57 | * @param firstLogin 是第一次登陆 58 | */ 59 | void setFirstLogin(Map firstLogin); 60 | 61 | /** 62 | * 根据用户ID返回用户信息 63 | * 64 | * @param uid 用户ID 65 | * @return 用户信息 66 | */ 67 | User getUserEntityByID(String uid); 68 | 69 | /** 70 | * 获取所有用户 71 | * 72 | * @return 用户集合 73 | */ 74 | List getUserList(); 75 | 76 | /** 77 | * 根据OPEN ID获取用户 78 | * 79 | * @param userOpenID OPEN ID 80 | * @return 用户信息 81 | */ 82 | User getUserEntityByOpenID(String userOpenID); 83 | 84 | /** 85 | * 根据用户ID插入用户OPEN ID 86 | * 87 | * @param user {@link User} 88 | */ 89 | void insertQQIDByUID(User user); 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/ning/login/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ning.login.service.impl; 2 | 3 | import com.ning.login.dao.UserDao; 4 | import com.ning.login.entity.User; 5 | import com.ning.login.service.UserService; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * 用户服务实现类 14 | * 15 | * @author wangn 16 | * @date 2017/5/19 17 | */ 18 | @Service 19 | public class UserServiceImpl implements UserService { 20 | @Resource 21 | private UserDao userDao; 22 | 23 | @Override 24 | public String getPasswd(String username) { 25 | return userDao.getPasswd(username); 26 | } 27 | 28 | @Override 29 | public String getPasswdById(String uid) { 30 | return userDao.getPasswdById(uid); 31 | } 32 | 33 | @Override 34 | public boolean isFirstLogin(String uid) { 35 | return userDao.isFirstLogin(uid); 36 | } 37 | 38 | @Override 39 | public User getUserEntity(String username) { 40 | return userDao.getUserEntity(username); 41 | } 42 | 43 | @Override 44 | public void setUserPasswd(Map map) { 45 | userDao.setUserPasswd(map); 46 | } 47 | 48 | @Override 49 | public void setFirstLogin(Map firstLogin) { 50 | userDao.setFirstLogin(firstLogin); 51 | } 52 | 53 | @Override 54 | public User getUserEntityByID(String uid) { 55 | return userDao.getUserEntityByID(uid); 56 | } 57 | 58 | @Override 59 | public List getUserList() { 60 | return userDao.getUserList(); 61 | } 62 | 63 | @Override 64 | public User getUserEntityByOpenID(String userOpenID) { 65 | return userDao.getUserEntityByOpenID(userOpenID); 66 | } 67 | 68 | @Override 69 | public void insertQQIDByUID(User user) { 70 | userDao.insertQQIDByUID(user); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/ning/login/service/CustomRealm.java: -------------------------------------------------------------------------------- 1 | package com.ning.login.service; 2 | 3 | import com.ning.login.entity.User; 4 | import org.apache.shiro.authc.AuthenticationException; 5 | import org.apache.shiro.authc.AuthenticationInfo; 6 | import org.apache.shiro.authc.AuthenticationToken; 7 | import org.apache.shiro.authc.SimpleAuthenticationInfo; 8 | import org.apache.shiro.authz.AuthorizationInfo; 9 | import org.apache.shiro.authz.SimpleAuthorizationInfo; 10 | import org.apache.shiro.realm.AuthorizingRealm; 11 | import org.apache.shiro.subject.PrincipalCollection; 12 | 13 | import javax.annotation.Resource; 14 | 15 | /** 16 | * @author wangn 17 | * @date 2017/5/19 18 | */ 19 | public class CustomRealm extends AuthorizingRealm { 20 | @Resource 21 | private UserService userService; 22 | 23 | /** 24 | * 授权 25 | * 26 | * @param principals {@link PrincipalCollection} 27 | * @return {@link AuthorizationInfo} 28 | */ 29 | @Override 30 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 31 | User user = (User) principals.getPrimaryPrincipal(); 32 | SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); 33 | simpleAuthorizationInfo.addStringPermission(user.getPercode()); 34 | return simpleAuthorizationInfo; 35 | } 36 | 37 | /** 38 | * 认证 39 | * 40 | * @param token {@link AuthenticationToken} 41 | * @return {@link AuthenticationInfo} 42 | * @throws AuthenticationException AuthenticationException 43 | */ 44 | @Override 45 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 46 | String username = (String) token.getPrincipal(); 47 | String password = userService.getPasswd(username); 48 | User user = userService.getUserEntity(username); 49 | return new SimpleAuthenticationInfo(user, password, "customrealm"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/explorer/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme configuration for bootstrap-fileinput. Load this theme file after loading `fileinput.js`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(e){"use strict";var t='\n {close}
\n \n
\n
\n
\n
\n',footer:'
{caption}
{size}{progress}{indicator} {actions}',actions:'{drag}\n
\n \n
',zoomCache:'{zoomContent}
'},previewMarkupTags:{tagBefore1:t+">"+i,tagBefore2:t+' title="{caption}">'+i,tagAfter:"\n{footer}\n"},previewSettings:{image:{height:"60px"},html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame"}}(window.jQuery); -------------------------------------------------------------------------------- /src/main/webapp/jsp/error_500.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 服务器提出了个问题-500 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 33 | 34 | 35 |
36 |
37 |

服务器提出了个问题-500 :

38 |

${errorMessage }

39 |
40 |
41 | 42 | 43 | <%@include file="footer.jsp" %> 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/fa/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Font Awesome icon theme configuration for bootstrap-fileinput. Requires font awesome assets to be loaded. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function ($) { 14 | "use strict"; 15 | 16 | $.fn.fileinputThemes.fa = { 17 | fileActionSettings: { 18 | removeIcon: '', 19 | uploadIcon: '', 20 | zoomIcon: '', 21 | dragIcon: '', 22 | indicatorNew: '', 23 | indicatorSuccess: '', 24 | indicatorError: '', 25 | indicatorLoading: '' 26 | }, 27 | layoutTemplates: { 28 | fileIcon: ' ' 29 | }, 30 | previewZoomButtonIcons: { 31 | prev: '', 32 | next: '', 33 | toggleheader: '', 34 | fullscreen: '', 35 | borderless: '', 36 | close: '' 37 | }, 38 | previewFileIcon: '', 39 | browseIcon: '', 40 | removeIcon: '', 41 | cancelIcon: '', 42 | uploadIcon: '', 43 | msgValidationErrorIcon: ' ' 44 | }; 45 | })(window.jQuery); 46 | -------------------------------------------------------------------------------- /src/main/java/com/ning/util/properties/PropertiesUtil.java: -------------------------------------------------------------------------------- 1 | package com.ning.util.properties; 2 | 3 | import com.ning.exception.file.FileException; 4 | import org.springframework.web.context.request.RequestContextHolder; 5 | import org.springframework.web.context.request.ServletRequestAttributes; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.util.Properties; 12 | 13 | /** 14 | * 属性工具类 15 | * 16 | * @author wangn 17 | * @date 2017/5/25 18 | */ 19 | public class PropertiesUtil { 20 | public static String getUpLoadFilePath() throws Exception { 21 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 22 | Properties properties = new Properties(); 23 | try { 24 | properties.load(new FileInputStream(new File(request.getSession().getServletContext().getRealPath("/WEB-INF/classes/context.properties")))); 25 | } catch (IOException e) { 26 | throw new FileException("获取文件路径失败!" + e.getMessage()); 27 | } 28 | String filepath = properties.getProperty("upLoadFilePath"); 29 | if (filepath == null || "".equals(filepath)) { 30 | throw new FileException("文件路径不正确:upLoadFilePath=" + filepath); 31 | } 32 | return filepath; 33 | } 34 | 35 | public static String filterOutUrl(String teststr) throws Exception{ 36 | if (teststr.charAt(0) == '[' && teststr.charAt(teststr.length() - 1) == ')'){ 37 | int count = 0; 38 | count += teststr.chars().filter(ch -> ch == '[').count(); 39 | count += teststr.chars().filter(ch -> ch == ']').count(); 40 | count += teststr.chars().filter(ch -> ch == '(').count(); 41 | count += teststr.chars().filter(ch -> ch == ')').count(); 42 | 43 | if (count == 4) { 44 | String ptext = teststr.substring(teststr.lastIndexOf('[') + 1, teststr.lastIndexOf(']')); 45 | return ptext; 46 | } 47 | } 48 | 49 | return teststr; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/gly/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Glyphicon (default) theme configuration for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function ($) { 14 | "use strict"; 15 | 16 | $.fn.fileinputThemes.gly = { 17 | fileActionSettings: { 18 | removeIcon: '', 19 | uploadIcon: '', 20 | zoomIcon: '', 21 | dragIcon: '', 22 | indicatorNew: '', 23 | indicatorSuccess: '', 24 | indicatorError: '', 25 | indicatorLoading: '' 26 | }, 27 | layoutTemplates: { 28 | fileIcon: '' 29 | }, 30 | previewZoomButtonIcons: { 31 | prev: '', 32 | next: '', 33 | toggleheader: '', 34 | fullscreen: '', 35 | borderless: '', 36 | close: '' 37 | }, 38 | previewFileIcon: '', 39 | browseIcon: ' ', 40 | removeIcon: '', 41 | cancelIcon: '', 42 | uploadIcon: '', 43 | msgValidationErrorIcon: ' ' 44 | }; 45 | })(window.jQuery); 46 | -------------------------------------------------------------------------------- /src/main/java/com/ning/file/entity/OrderInfo.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.entity; 2 | 3 | import java.io.Serializable; 4 | import java.text.DateFormat; 5 | import java.text.ParseException; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Date; 8 | 9 | /** 10 | * 作业名称实体 11 | * 12 | * @author wangn 13 | * @date 2017/5/20 14 | */ 15 | public class OrderInfo implements Serializable { 16 | /** 17 | * 作业名称ID 18 | */ 19 | private int oid; 20 | /** 21 | * 课程名 22 | */ 23 | private String oname; 24 | /** 25 | * 作业名 26 | */ 27 | private String osubject; 28 | /** 29 | * 是否允许上传 30 | */ 31 | private Boolean ostate; 32 | /** 33 | * 修改时间 34 | */ 35 | private Date otime; 36 | 37 | private Date odeadline; 38 | private String odeadlinestr; 39 | 40 | public Boolean getOstate() { 41 | return ostate; 42 | } 43 | 44 | public void setOstate(Boolean ostate) { 45 | this.ostate = ostate; 46 | } 47 | 48 | public Date getOtime() { 49 | return otime; 50 | } 51 | 52 | // 截止时间 53 | public Date getOdeadline() {return odeadline;} 54 | public void setOdeadline(Date odeadline) {this.odeadline = odeadline;} 55 | public String getOdeadlinestr() {return odeadlinestr;} 56 | public void setOdeadlinestr(String odeadlinestr) {this.odeadlinestr = odeadlinestr;} 57 | 58 | // convert string to java date 59 | //https://stackoverflow.com/questions/2318719/how-to-convert-timestamp-string-to-java-util-date 60 | public void setOdeadlineFromStr(String odeadlinestr) throws ParseException { 61 | // unix timestamp counts seconds, need to multiply 1000 62 | Date deadlineDate = new Date(Long.parseLong(odeadlinestr) * 1000); 63 | this.odeadline = deadlineDate; 64 | } 65 | 66 | 67 | public void setOtime(Date otime) { 68 | this.otime = otime; 69 | } 70 | 71 | public int getOid() { 72 | return oid; 73 | } 74 | 75 | public void setOid(int oid) { 76 | this.oid = oid; 77 | } 78 | 79 | public String getOname() { 80 | return oname; 81 | } 82 | 83 | public void setOname(String oname) { 84 | this.oname = oname; 85 | } 86 | 87 | public String getOsubject() { 88 | return osubject; 89 | } 90 | 91 | public void setOsubject(String osubject) { 92 | this.osubject = osubject; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/webapp/js/filterurl.js: -------------------------------------------------------------------------------- 1 | function isValidURL(string) { 2 | var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g); 3 | return (res !== null) 4 | }; 5 | 6 | function checkSetURL(classstr){ 7 | var teststr = $(classstr).html(); 8 | 9 | if (teststr[0] !== '[' || teststr[teststr.length-1] !== ')'){ 10 | // not a link 11 | } else { 12 | // check if there's many [] () s 13 | var count = 0; 14 | count += (teststr.match(/\[/g) || []).length; 15 | count += (teststr.match(/\]/g) || []).length; 16 | count += (teststr.match(/\(/g) || []).length; 17 | count += (teststr.match(/\)/g) || []).length; 18 | 19 | if (count === 4){ 20 | // possiblely a markdown url link 21 | 22 | // get substring between 23 | var purl = teststr.substring( 24 | teststr.lastIndexOf('(') + 1, 25 | teststr.lastIndexOf(')') 26 | ); 27 | 28 | var ptext = teststr.substring( 29 | teststr.lastIndexOf('[') + 1, 30 | teststr.lastIndexOf(']') 31 | ); 32 | 33 | if (isValidURL(purl)){ 34 | $(classstr).html("" + ptext + ""); 35 | } 36 | } 37 | } 38 | } 39 | 40 | function checkSetURLGivenStr(teststr){ 41 | if (teststr[0] !== '[' || teststr[teststr.length-1] !== ')'){ 42 | // not a link 43 | } else { 44 | // check if there's many [] () s 45 | var count = 0; 46 | count += (teststr.match(/\[/g) || []).length; 47 | count += (teststr.match(/\]/g) || []).length; 48 | count += (teststr.match(/\(/g) || []).length; 49 | count += (teststr.match(/\)/g) || []).length; 50 | 51 | if (count === 4){ 52 | // possiblely a markdown url link 53 | 54 | // get substring between 55 | var purl = teststr.substring( 56 | teststr.lastIndexOf('(') + 1, 57 | teststr.lastIndexOf(')') 58 | ); 59 | 60 | var ptext = teststr.substring( 61 | teststr.lastIndexOf('[') + 1, 62 | teststr.lastIndexOf(']') 63 | ); 64 | 65 | if (isValidURL(purl)){ 66 | return "" + ptext + ""; 67 | } 68 | } 69 | } 70 | 71 | return null; 72 | } -------------------------------------------------------------------------------- /src/main/resources/HistoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | INSERT INTO history(hid, huid, hoid, type, filepath, uptime, filesize) 17 | VALUES (#{hid}, #{huid}, #{hoid}, #{type}, #{filepath}, #{uptime}, #{filesize}) 18 | 19 | 20 | 25 | 26 | 27 | DELETE 28 | FROM history 29 | WHERE hid = #{delHid} 30 | 31 | 32 | DELETE 33 | FROM history 34 | WHERE hoid = #{hoid} 35 | 36 | 41 | 42 | 48 | 49 | 50 | UPDATE history 51 | SET type = #{type}, 52 | filepath = #{filepath}, 53 | uptime = #{uptime}, 54 | filesize = #{filesize} 55 | WHERE hid = 56 | #{hid} 57 | 58 | 59 | 64 | -------------------------------------------------------------------------------- /src/main/java/com/ning/login/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.ning.login.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 用户实体类 7 | * 8 | * @author wangn 9 | * @date 2017/5/19 10 | */ 11 | public class User implements Serializable { 12 | /** 13 | * 用户唯一ID 14 | */ 15 | private String uid; 16 | /** 17 | * 用户名 18 | */ 19 | private String username; 20 | /** 21 | * 密码 22 | */ 23 | private String password; 24 | /** 25 | * 头像(目前没用) 26 | */ 27 | private String headimg; 28 | /** 29 | * 是否是第一次登陆 30 | */ 31 | private Boolean firstlogin; 32 | /** 33 | * 姓名 34 | */ 35 | private String name; 36 | /** 37 | * 38 | */ 39 | private Integer userSelectOid; 40 | /** 41 | * 角色 42 | */ 43 | private String percode; 44 | /** 45 | * QQ登陆用的OPEN ID 用于识别用户 46 | */ 47 | private String userOpenID; 48 | 49 | public String getUserOpenID() { 50 | return userOpenID; 51 | } 52 | 53 | public void setUserOpenID(String userOpenID) { 54 | this.userOpenID = userOpenID; 55 | } 56 | 57 | public String getPercode() { 58 | return percode; 59 | } 60 | 61 | public void setPercode(String percode) { 62 | this.percode = percode; 63 | } 64 | 65 | public Integer getUserSelectOid() { 66 | return userSelectOid; 67 | } 68 | 69 | public void setUserSelectOid(Integer userSelectOid) { 70 | this.userSelectOid = userSelectOid; 71 | } 72 | 73 | public String getName() { 74 | return name; 75 | } 76 | 77 | public void setName(String name) { 78 | this.name = name; 79 | } 80 | 81 | public String getUid() { 82 | return uid; 83 | } 84 | 85 | public void setUid(String uid) { 86 | this.uid = uid; 87 | } 88 | 89 | public String getUsername() { 90 | return username; 91 | } 92 | 93 | public void setUsername(String username) { 94 | this.username = username; 95 | } 96 | 97 | public String getPassword() { 98 | return password; 99 | } 100 | 101 | public void setPassword(String password) { 102 | this.password = password; 103 | } 104 | 105 | public String getHeadimg() { 106 | return headimg; 107 | } 108 | 109 | public void setHeadimg(String headimg) { 110 | this.headimg = headimg; 111 | } 112 | 113 | public Boolean getFirstlogin() { 114 | return firstlogin; 115 | } 116 | 117 | public void setFirstlogin(Boolean firstlogin) { 118 | this.firstlogin = firstlogin; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/ning/file/entity/History.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * 上传历史记录 8 | * 9 | * @author wangn 10 | * @date 2017/5/22 11 | */ 12 | public class History implements Serializable { 13 | /** 14 | * 唯一ID 15 | */ 16 | private String hid; 17 | /** 18 | * 对应的用户ID 19 | */ 20 | private String huid; 21 | /** 22 | * 课程ID 23 | */ 24 | private Integer hoid; 25 | /** 26 | * 上传的文件MIME类型 27 | */ 28 | private String type; 29 | /** 30 | * 文件名 31 | */ 32 | private String filepath; 33 | /** 34 | * 上传时间 35 | */ 36 | private Date uptime; 37 | 38 | private Date deadline; 39 | 40 | /** 41 | * 文件大小 42 | */ 43 | private Double filesize; 44 | /** 45 | * 作业名 46 | */ 47 | private String osubject; 48 | /** 49 | * 课程名 50 | */ 51 | private String oname; 52 | 53 | public String getOsubject() { 54 | return osubject; 55 | } 56 | 57 | public void setOsubject(String osubject) { 58 | this.osubject = osubject; 59 | } 60 | 61 | public String getOname() { 62 | return oname; 63 | } 64 | 65 | public void setOname(String oname) { 66 | this.oname = oname; 67 | } 68 | 69 | public String getHid() { 70 | return hid; 71 | } 72 | 73 | public void setHid(String hid) { 74 | this.hid = hid; 75 | } 76 | 77 | public String getHuid() { 78 | return huid; 79 | } 80 | 81 | public void setHuid(String huid) { 82 | this.huid = huid; 83 | } 84 | 85 | public Integer getHoid() { 86 | return hoid; 87 | } 88 | 89 | public void setHoid(Integer hoid) { 90 | this.hoid = hoid; 91 | } 92 | 93 | public String getType() { 94 | return type; 95 | } 96 | 97 | public void setType(String type) { 98 | this.type = type; 99 | } 100 | 101 | public String getFilepath() { 102 | return filepath; 103 | } 104 | 105 | public void setFilepath(String filepath) { 106 | this.filepath = filepath; 107 | } 108 | 109 | public Date getUptime() { 110 | return uptime; 111 | } 112 | 113 | public void setUptime(Date uptime) { 114 | this.uptime = uptime; 115 | } 116 | 117 | public Date getDeadline() {return deadline;} 118 | public void setDeadline(Date deadline) {this.deadline = deadline;} 119 | 120 | 121 | public Double getFilesize() { 122 | return filesize; 123 | } 124 | 125 | public void setFilesize(Double filesize) { 126 | this.filesize = filesize; 127 | } 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/explorer/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme configuration for bootstrap-fileinput. Load this theme file after loading `fileinput.js`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function ($) { 14 | "use strict"; 15 | var teTagBef = '\n' + 20 | ' {close}' + 21 | '
\n' + 22 | ' \n' + 23 | '
\n' + 24 | '
' + 25 | '
\n' + 26 | '
\n' + 27 | '
\n' + 28 | '', 29 | footer: '
{caption}
' + 30 | '{size}{progress}{indicator} {actions}', 31 | actions: '{drag}\n' + 32 | '
\n' + 33 | ' \n' + 36 | '
', 37 | zoomCache: '' + 38 | '{zoomContent}
' 39 | }, 40 | previewMarkupTags: { 41 | tagBefore1: teTagBef + '>' + teContent, 42 | tagBefore2: teTagBef + ' title="{caption}">' + teContent, 43 | tagAfter: '\n{footer}\n' 44 | }, 45 | previewSettings: { 46 | image: {height: "60px"}, 47 | html: {width: "100px", height: "60px"}, 48 | text: {width: "100px", height: "60px"}, 49 | video: {width: "auto", height: "60px"}, 50 | audio: {width: "auto", height: "60px"}, 51 | flash: {width: "100%", height: "60px"}, 52 | object: {width: "100%", height: "60px"}, 53 | pdf: {width: "100px", height: "60px"}, 54 | other: {width: "100%", height: "60px"} 55 | }, 56 | frameClass: 'explorer-frame' 57 | }; 58 | })(window.jQuery); 59 | -------------------------------------------------------------------------------- /src/main/resources/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 28 | 29 | 30 | UPDATE user 31 | set password = #{password} 32 | WHERE uid = #{uid} 33 | 34 | 35 | 36 | UPDATE user 37 | SET firstlogin = #{isfirst} 38 | WHERE uid = #{uid} 39 | 40 | 41 | 46 | 47 | 52 | 53 | 58 | 59 | 64 | 65 | 70 | 71 | 72 | UPDATE user 73 | SET userOpenID = #{userOpenID} 74 | WHERE uid = #{uid} 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/main/resources/springmvc.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | text/html;charset=UTF-8 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/addsubjectui.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | <%@ page isELIgnored="false" %> 5 | <% String path = request.getContextPath(); 6 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 7 | application.setAttribute("basePath", basePath); 8 | %> 9 | 10 | 11 | 12 |
13 |

添加课程和类别:

14 | 20 |
21 | 22 |
23 | 24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 | 33 | 34 | 35 |
36 | 37 | 38 |
39 | 40 | 41 | 42 | 43 |
44 |
45 | 46 |
47 | 48 |
49 | 55 |
56 |
57 |
58 |
59 | 60 |
61 |
62 |
63 | -------------------------------------------------------------------------------- /src/main/resources/OrderInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 27 | 28 | 32 | 33 | 38 | 39 | 40 | INSERT INTO orderinfo(oid, oname, osubject, ostate, otime, odeadline) 41 | VALUES (#{oid}, #{oname}, #{osubject}, #{ostate}, #{otime}, #{odeadline}) 42 | 43 | 44 | UPDATE orderinfo 45 | 46 | oname = #{oname}, 47 | osubject = #{osubject}, 48 | ostate = #{ostate} 49 | 50 | WHERE oid = #{oid} 51 | 52 | 53 | UPDATE orderinfo 54 | 55 | odeadline = #{odeadline} 56 | 57 | WHERE oid = #{oid} 58 | 59 | 60 | 61 | UPDATE orderinfo 62 | 63 | osubject = #{osubject}, 64 | oname = #{oname}, 65 | ostate = #{ostate}, 66 | otime = #{otime}, 67 | odeadline = #{odeadline} 68 | 69 | WHERE oid = #{oid} 70 | 71 | 72 | 73 | DELETE 74 | FROM orderinfo 75 | WHERE oid = #{oid} 76 | 77 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/upfileui.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 文件上传UI 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 正在加载主页... 15 | 16 | 17 | 39 | 40 | 41 |

正在加载主页,请稍等...

42 | 98 | 99 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/explorer/theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme style for bootstrap-fileinput. Load this theme file after loading `fileinput.css`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */.theme-explorer .file-preview .table{margin:0}.theme-explorer .explorer-frame td{vertical-align:middle;text-align:left}.explorer-frame .file-preview-text{display:inline-block;color:#428bca;border:1px solid #ddd;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;outline:0;padding:8px;resize:none}.explorer-frame .file-preview-html{display:inline-block;border:1px solid #ddd;padding:8px;overflow:auto}.explorer-frame .file-preview-other{text-align:center}.explorer-frame .file-other-icon{font-size:4.2em}.theme-explorer .explorer-frame .kv-file-content{width:80px;height:80px;padding:5px;text-align:center}.theme-explorer .file-actions-cell{width:100px;padding:0;position:relative}.theme-explorer .file-thumb-progress .progress{display:block;margin-top:5px}.theme-explorer .file-thumb-progress .progress,.theme-explorer .file-thumb-progress .progress-bar{height:13px;font-size:11px;line-height:13px}.theme-explorer .file-drag-handle,.theme-explorer .file-upload-indicator{position:absolute;text-align:center;top:0;right:0;padding-left:5px;padding-right:2px;border-right:none;border-top:none;border-left:1px solid #8a6d3b;border-bottom:1px solid #8a6d3b;border-bottom-left-radius:11px;font-size:12px}.theme-explorer .explorer-caption{display:block;color:#777}.theme-explorer .file-actions{text-align:center}.theme-explorer .kvsortable-ghost{opacity:.6;background:#e1edf7;border:2px solid #a1abff}.theme-explorer .file-upload-indicator{font-size:13px;padding-left:6px;background-color:#fcf8e3;border-color:#faebcc}.theme-explorer .file-drag-handle{right:-2px;background-color:#d9edf7;border-color:#bce8f1}.theme-explorer .file-preview-error .file-upload-indicator{background-color:#f2dede;border-color:#ebccd1}.theme-explorer .file-preview-success .file-upload-indicator{background-color:#dff0d8;border-color:#d6e9c6}.theme-explorer .file-preview-loading .file-upload-indicator{background-color:#e5e5e5;border-color:#777}.theme-explorer .file-error-message ul{padding-left:15px}.theme-explorer .file-error-message .close{margin-top:-5px;margin-right:-5px}@media only screen and (max-width:500px){.theme-explorer .table,.theme-explorer .table tbody,.theme-explorer .table td,.theme-explorer .table tr{display:block;width:100%!important}.theme-explorer .table{border:none}.theme-explorer .table tr{margin-top:5px}.theme-explorer .table tr:first-child{margin-top:0}.theme-explorer .table td{text-align:center}.theme-explorer .table .kv-file-content{border-bottom:none;padding:4px;margin:0}.theme-explorer .table .kv-file-content .file-preview-image{max-width:100%}.theme-explorer .file-details-cell{border-top:none;border-bottom:none;padding-top:0;margin:0}.theme-explorer .file-actions-cell{border-top:none;padding-bottom:4px}.theme-explorer .explorer-frame .explorer-caption{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;left:0;right:0;margin:auto}.theme-explorer .file-drag-handle,.theme-explorer .file-upload-indicator{right:0;bottom:0;border-top-left-radius:40px;border-bottom-left-radius:0;padding:12px 3px 0 6px}.theme-explorer .file-actions-cell .btn-xs{font-size:.9em;padding:2px 7px;margin-right:3px;cursor:pointer}} -------------------------------------------------------------------------------- /src/main/java/com/ning/file/service/FileService.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.service; 2 | 3 | import com.ning.file.entity.History; 4 | import com.ning.file.entity.OrderInfo; 5 | import com.ning.login.entity.User; 6 | import org.springframework.web.multipart.MultipartFile; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | /** 13 | * 文件服务 14 | * 15 | * @author wangn 16 | * @date 2017/5/19 17 | */ 18 | public interface FileService { 19 | /** 20 | * 根据课程名称名获取可上传的课程名称集合 21 | * 22 | * @param oname 课程名称名 23 | * @return 可上传的课程名称集合 24 | */ 25 | List getONameBySubject(String oname); 26 | 27 | /** 28 | * 根据课程名称名获取所有课程名称集合 29 | * 30 | * @param oname 课程名称名 31 | * @return 课程名称集合 32 | */ 33 | List getOnameBysubjectOfAll(String oname); 34 | 35 | /** 36 | * 获取所有开启的作业的作业 37 | * 38 | * @return 作业OrderInfo List 39 | */ 40 | List getOrderInfoFullEntity(); 41 | 42 | /** 43 | * 获取所有开启的作业的作业名 44 | * 45 | * @return 作业名集合 46 | */ 47 | Set getOrderInfoEntity(); 48 | 49 | /** 50 | * 获取所有作业的作业名 51 | * 52 | * @return 作业名集合 53 | */ 54 | Set getOrderInfoEntityOfAll(); 55 | 56 | /** 57 | * 根据课程名称ID获取课程名称实体 58 | * 59 | * @param oid 课程名称ID 60 | * @return 课程名称实体 61 | */ 62 | OrderInfo getOrderInfoEntityByOID(Integer oid); 63 | 64 | /** 65 | * 新增课程名称信息 66 | * 67 | * @param history {@link History} 68 | */ 69 | void insertDataByEntity(History history); 70 | 71 | /** 72 | * 根据用户ID获取用户上传的文件历史 73 | * 74 | * @param huid 用户ID 75 | * @return 用户上传的文件历史集合 76 | */ 77 | List getUpListByUID(String huid); 78 | 79 | /** 80 | * 根据上传历史ID删除历史纪录 81 | * 82 | * @param delHid 上传历史ID 83 | */ 84 | void delEntityByHID(String delHid); 85 | 86 | /** 87 | * 根据上传历史ID获取上传信息 88 | * 89 | * @param hid 上传历史ID 90 | * @return {@link History} 91 | */ 92 | History getEntityByHID(String hid); 93 | 94 | /** 95 | * 根据作业ID和用户ID查找上传历史
96 | * map.put("hoid", user.getUserSelectOid());
97 | * map.put("huid", user.getUid()); 98 | * 99 | * @param hoidhuid 作业ID和用户ID 100 | * @return 上传历史记录,可能为null 101 | */ 102 | History findHuidExists(Map hoidhuid); 103 | 104 | /** 105 | * 更新上传历史 106 | * 107 | * @param history {@link History} 108 | */ 109 | void upHistoryData(History history); 110 | 111 | /** 112 | * 根据作业名称ID删除上传历史 113 | * 114 | * @param hoid 作业名称ID 115 | */ 116 | void delEntityByHOID(Integer hoid); 117 | 118 | /** 119 | * 根据用户ID获取用户上传历史 120 | * 121 | * @param uId 用户ID 122 | * @return 上传历史集合 123 | */ 124 | List getUserHistoryByUserId(String uId); 125 | 126 | /** 127 | * 上传文件 128 | * 129 | * @param file {@link MultipartFile} 130 | * @param user 用户 131 | * @throws Exception Exception 132 | */ 133 | void uploadFile(MultipartFile file, User user) throws Exception; 134 | 135 | /** 136 | * 删除上传的文件 137 | * 138 | * @param user 用户 139 | * @param hId 文件ID 140 | * @return 删除成功否 141 | * @throws Exception Exception 142 | */ 143 | boolean deleteFile(User user, String hId) throws Exception; 144 | } 145 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/subjectui.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | <%@ page isELIgnored="false" %> 5 | <% String path = request.getContextPath(); 6 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 7 | application.setAttribute("basePath", basePath); 8 | %> 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | class='danger' id="${allorderinfo.oid }"> 22 | 23 | 24 | <%-- check if this is a link, if so just use the right link--%> 25 | 26 | 27 | 28 | 29 | 30 | 31 | 52 | 53 | 54 |
课程名称名称名称当前状态管理教师上次操作时间截止时间操作

${allorderinfo.osubject }

${allorderinfo.oname }

${allorderinfo.ostate?"已启用":"已禁用" }

32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 48 | 49 | 51 |
55 |
56 | 57 | 77 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/downfileui.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | <%@ page isELIgnored="false" %> 5 | <% String path = request.getContextPath(); 6 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 7 | application.setAttribute("basePath", basePath); 8 | %> 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | class='danger' 26 | 27 | <%-- if there is file uploaded, make flag to be false;--%> 28 | 29 | 30 | > 31 | 32 | 33 | 34 | 35 | 42 | 50 | 51 | 52 |
学生学号学生姓名是否上传上传时间文件大小操作

${filelist.osubject }

${filelist.oname }

${filelist.uptime==null?"未上传":"已上传" }

36 |

37 | 38 | Kb 39 | 40 |

41 |
43 | 46 | 49 |
53 |
54 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/moment/zh-cn.js: -------------------------------------------------------------------------------- 1 | //! moment.js locale configuration 2 | 3 | ;(function (global, factory) { 4 | typeof exports === 'object' && typeof module !== 'undefined' 5 | && typeof require === 'function' ? factory(require('../moment')) : 6 | typeof define === 'function' && define.amd ? define(['../moment'], factory) : 7 | factory(global.moment) 8 | }(this, (function (moment) { 'use strict'; 9 | 10 | 11 | var zhCn = moment.defineLocale('zh-cn', { 12 | months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), 13 | monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), 14 | weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), 15 | weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), 16 | weekdaysMin : '日_一_二_三_四_五_六'.split('_'), 17 | longDateFormat : { 18 | LT : 'HH:mm', 19 | LTS : 'HH:mm:ss', 20 | L : 'YYYY/MM/DD', 21 | LL : 'YYYY年M月D日', 22 | LLL : 'YYYY年M月D日Ah点mm分', 23 | LLLL : 'YYYY年M月D日ddddAh点mm分', 24 | l : 'YYYY/M/D', 25 | ll : 'YYYY年M月D日', 26 | lll : 'YYYY年M月D日 HH:mm', 27 | llll : 'YYYY年M月D日dddd HH:mm' 28 | }, 29 | meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, 30 | meridiemHour: function (hour, meridiem) { 31 | if (hour === 12) { 32 | hour = 0; 33 | } 34 | if (meridiem === '凌晨' || meridiem === '早上' || 35 | meridiem === '上午') { 36 | return hour; 37 | } else if (meridiem === '下午' || meridiem === '晚上') { 38 | return hour + 12; 39 | } else { 40 | // '中午' 41 | return hour >= 11 ? hour : hour + 12; 42 | } 43 | }, 44 | meridiem : function (hour, minute, isLower) { 45 | var hm = hour * 100 + minute; 46 | if (hm < 600) { 47 | return '凌晨'; 48 | } else if (hm < 900) { 49 | return '早上'; 50 | } else if (hm < 1130) { 51 | return '上午'; 52 | } else if (hm < 1230) { 53 | return '中午'; 54 | } else if (hm < 1800) { 55 | return '下午'; 56 | } else { 57 | return '晚上'; 58 | } 59 | }, 60 | calendar : { 61 | sameDay : '[今天]LT', 62 | nextDay : '[明天]LT', 63 | nextWeek : '[下]ddddLT', 64 | lastDay : '[昨天]LT', 65 | lastWeek : '[上]ddddLT', 66 | sameElse : 'L' 67 | }, 68 | dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, 69 | ordinal : function (number, period) { 70 | switch (period) { 71 | case 'd': 72 | case 'D': 73 | case 'DDD': 74 | return number + '日'; 75 | case 'M': 76 | return number + '月'; 77 | case 'w': 78 | case 'W': 79 | return number + '周'; 80 | default: 81 | return number; 82 | } 83 | }, 84 | relativeTime : { 85 | future : '%s内', 86 | past : '%s前', 87 | s : '几秒', 88 | ss : '%d 秒', 89 | m : '1 分钟', 90 | mm : '%d 分钟', 91 | h : '1 小时', 92 | hh : '%d 小时', 93 | d : '1 天', 94 | dd : '%d 天', 95 | M : '1 个月', 96 | MM : '%d 个月', 97 | y : '1 年', 98 | yy : '%d 年' 99 | }, 100 | week : { 101 | // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 102 | dow : 1, // Monday is the first day of the week. 103 | doy : 4 // The week that contains Jan 4th is the first week of the year. 104 | } 105 | }); 106 | 107 | return zhCn; 108 | 109 | }))); -------------------------------------------------------------------------------- /src/main/java/com/ning/admin/service/impl/AdminServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ning.admin.service.impl; 2 | 3 | import com.ning.admin.service.AdminService; 4 | import com.ning.file.dao.HistoryDao; 5 | import com.ning.file.dao.OrderInfoDao; 6 | import com.ning.file.entity.History; 7 | import com.ning.file.entity.OrderInfo; 8 | import com.ning.file.service.FileService; 9 | import com.ning.login.entity.User; 10 | import com.ning.login.service.UserService; 11 | import com.ning.util.properties.PropertiesUtil; 12 | import org.springframework.stereotype.Service; 13 | 14 | import javax.annotation.Resource; 15 | import java.io.File; 16 | import java.util.ArrayList; 17 | import java.util.Date; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | /** 22 | * 管理员服务接口实现 23 | * 24 | * @author wangn 25 | * @date 2017/5/24 26 | */ 27 | @Service 28 | public class AdminServiceImpl implements AdminService { 29 | @Resource 30 | private HistoryDao historyDao; 31 | 32 | @Resource 33 | private OrderInfoDao orderInfoDao; 34 | 35 | @Resource 36 | private UserService userService; 37 | 38 | @Resource 39 | private FileService fileService; 40 | 41 | 42 | @Override 43 | public List findFileListByHoid(Integer hoid) { 44 | return historyDao.findFileListByHoid(hoid); 45 | } 46 | 47 | @Override 48 | public List getOrderInfoEntity() { 49 | return orderInfoDao.getOrderInfoEntity(); 50 | } 51 | 52 | @Override 53 | public void updateDeadlineByOID(Map map) { orderInfoDao.updateDeadlineByOID(map);} 54 | 55 | @Override 56 | public void changeKeyByOID(Map map) { 57 | orderInfoDao.changeKeyByOID(map); 58 | } 59 | 60 | @Override 61 | public void updateOrderByOID(Map map) { orderInfoDao.updateOrderByOID(map);} 62 | 63 | @Override 64 | public void addOrderInfo(OrderInfo orderInfo) { 65 | orderInfoDao.addOrderInfo(orderInfo); 66 | } 67 | 68 | @Override 69 | public void delOrderinfoByOID(Integer oid) { 70 | orderInfoDao.delOrderinfoByOID(oid); 71 | } 72 | 73 | @Override 74 | public List getAllUploadedByHoid(int hoid) { 75 | //所有的已上传文件实体集合 76 | List fileListByHoid = this.findFileListByHoid(hoid); 77 | //所有的学生实体集合 78 | List users = userService.getUserList(); 79 | //该集合用于存储所有用户上传实体信息,包括未上传文件的用户 80 | List list = new ArrayList<>(users.size()); 81 | for (User alluser : users) { 82 | //历史记录实体 83 | History history = new History(); 84 | //将学号和姓名存入 85 | history.setOname(alluser.getName()); 86 | history.setOsubject(alluser.getUsername()); 87 | for (History historys : fileListByHoid) { 88 | User user = userService.getUserEntityByID(historys.getHuid()); 89 | //如果数据库中已上传过文件的用户ID和用户列表中的ID相等 90 | if (user.getUid().equals(alluser.getUid())) { 91 | //将数据库中信息存入历史记录实体 92 | history.setFilesize(historys.getFilesize()); 93 | history.setHid(historys.getHid()); 94 | history.setUptime(historys.getUptime()); 95 | } 96 | } 97 | list.add(history); 98 | } 99 | return list; 100 | } 101 | 102 | @SuppressWarnings("ResultOfMethodCallIgnored") 103 | @Override 104 | public void delOrderInfosAndFilesByOID(int oid) throws Exception { 105 | List historyList = this.findFileListByHoid(oid); 106 | String upLoadFilePath = PropertiesUtil.getUpLoadFilePath(); 107 | for (History history : historyList) { 108 | File file = new File(upLoadFilePath + history.getFilepath()); 109 | if (file.exists()) { 110 | file.delete(); 111 | } 112 | } 113 | //删除历史记录 114 | fileService.delEntityByHOID(oid); 115 | //删除课程 116 | this.delOrderinfoByOID(oid); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/js/plugins/canvas-to-blob.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript Canvas to Blob 2.0.5 3 | * https://github.com/blueimp/JavaScript-Canvas-to-Blob 4 | * 5 | * Copyright 2012, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | * 11 | * Based on stackoverflow user Stoive's code snippet: 12 | * http://stackoverflow.com/q/4998908 13 | */ 14 | 15 | /*jslint nomen: true, regexp: true */ 16 | /*global window, atob, Blob, ArrayBuffer, Uint8Array, define */ 17 | 18 | (function (window) { 19 | 'use strict'; 20 | var CanvasPrototype = window.HTMLCanvasElement && 21 | window.HTMLCanvasElement.prototype, 22 | hasBlobConstructor = window.Blob && (function () { 23 | try { 24 | return Boolean(new Blob()); 25 | } catch (e) { 26 | return false; 27 | } 28 | }()), 29 | hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array && 30 | (function () { 31 | try { 32 | return new Blob([new Uint8Array(100)]).size === 100; 33 | } catch (e) { 34 | return false; 35 | } 36 | }()), 37 | BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || 38 | window.MozBlobBuilder || window.MSBlobBuilder, 39 | dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob && 40 | window.ArrayBuffer && window.Uint8Array && function (dataURI) { 41 | var byteString, 42 | arrayBuffer, 43 | intArray, 44 | i, 45 | mimeString, 46 | bb; 47 | if (dataURI.split(',')[0].indexOf('base64') >= 0) { 48 | // Convert base64 to raw binary data held in a string: 49 | byteString = atob(dataURI.split(',')[1]); 50 | } else { 51 | // Convert base64/URLEncoded data component to raw binary data: 52 | byteString = decodeURIComponent(dataURI.split(',')[1]); 53 | } 54 | // Write the bytes of the string to an ArrayBuffer: 55 | arrayBuffer = new ArrayBuffer(byteString.length); 56 | intArray = new Uint8Array(arrayBuffer); 57 | for (i = 0; i < byteString.length; i += 1) { 58 | intArray[i] = byteString.charCodeAt(i); 59 | } 60 | // Separate out the mime component: 61 | mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 62 | // Write the ArrayBuffer (or ArrayBufferView) to a blob: 63 | if (hasBlobConstructor) { 64 | return new Blob( 65 | [hasArrayBufferViewSupport ? intArray : arrayBuffer], 66 | {type: mimeString} 67 | ); 68 | } 69 | bb = new BlobBuilder(); 70 | bb.append(arrayBuffer); 71 | return bb.getBlob(mimeString); 72 | }; 73 | if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) { 74 | if (CanvasPrototype.mozGetAsFile) { 75 | CanvasPrototype.toBlob = function (callback, type, quality) { 76 | if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) { 77 | callback(dataURLtoBlob(this.toDataURL(type, quality))); 78 | } else { 79 | callback(this.mozGetAsFile('blob', type)); 80 | } 81 | }; 82 | } else if (CanvasPrototype.toDataURL && dataURLtoBlob) { 83 | CanvasPrototype.toBlob = function (callback, type, quality) { 84 | callback(dataURLtoBlob(this.toDataURL(type, quality))); 85 | }; 86 | } 87 | } 88 | if (typeof define === 'function' && define.amd) { 89 | define(function () { 90 | return dataURLtoBlob; 91 | }); 92 | } else { 93 | window.dataURLtoBlob = dataURLtoBlob; 94 | } 95 | }(window)); 96 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/js/locales/zh.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FileInput Chinese Translations 3 | * 4 | * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or 5 | * any HTML markup tags in the messages must not be converted or translated. 6 | * 7 | * @see http://github.com/kartik-v/bootstrap-fileinput 8 | * @author kangqf 9 | * 10 | * NOTE: this file must be saved in UTF-8 encoding. 11 | */ 12 | (function ($) { 13 | "use strict"; 14 | 15 | $.fn.fileinputLocales['zh'] = { 16 | fileSingle: '文件', 17 | filePlural: '个文件', 18 | browseLabel: '选择 …', 19 | removeLabel: '移除', 20 | removeTitle: '清除选中文件', 21 | cancelLabel: '取消', 22 | cancelTitle: '取消进行中的上传', 23 | uploadLabel: '上传', 24 | uploadTitle: '上传选中文件', 25 | msgNo: '没有', 26 | msgNoFilesSelected: '', 27 | msgCancelled: '取消', 28 | msgZoomModalHeading: '详细预览', 29 | msgFileRequired: 'You must select a file to upload.', 30 | msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', 31 | msgSizeTooLarge: '文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB.', 32 | msgFilesTooLess: '你必须选择最少 {n} {files} 来上传. ', 33 | msgFilesTooMany: '选择的上传文件个数 ({n}) 超出最大文件的限制个数 {m}.', 34 | msgFileNotFound: '文件 "{name}" 未找到!', 35 | msgFileSecured: '安全限制,为了防止读取文件 "{name}".', 36 | msgFileNotReadable: '文件 "{name}" 不可读.', 37 | msgFilePreviewAborted: '取消 "{name}" 的预览.', 38 | msgFilePreviewError: '读取 "{name}" 时出现了一个错误.', 39 | msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', 40 | msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.', 41 | msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.', 42 | msgFileTypes: { 43 | 'image': 'image', 44 | 'html': 'HTML', 45 | 'text': 'text', 46 | 'video': 'video', 47 | 'audio': 'audio', 48 | 'flash': 'flash', 49 | 'pdf': 'PDF', 50 | 'object': 'object' 51 | }, 52 | msgUploadAborted: '该文件上传被中止', 53 | msgUploadThreshold: 'Processing...', 54 | msgUploadBegin: 'Initializing...', 55 | msgUploadEnd: 'Done', 56 | msgUploadEmpty: 'No valid data available for upload.', 57 | msgValidationError: '验证错误', 58 | msgLoading: '加载第 {index} 文件 共 {files} …', 59 | msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', 60 | msgSelected: '{n} {files} 选中', 61 | msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', 62 | msgImageWidthSmall: '宽度的图像文件的"{name}"的必须是至少{size}像素.', 63 | msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', 64 | msgImageWidthLarge: '宽度的图像文件"{name}"不能超过{size}像素.', 65 | msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', 66 | msgImageResizeError: '无法获取的图像尺寸调整。', 67 | msgImageResizeException: '错误而调整图像大小。
{errors}
', 68 | msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', 69 | msgAjaxProgressError: '{operation} failed', 70 | ajaxOperations: { 71 | deleteThumb: 'file delete', 72 | uploadThumb: 'file upload', 73 | uploadBatch: 'batch file upload', 74 | uploadExtra: 'form data upload' 75 | }, 76 | dropZoneTitle: '拖拽文件到这里 …
支持多文件同时上传', 77 | dropZoneClickTitle: '
(或点击{files}按钮选择文件)', 78 | fileActionSettings: { 79 | removeTitle: '删除文件', 80 | uploadTitle: '上传文件', 81 | zoomTitle: '查看详情', 82 | dragTitle: '移动 / 重置', 83 | indicatorNewTitle: '没有上传', 84 | indicatorSuccessTitle: '上传', 85 | indicatorErrorTitle: '上传错误', 86 | indicatorLoadingTitle: '上传 ...' 87 | }, 88 | previewZoomButtonTitles: { 89 | prev: '预览上一个文件', 90 | next: '预览下一个文件', 91 | toggleheader: '缩放', 92 | fullscreen: '全屏', 93 | borderless: '无边界模式', 94 | close: '关闭当前预览' 95 | } 96 | }; 97 | })(window.jQuery); -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Students Homework Management System 7 | 8 | 9 | contextConfigLocation 10 | classpath:applicationContext.xml 11 | 12 | 13 | 14 | CharacterEncodingFilter 15 | 16 | org.springframework.web.filter.CharacterEncodingFilter 17 | 18 | 19 | encoding 20 | UTF-8 21 | 22 | 23 | 24 | shiroFilter 25 | org.springframework.web.filter.DelegatingFilterProxy 26 | 27 | targetFilterLifecycle 28 | true 29 | 30 | 31 | 32 | druidWebStatFilter 33 | com.alibaba.druid.support.http.WebStatFilter 34 | 35 | exclusions 36 | /public/*,*.js,*.css,/druid*,*.jsp,*.swf 37 | 38 | 39 | principalSessionName 40 | sessionInfo 41 | 42 | 43 | profileEnable 44 | true 45 | 46 | 47 | 48 | 49 | CharacterEncodingFilter 50 | /* 51 | 52 | 53 | shiroFilter 54 | /* 55 | 56 | 57 | druidWebStatFilter 58 | /* 59 | 60 | 61 | 62 | org.springframework.web.context.ContextLoaderListener 63 | 64 | 65 | 66 | DispatcherServlet 67 | org.springframework.web.servlet.DispatcherServlet 68 | 69 | contextConfigLocation 70 | classpath:springmvc.xml 71 | 72 | 73 | 74 | DruidStatView 75 | com.alibaba.druid.support.http.StatViewServlet 76 | 77 | 78 | resetEnable 79 | true 80 | 81 | 82 | 83 | loginUsername 84 | itning 85 | 86 | 87 | 88 | loginPassword 89 | kingston 90 | 91 | 92 | 93 | DruidStatView 94 | /druid/* 95 | 96 | 97 | DispatcherServlet 98 | / 99 | 100 | 101 | 102 | /index.jsp 103 | 104 | 105 | 106 | 404 107 | /jsp/error.jsp 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/editsubjectui.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | <%@ page isELIgnored="false" %> 5 | <% String path = request.getContextPath(); 6 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 7 | application.setAttribute("basePath", basePath); 8 | %> 9 | 10 | 11 | 12 |
13 |

编辑作业:

14 | 20 |
21 | 22 |
23 | 24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 | 33 | 34 | 35 |
36 | 37 | 38 |
39 | 40 | 41 | 42 | 43 |
44 |
45 | 46 |
47 | 48 |
49 | 55 |
56 |
57 |
58 |
59 | 60 |
61 |
62 |
63 | -------------------------------------------------------------------------------- /src/main/webapp/js/canvas-nest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 hustcc 3 | * License: MIT 4 | * Version: v1.0.1 5 | * GitHub: https://github.com/hustcc/canvas-nest.js 6 | **/ 7 | !function () { 8 | //封装方法,压缩之后减少文件大小 9 | function get_attribute(node, attr, default_value) { 10 | return node.getAttribute(attr) || default_value; 11 | } 12 | 13 | //封装方法,压缩之后减少文件大小 14 | function get_by_tagname(name) { 15 | return document.getElementsByTagName(name); 16 | } 17 | 18 | //获取配置参数 19 | function get_config_option() { 20 | var scripts = get_by_tagname("script"), 21 | script_len = scripts.length, 22 | script = scripts[script_len - 1]; //当前加载的script 23 | return { 24 | l: script_len, //长度,用于生成id用 25 | z: get_attribute(script, "zIndex", -1), //z-index 26 | o: get_attribute(script, "opacity", 0.5), //opacity 27 | c: get_attribute(script, "color", "0,0,0"), //color 28 | n: get_attribute(script, "count", 99) //count 29 | }; 30 | } 31 | 32 | //设置canvas的高宽 33 | function set_canvas_size() { 34 | canvas_width = the_canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, 35 | canvas_height = the_canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 36 | } 37 | 38 | //绘制过程 39 | function draw_canvas() { 40 | context.clearRect(0, 0, canvas_width, canvas_height); 41 | //随机的线条和当前位置联合数组 42 | var e, i, d, x_dist, y_dist, dist; //临时节点 43 | //遍历处理每一个点 44 | random_points.forEach(function (r, idx) { 45 | r.x += r.xa, 46 | r.y += r.ya, //移动 47 | r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1, 48 | r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1, //碰到边界,反向反弹 49 | context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); //绘制一个宽高为1的点 50 | //从下一个点开始 51 | for (i = idx + 1; i < all_array.length; i++) { 52 | e = all_array[i]; 53 | // 当前点存在 54 | if (null !== e.x && null !== e.y) { 55 | x_dist = r.x - e.x; //x轴距离 l 56 | y_dist = r.y - e.y; //y轴距离 n 57 | dist = x_dist * x_dist + y_dist * y_dist; //总距离, m 58 | 59 | dist < e.max && (e === current_point && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), //靠近的时候加速 60 | d = (e.max - dist) / e.max, 61 | context.beginPath(), 62 | context.lineWidth = d / 2, 63 | context.strokeStyle = "rgba(" + config.c + "," + (d + 0.2) + ")", 64 | context.moveTo(r.x, r.y), 65 | context.lineTo(e.x, e.y), 66 | context.stroke()); 67 | } 68 | } 69 | }), frame_func(draw_canvas); 70 | } 71 | 72 | //创建画布,并添加到body中 73 | var the_canvas = document.createElement("canvas"), //画布 74 | config = get_config_option(), //配置 75 | canvas_id = "c_n" + config.l, //canvas id 76 | context = the_canvas.getContext("2d"), canvas_width, canvas_height, 77 | frame_func = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (func) { 78 | window.setTimeout(func, 1000 / 45); 79 | }, random = Math.random, 80 | current_point = { 81 | x: null, //当前鼠标x 82 | y: null, //当前鼠标y 83 | max: 20000 // 圈半径的平方 84 | }, 85 | all_array; 86 | the_canvas.id = canvas_id; 87 | the_canvas.style.cssText = "position:fixed;top:0;left:0;z-index:" + config.z + ";opacity:" + config.o; 88 | get_by_tagname("body")[0].appendChild(the_canvas); 89 | 90 | //初始化画布大小 91 | set_canvas_size(); 92 | window.onresize = set_canvas_size; 93 | //当时鼠标位置存储,离开的时候,释放当前位置信息 94 | window.onmousemove = function (e) { 95 | e = e || window.event; 96 | current_point.x = e.clientX; 97 | current_point.y = e.clientY; 98 | }, window.onmouseout = function () { 99 | current_point.x = null; 100 | current_point.y = null; 101 | }; 102 | //随机生成config.n条线位置信息 103 | for (var random_points = [], i = 0; config.n > i; i++) { 104 | var x = random() * canvas_width, //随机位置 105 | y = random() * canvas_height, 106 | xa = 2 * random() - 1, //随机运动方向 107 | ya = 2 * random() - 1; 108 | // 随机点 109 | random_points.push({ 110 | x: x, 111 | y: y, 112 | xa: xa, 113 | ya: ya, 114 | max: 6000 //沾附距离 115 | }); 116 | } 117 | all_array = random_points.concat([current_point]); 118 | //0.1秒后绘制 119 | setTimeout(function () { 120 | draw_canvas(); 121 | }, 100); 122 | }(); 123 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/BindQQ.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 学生作业管理系统-绑定QQ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 30 | 31 | 32 |
33 |
34 | 48 |

49 |
50 |
51 | 52 | 53 | <%@include file="footer.jsp" %> 54 | 55 | 56 | 57 | 58 | 59 | 60 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/java/com/ning/login/action/Login.java: -------------------------------------------------------------------------------- 1 | package com.ning.login.action; 2 | 3 | import com.ning.exception.login.LoginException; 4 | import com.ning.login.entity.User; 5 | import com.ning.login.service.UserService; 6 | import com.ning.util.qqlogin.QQLoginUtil; 7 | import com.qq.connect.QQConnectException; 8 | import com.qq.connect.oauth.Oauth; 9 | import org.apache.shiro.SecurityUtils; 10 | import org.apache.shiro.authc.AuthenticationException; 11 | import org.apache.shiro.authc.IncorrectCredentialsException; 12 | import org.apache.shiro.authc.UnknownAccountException; 13 | import org.apache.shiro.authc.UsernamePasswordToken; 14 | import org.apache.shiro.subject.Subject; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.springframework.stereotype.Controller; 18 | import org.springframework.ui.Model; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | 21 | import javax.annotation.Resource; 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | /** 25 | * 登陆 26 | * 27 | * @author wangn 28 | * @date 2017/5/19 29 | */ 30 | @Controller 31 | public class Login { 32 | private static final Logger logger = LoggerFactory.getLogger(Login.class); 33 | 34 | @Resource 35 | private UserService userService; 36 | 37 | /** 38 | * 用户登陆 39 | * 40 | * @param model {@link Model} 41 | * @param request {@link HttpServletRequest} 42 | * @return jsp/login.jsp 43 | * @throws LoginException LoginException 44 | */ 45 | @RequestMapping("login") 46 | public String userLogin(Model model, HttpServletRequest request) throws LoginException { 47 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 48 | if (user != null && user.getUid() != null) { 49 | logger.debug("用户成功登录 {}", user); 50 | return "redirect:index.jsp"; 51 | } 52 | String exceptionClassName = (String) request.getAttribute("shiroLoginFailure"); 53 | if (exceptionClassName != null) { 54 | if (UnknownAccountException.class.getName().equals(exceptionClassName)) { 55 | model.addAttribute("returninfo", "账号不存在"); 56 | } else if (IncorrectCredentialsException.class.getName().equals( 57 | exceptionClassName) || AuthenticationException.class.getName().equals(exceptionClassName)) { 58 | model.addAttribute("returninfo", "用户名/密码错误"); 59 | } else { 60 | throw new LoginException(exceptionClassName); 61 | } 62 | } 63 | return "jsp/login.jsp"; 64 | } 65 | 66 | /** 67 | * QQ登陆 68 | * 69 | * @param request {@link HttpServletRequest} 70 | * @return 重定向到QQ登陆地址 71 | * @throws QQConnectException QQConnectException 72 | */ 73 | @RequestMapping("qqLogin") 74 | public String qqLogin(HttpServletRequest request) throws QQConnectException { 75 | return "redirect:" + new Oauth().getAuthorizeURL(request); 76 | } 77 | 78 | /** 79 | * QQ登陆解析 80 | * 81 | * @param request {@link HttpServletRequest} 82 | * @return JSP页面 83 | * @throws LoginException LoginException 84 | */ 85 | @RequestMapping("qqLoginAfter") 86 | public String qqLoginAfter(HttpServletRequest request) throws LoginException { 87 | String userOpenID = QQLoginUtil.getUserOpenID(request); 88 | if (userOpenID == null) { 89 | throw new LoginException("userOpenID==null"); 90 | } 91 | User userByopenID = userService.getUserEntityByOpenID(userOpenID); 92 | if (userByopenID == null) { 93 | request.getSession().setAttribute("userOpenID", userOpenID); 94 | return "jsp/BindQQ.jsp"; 95 | } else { 96 | Subject currentUser = SecurityUtils.getSubject(); 97 | UsernamePasswordToken token = new UsernamePasswordToken(userByopenID.getUsername(), userByopenID.getPassword(), false, request.getRemoteAddr()); 98 | currentUser.login(token); 99 | } 100 | return "index.jsp"; 101 | } 102 | 103 | /** 104 | * 将QQ绑定到用户 105 | * 106 | * @param username 用户名 107 | * @param password 密码 108 | * @param model {@link Model} 109 | * @param request {@link HttpServletRequest} 110 | * @return JSP页面 111 | */ 112 | @RequestMapping("bindQQ") 113 | public String bindQQ(String username, String password, Model model, HttpServletRequest request) { 114 | String userOpenID = (String) request.getSession().getAttribute("userOpenID"); 115 | String passwd = userService.getPasswd(username); 116 | if (passwd == null) { 117 | model.addAttribute("returninfo", "输入的学号不存在,请重试!"); 118 | return "jsp/BindQQ.jsp"; 119 | } 120 | if (!(passwd.equals(password))) { 121 | model.addAttribute("returninfo", "密码错误,请重试!"); 122 | return "jsp/BindQQ.jsp"; 123 | } 124 | Subject currentUser = SecurityUtils.getSubject(); 125 | UsernamePasswordToken token = new UsernamePasswordToken(username, password, false, request.getRemoteAddr()); 126 | currentUser.login(token); 127 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 128 | user.setUserOpenID(userOpenID); 129 | userService.insertQQIDByUID(user); 130 | return "index.jsp"; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/cpasswd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 学生作业管理系统-更改密码 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 30 | 31 | 32 |
33 |
34 | 49 |

50 |
51 |
52 | 53 | <%@include file="footer.jsp" %> 54 | 55 | 56 | 57 | 58 | 59 | 60 | 110 | 111 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/themes/explorer/theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme style for bootstrap-fileinput. Load this theme file after loading `fileinput.css`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | .theme-explorer .file-preview .table { 14 | margin: 0; 15 | } 16 | 17 | .theme-explorer .explorer-frame td { 18 | vertical-align: middle; 19 | text-align: left; 20 | } 21 | 22 | .explorer-frame .file-preview-text { 23 | display: inline-block; 24 | color: #428bca; 25 | border: 1px solid #ddd; 26 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 27 | outline: none; 28 | padding: 8px; 29 | resize: none; 30 | } 31 | 32 | .explorer-frame .file-preview-html { 33 | display: inline-block; 34 | border: 1px solid #ddd; 35 | padding: 8px; 36 | overflow: auto; 37 | } 38 | 39 | .explorer-frame .file-preview-other { 40 | text-align: center; 41 | } 42 | 43 | .explorer-frame .file-other-icon { 44 | font-size: 4.2em; 45 | } 46 | 47 | .theme-explorer .explorer-frame .kv-file-content { 48 | width: 80px; 49 | height: 80px; 50 | padding: 5px; 51 | text-align: center; 52 | } 53 | 54 | .theme-explorer .file-actions-cell { 55 | width: 100px; 56 | padding: 0; 57 | } 58 | 59 | .theme-explorer .file-thumb-progress .progress { 60 | display: block; 61 | margin-top: 5px; 62 | } 63 | 64 | .theme-explorer .file-thumb-progress .progress, .theme-explorer .file-thumb-progress .progress-bar { 65 | height: 13px; 66 | font-size: 11px; 67 | line-height: 13px; 68 | } 69 | 70 | .theme-explorer .file-actions-cell { 71 | position: relative; 72 | } 73 | 74 | .theme-explorer .file-upload-indicator, .theme-explorer .file-drag-handle { 75 | position: absolute; 76 | text-align: center; 77 | top: 0; 78 | right: 0; 79 | padding-left: 5px; 80 | padding-right: 2px; 81 | border-right: none; 82 | border-top: none; 83 | border-left: 1px solid #8a6d3b; 84 | border-bottom: 1px solid #8a6d3b; 85 | border-bottom-left-radius: 11px; 86 | font-size: 12px; 87 | } 88 | 89 | .theme-explorer .explorer-caption { 90 | display: block; 91 | color: #777; 92 | } 93 | 94 | .theme-explorer .file-actions { 95 | text-align: center; 96 | } 97 | 98 | .theme-explorer .kvsortable-ghost { 99 | opacity: 0.6; 100 | background: #e1edf7; 101 | border: 2px solid #a1abff; 102 | } 103 | 104 | .theme-explorer .file-upload-indicator { 105 | font-size: 13px; 106 | padding-left: 6px; 107 | background-color: #fcf8e3; 108 | border-color: #faebcc; 109 | } 110 | 111 | .theme-explorer .file-drag-handle { 112 | right: -2px; 113 | background-color: #d9edf7; 114 | border-color: #bce8f1; 115 | } 116 | 117 | .theme-explorer .file-preview-error .file-upload-indicator { 118 | background-color: #f2dede; 119 | border-color: #ebccd1; 120 | } 121 | 122 | .theme-explorer .file-preview-success .file-upload-indicator { 123 | background-color: #dff0d8; 124 | border-color: #d6e9c6; 125 | } 126 | 127 | .theme-explorer .file-preview-loading .file-upload-indicator { 128 | background-color: #e5e5e5; 129 | border-color: #777; 130 | } 131 | 132 | .theme-explorer .file-error-message ul { 133 | padding-left: 15px; 134 | } 135 | 136 | .theme-explorer .file-error-message .close { 137 | margin-top: -5px; 138 | margin-right: -5px; 139 | } 140 | 141 | /* 142 | * mobile responsive styling 143 | */ 144 | @media only screen and (max-width: 500px) { 145 | .theme-explorer .table, .theme-explorer .table tbody, .theme-explorer .table tr, .theme-explorer .table td { 146 | display: block; 147 | width: 100% !important; 148 | } 149 | 150 | .theme-explorer .table { 151 | border: none; 152 | } 153 | 154 | .theme-explorer .table tr { 155 | margin-top: 5px; 156 | } 157 | 158 | .theme-explorer .table tr:first-child { 159 | margin-top: 0; 160 | } 161 | 162 | .theme-explorer .table td { 163 | text-align: center; 164 | } 165 | 166 | .theme-explorer .table .kv-file-content { 167 | border-bottom: none; 168 | padding: 4px; 169 | margin: 0; 170 | } 171 | 172 | .theme-explorer .table .kv-file-content .file-preview-image { 173 | max-width: 100%; 174 | } 175 | 176 | .theme-explorer .file-details-cell { 177 | border-top: none; 178 | border-bottom: none; 179 | padding-top: 0; 180 | margin: 0; 181 | } 182 | 183 | .theme-explorer .file-actions-cell { 184 | border-top: none; 185 | padding-bottom: 4px; 186 | } 187 | 188 | .theme-explorer .explorer-frame .explorer-caption { 189 | white-space: nowrap; 190 | text-overflow: ellipsis; 191 | overflow: hidden; 192 | left: 0; 193 | right: 0; 194 | margin: auto; 195 | } 196 | 197 | .theme-explorer .file-upload-indicator, .theme-explorer .file-drag-handle { 198 | right: 0; 199 | bottom: 0; 200 | border-top-left-radius: 40px; 201 | border-bottom-left-radius: 0; 202 | padding: 12px 3px 0 6px; 203 | } 204 | 205 | .theme-explorer .file-actions-cell .btn-xs { 206 | font-size: 0.9em; 207 | padding: 2px 7px; 208 | margin-right: 3px; 209 | cursor: pointer; 210 | } 211 | } -------------------------------------------------------------------------------- /src/main/webapp/jsp/firstpd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 4 | <%@ page isELIgnored="false" %> 5 | <% String path = request.getContextPath(); 6 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 7 | application.setAttribute("basePath", basePath); 8 | %> 9 | 10 | 11 | 12 | 13 | 14 | 15 | 学生作业管理系统-更改密码 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 31 | 32 | 33 |
34 |
35 | 51 |

52 |
53 |
54 | 55 | <%@include file="footer.jsp" %> 56 | 57 | 58 | 59 | 60 | 61 | 62 | 112 | 113 | -------------------------------------------------------------------------------- /src/main/webapp/jsp/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ page isELIgnored="false" %> 4 | <% String path = request.getContextPath(); 5 | String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; 6 | application.setAttribute("basePath", basePath); 7 | %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 学生作业管理系统-登录 15 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 34 | 35 | 36 |
37 |
38 | 66 |

67 |
68 |
69 | 70 | <%@include file="footer.jsp" %> 71 | 72 | 73 | 74 | 75 | 76 | 77 | 133 | 134 | -------------------------------------------------------------------------------- /src/main/java/com/ning/file/service/impl/FileServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.service.impl; 2 | 3 | import com.ning.exception.file.FileException; 4 | import com.ning.file.dao.HistoryDao; 5 | import com.ning.file.dao.OrderInfoDao; 6 | import com.ning.file.entity.History; 7 | import com.ning.file.entity.OrderInfo; 8 | import com.ning.file.service.FileService; 9 | import com.ning.login.entity.User; 10 | import com.ning.util.properties.PropertiesUtil; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.web.multipart.MultipartFile; 13 | 14 | import javax.annotation.Resource; 15 | import java.io.File; 16 | import java.util.*; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * Created by wangn on 2017/5/20. 21 | */ 22 | @Service 23 | public class FileServiceImpl implements FileService { 24 | @Resource 25 | private OrderInfoDao orderInfoDao; 26 | 27 | @Resource 28 | private HistoryDao historyDao; 29 | 30 | @Override 31 | public List getONameBySubject(String oname) { 32 | return orderInfoDao.getONameBySubject(oname); 33 | } 34 | 35 | @Override 36 | public List getOnameBysubjectOfAll(String oname){ 37 | return orderInfoDao.getONameBySubjectOfAll(oname); 38 | } 39 | 40 | @Override 41 | public List getOrderInfoFullEntity(){ 42 | List orderInfoList = orderInfoDao.getOrderInfoEntity(); 43 | List filtered = new ArrayList<>(); 44 | for (OrderInfo orderInfo : orderInfoList) { 45 | if (orderInfo.getOstate()) { 46 | filtered.add(orderInfo); 47 | } 48 | } 49 | return filtered; 50 | } 51 | 52 | @Override 53 | public Set getOrderInfoEntity(){ 54 | List orderInfoList = orderInfoDao.getOrderInfoEntity(); 55 | //集合用于存储并清除重复下拉框数据 56 | Set set = new HashSet<>(); 57 | for (OrderInfo orderInfo : orderInfoList) { 58 | if (orderInfo.getOstate()) { 59 | set.add(orderInfo.getOsubject()); 60 | } 61 | } 62 | return set; 63 | } 64 | 65 | @Override 66 | public Set getOrderInfoEntityOfAll(){ 67 | List orderInfoList = orderInfoDao.getOrderInfoEntity(); 68 | //集合用于存储并清除重复下拉框数据 69 | Set set = new HashSet<>(); 70 | for (OrderInfo orderInfo : orderInfoList) { 71 | set.add(orderInfo.getOsubject()); 72 | } 73 | return set; 74 | } 75 | 76 | @Override 77 | public OrderInfo getOrderInfoEntityByOID(Integer oid) { 78 | return orderInfoDao.getOrderInfoEntityByOID(oid); 79 | } 80 | 81 | @Override 82 | public void insertDataByEntity(History history) { 83 | historyDao.insertDataByEntity(history); 84 | } 85 | 86 | @Override 87 | public List getUpListByUID(String huid) { 88 | return historyDao.getUpListByUID(huid); 89 | } 90 | 91 | @Override 92 | public void delEntityByHID(String delHid) { 93 | historyDao.delEntityByHID(delHid); 94 | } 95 | 96 | @Override 97 | public History getEntityByHID(String hid) { 98 | return historyDao.getEntityByHID(hid); 99 | } 100 | 101 | @Override 102 | public History findHuidExists(Map hoidhuid) { 103 | return historyDao.findHuidExists(hoidhuid); 104 | } 105 | 106 | @Override 107 | public void upHistoryData(History history) { 108 | historyDao.upHistoryData(history); 109 | } 110 | 111 | @Override 112 | public void delEntityByHOID(Integer hoid) { 113 | historyDao.delEntityByHoId(hoid); 114 | } 115 | 116 | @Override 117 | public List getUserHistoryByUserId(String uId) { 118 | return this.getUpListByUID(uId).stream().peek(history -> { 119 | // here we could have the deadline 120 | OrderInfo orderInfo = this.getOrderInfoEntityByOID(history.getHoid()); 121 | 122 | if (orderInfo != null) { 123 | history.setOsubject(orderInfo.getOsubject()); 124 | history.setOname(orderInfo.getOname()); 125 | //设置文件扩展名 126 | history.setFilepath(history.getFilepath().substring(history.getFilepath().lastIndexOf(".") + 1)); 127 | 128 | //set deadline 129 | history.setDeadline(orderInfo.getOdeadline()); 130 | } 131 | }).collect(Collectors.toList()); 132 | } 133 | 134 | @Override 135 | public void uploadFile(MultipartFile file, User user) throws Exception { 136 | OrderInfo orderInfo = this.getOrderInfoEntityByOID(user.getUserSelectOid()); 137 | History history = new History(); 138 | history.setHid(UUID.randomUUID().toString().replace("-", "")); 139 | history.setHuid(user.getUid()); 140 | history.setHoid(orderInfo.getOid()); 141 | String extensionName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); 142 | 143 | // since oname allows url markdown, this affect filename, causing problem. 144 | String filteredOname = PropertiesUtil.filterOutUrl(orderInfo.getOname()); 145 | 146 | String newfilename = user.getUsername() + "_" + user.getName() + "_" + orderInfo.getOsubject() + "_" + filteredOname + extensionName; 147 | 148 | history.setFilepath(newfilename); 149 | history.setFilesize((double) file.getSize()); 150 | history.setType(file.getContentType()); 151 | history.setUptime(new Date()); 152 | Map map = new HashMap<>(2); 153 | map.put("hoid", user.getUserSelectOid()); 154 | map.put("huid", user.getUid()); 155 | if ((this.findHuidExists(map)) != null) { 156 | this.delEntityByHID(this.findHuidExists(map).getHid()); 157 | } 158 | this.insertDataByEntity(history); 159 | File newfile = new File(PropertiesUtil.getUpLoadFilePath() + newfilename); 160 | file.transferTo(newfile); 161 | } 162 | 163 | @Override 164 | public boolean deleteFile(User user, String hId) throws Exception { 165 | boolean isNotThisUser = true; 166 | List historyList = this.getUpListByUID(user.getUid()); 167 | for (History history : historyList) { 168 | if (history.getHid().equals(hId)) { 169 | isNotThisUser = false; 170 | break; 171 | } 172 | } 173 | if (isNotThisUser) { 174 | return false; 175 | } 176 | History history = this.getEntityByHID(hId); 177 | if (history == null) { 178 | return false; 179 | } 180 | File file = new File(PropertiesUtil.getUpLoadFilePath() + history.getFilepath()); 181 | this.delEntityByHID(hId); 182 | //文件未被删除且存在 183 | return !file.exists() || file.delete(); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/main/webapp/weblib/bootstrap/css/bootstrap-datetimepicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Datetimepicker for Bootstrap 3 3 | * version : 4.17.47 4 | * https://github.com/Eonasdan/bootstrap-datetimepicker/ 5 | */.bootstrap-datetimepicker-widget{list-style:none}.bootstrap-datetimepicker-widget.dropdown-menu{display:block;margin:2px 0;padding:4px;width:19em}@media (min-width:768px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:992px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:1200px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}.bootstrap-datetimepicker-widget.dropdown-menu:before,.bootstrap-datetimepicker-widget.dropdown-menu:after{content:'';display:inline-block;position:absolute}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before{border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);top:-7px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after{border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid white;top:-6px;left:8px}.bootstrap-datetimepicker-widget.dropdown-menu.top:before{border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,0.2);bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.dropdown-menu.top:after{border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid white;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget .list-unstyled{margin:0}.bootstrap-datetimepicker-widget a[data-action]{padding:6px 0}.bootstrap-datetimepicker-widget a[data-action]:active{box-shadow:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:54px;font-weight:bold;font-size:1.2em;margin:0}.bootstrap-datetimepicker-widget button[data-action]{padding:6px}.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Increment Hours"}.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Increment Minutes"}.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Decrement Hours"}.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Decrement Minutes"}.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Show Hours"}.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Show Minutes"}.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Toggle AM/PM"}.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Clear the picker"}.bootstrap-datetimepicker-widget .btn[data-action="today"]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Set the date to today"}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget .picker-switch::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Toggle Date and Time Screens"}.bootstrap-datetimepicker-widget .picker-switch td{padding:0;margin:0;height:auto;width:auto;line-height:inherit}.bootstrap-datetimepicker-widget .picker-switch td span{line-height:2.5;height:2.5em;width:100%}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget table td,.bootstrap-datetimepicker-widget table th{text-align:center;border-radius:4px}.bootstrap-datetimepicker-widget table th{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table th.picker-switch{width:145px}.bootstrap-datetimepicker-widget table th.disabled,.bootstrap-datetimepicker-widget table th.disabled:hover{background:none;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget table th.prev::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Previous Month"}.bootstrap-datetimepicker-widget table th.next::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;content:"Next Month"}.bootstrap-datetimepicker-widget table thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#eee}.bootstrap-datetimepicker-widget table td{height:54px;line-height:54px;width:54px}.bootstrap-datetimepicker-widget table td.cw{font-size:.8em;height:20px;line-height:20px;color:#777}.bootstrap-datetimepicker-widget table td.day{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table td.day:hover,.bootstrap-datetimepicker-widget table td.hour:hover,.bootstrap-datetimepicker-widget table td.minute:hover,.bootstrap-datetimepicker-widget table td.second:hover{background:#eee;cursor:pointer}.bootstrap-datetimepicker-widget table td.old,.bootstrap-datetimepicker-widget table td.new{color:#777}.bootstrap-datetimepicker-widget table td.today{position:relative}.bootstrap-datetimepicker-widget table td.today:before{content:'';display:inline-block;border:solid transparent;border-width:0 0 7px 7px;border-bottom-color:#337ab7;border-top-color:rgba(0,0,0,0.2);position:absolute;bottom:4px;right:4px}.bootstrap-datetimepicker-widget table td.active,.bootstrap-datetimepicker-widget table td.active:hover{background-color:#337ab7;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.bootstrap-datetimepicker-widget table td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget table td.disabled,.bootstrap-datetimepicker-widget table td.disabled:hover{background:none;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget table td span{display:inline-block;width:54px;height:54px;line-height:54px;margin:2px 1.5px;cursor:pointer;border-radius:4px}.bootstrap-datetimepicker-widget table td span:hover{background:#eee}.bootstrap-datetimepicker-widget table td span.active{background-color:#337ab7;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.bootstrap-datetimepicker-widget table td span.old{color:#777}.bootstrap-datetimepicker-widget table td span.disabled,.bootstrap-datetimepicker-widget table td span.disabled:hover{background:none;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget.usetwentyfour td.hour{height:27px;line-height:27px}.bootstrap-datetimepicker-widget.wider{width:21em}.bootstrap-datetimepicker-widget .datepicker-decades .decade{line-height:1.8em !important}.input-group.date .input-group-addon{cursor:pointer}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0} -------------------------------------------------------------------------------- /src/main/webapp/weblib/fileinput/css/fileinput.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v4.4.1 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee default styling for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2017, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD 3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */.file-drop-zone,.krajee-default .file-preview-audio audio,.krajee-default .file-preview-image,.krajee-default .file-preview-other{vertical-align:middle}.file-loading{top:0;right:0;width:25px;height:25px;font-size:999px;text-align:right;color:#fff;background:url(../img/loading.gif) top left no-repeat;border:none}.file-object{margin:0 0 -5px;padding:0}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;text-align:right;opacity:0;background:none;cursor:inherit;display:block}.file-caption-name{display:inline-block;overflow:hidden;height:20px;word-break:break-all}.input-group-lg .file-caption-name{height:25px}.file-zoom-dialog{text-align:left}.file-error-message{color:#a94442;background-color:#f2dede;margin:5px;border:1px solid #ebccd1;border-radius:4px;padding:15px}.file-error-message pre,.file-error-message ul{margin:0;text-align:left}.file-error-message pre{margin:5px 0}.file-caption-disabled{background-color:#EEE;cursor:not-allowed;opacity:1}.file-preview{border-radius:5px;border:1px solid #ddd;padding:5px;width:100%;margin-bottom:5px}.krajee-default.file-preview-frame{position:relative;display:table;margin:8px;border:1px solid #ddd;box-shadow:1px 1px 5px 0 #a2958a;padding:6px;float:left;text-align:center}.krajee-default.file-preview-frame:not(.file-preview-error):hover{box-shadow:3px 3px 5px 0 #333}.krajee-default.file-preview-frame .kv-file-content{height:170px}.krajee-default.file-preview-frame .file-thumbnail-footer{height:70px}.krajee-default .file-preview-text{display:block;color:#428bca;border:1px solid #ddd;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;outline:0;padding:8px;resize:none}.krajee-default .file-preview-html{border:1px solid #ddd;padding:8px;overflow:auto}.krajee-default[data-template=audio] .file-preview-audio{display:table-cell;vertical-align:middle;height:170px;border:1px solid #ddd;border-radius:5px}.krajee-default .file-zoom-dialog .file-preview-text{font-size:1.2em}.krajee-default .file-preview-other{left:0;top:0;right:0;bottom:0;margin:auto;text-align:center;padding:10px}.krajee-default .file-preview-other:hover{opacity:.8}.krajee-default .file-actions,.krajee-default .file-other-error{text-align:left}.krajee-default .file-other-icon{font-size:8em}.krajee-default .file-actions{margin-top:15px}.krajee-default .file-footer-buttons{float:right}.krajee-default .file-footer-caption{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:160px;text-align:center;padding-top:4px;font-size:11px;color:#777;margin:5px auto}.file-input-ajax-new .fileinput-remove-button,.file-input-ajax-new .fileinput-upload-button,.file-input-ajax-new .no-browse .input-group-btn,.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file,.file-input-new .no-browse .input-group-btn{display:none}.krajee-default .file-preview-error{opacity:.65;box-shadow:none}.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover{color:#000}.krajee-default .file-drag-handle,.krajee-default .file-upload-indicator{position:absolute;text-align:center;bottom:-6px;left:-6px;padding:8px 8px 1px 3px;border-left:none;border-bottom:none;border-right:1px solid #8a6d3b;border-top:1px solid #8a6d3b;border-top-right-radius:24px;font-size:12px}.krajee-default .file-drag-handle{background-color:#d9edf7;border-color:#bce8f1}.krajee-default .file-upload-indicator{font-size:13px;background-color:#fcf8e3;border-color:#faebcc;padding-bottom:0}.krajee-default.file-preview-error .file-upload-indicator{background-color:#f2dede;border-color:#ebccd1}.krajee-default.file-preview-success .file-upload-indicator{background-color:#dff0d8;border-color:#d6e9c6}.krajee-default.file-preview-loading .file-upload-indicator{background-color:#e5e5e5;border-color:#777}.krajee-default .file-thumb-progress .progress,.krajee-default .file-thumb-progress .progress-bar{height:10px;font-size:9px;line-height:10px}.krajee-default .file-thumbnail-footer{position:relative}.krajee-default .file-thumb-progress{height:10px;position:absolute;top:35px;left:0;right:0}.krajee-default.kvsortable-ghost{background:#e1edf7;border:2px solid #a1abff}.file-zoom-dialog .file-other-icon{font-size:22em;font-size:50vmin}.file-caption-main{width:100%}.file-input-ajax-new .no-browse .form-control,.file-input-new .no-browse .form-control{border-top-right-radius:4px;border-bottom-right-radius:4px}.file-thumb-loading{background:url(../img/loading.gif) center center no-repeat content-box!important}.file-sortable .file-drag-handle{cursor:move;cursor:-webkit-grabbing;opacity:1}.file-sortable .file-drag-handle:hover{opacity:.7}.file-drop-zone{border:1px dashed #aaa;border-radius:4px;height:100%;text-align:center;margin:12px 15px 12px 12px;padding:5px}.file-drop-zone-title{color:#aaa;font-size:1.6em;padding:85px 10px;cursor:default}.clickable .file-drop-zone-title,.file-preview .clickable{cursor:pointer}.file-drop-zone.clickable:hover{border:2px dashed #999}.file-drop-zone.clickable:focus{border:2px solid #5acde2}.file-drop-zone .file-preview-thumbnails{cursor:default}.file-highlighted{border:2px dashed #999!important;background-color:#f0f0f0}.file-uploading{background:url(../img/loading-sm.gif) center bottom 10px no-repeat;opacity:.65}.file-zoom-fullscreen.modal{position:fixed;top:0;right:0;bottom:0;left:0}.file-zoom-fullscreen .modal-dialog{position:fixed;margin:0;width:100%;height:100%;padding:0}.file-zoom-fullscreen .modal-content{border-radius:0;box-shadow:none}.file-zoom-fullscreen .modal-body{overflow-y:auto}.file-zoom-dialog .modal-body{position:relative!important}.file-zoom-dialog .btn-navigate{position:absolute;padding:0;margin:0;background:0 0;text-decoration:none;outline:0;opacity:.7;top:45%;font-size:4em;color:#1c94c4}.file-zoom-dialog .floating-buttons{position:absolute;top:5px;right:10px}.floating-buttons,.floating-buttons .btn{z-index:3000}.file-zoom-dialog .kv-zoom-actions .btn,.floating-buttons .btn{margin-left:3px}.file-zoom-dialog .btn-navigate:not([disabled]):focus,.file-zoom-dialog .btn-navigate:not([disabled]):hover{outline:0;box-shadow:none;opacity:.5}.file-zoom-dialog .btn-navigate[disabled]{opacity:.3}.file-zoom-dialog .btn-prev{left:1px}.file-zoom-dialog .btn-next{right:1px}.file-zoom-content{height:480px;text-align:center}.file-zoom-content .file-preview-image,.file-zoom-content .file-preview-video{max-height:100%}.file-zoom-content>.file-object.type-image{width:auto;height:auto;min-height:inherit;max-width:100%;max-height:100%}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-video{width:auto;height:100%;max-width:100%;max-height:100%}.file-zoom-content>.file-object.type-audio{width:auto;height:30px}.file-zoom-content>.file-object.type-default,.file-zoom-content>.file-object.type-html,.file-zoom-content>.file-object.type-pdf,.file-zoom-content>.file-object.type-text{width:100%}.file-preview-initial.sortable-chosen{background-color:#d9edf7}.btn-file ::-ms-browse{font-size:10000px;width:100%;height:100%}.rotate-2{transform:rotateY(180deg)}.rotate-3{transform:rotate(180deg)}.rotate-4{transform:rotate(180deg) rotateY(180deg)}.rotate-5{transform:rotate(270deg) rotateY(180deg)}.rotate-6{transform:rotate(90deg)}.rotate-7{transform:rotate(90deg) rotateY(180deg)}.rotate-8{transform:rotate(270deg)}.file-zoom-content .is-portrait-gt4{margin-top:60px} -------------------------------------------------------------------------------- /src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | com.ning.* 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 110 | 111 | 112 | /logout = logout 113 | /qqLogin = anon 114 | /qqLoginAfter = anon 115 | /downFile = anon 116 | /bindQQ = anon 117 | /css/** = anon 118 | /img/** = anon 119 | /js/** = anon 120 | /weblib/** = anon 121 | /druid/** = anon 122 | /** = user 123 | /** = authc 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 学生作业管理系统 2 | 3 | **Deprecated:New Version Location [Click To New Project](https://github.com/itning/shw_server)** 4 | 5 | **停止维护:新项目地址 [点击进入](https://github.com/itning/shw_server)** 6 | 7 | [![GitHub stars](https://img.shields.io/github/stars/itning/Student-Homework-Management-System.svg?style=social&label=Stars)](https://github.com/itning/Student-Homework-Management-System/stargazers) 8 | [![GitHub forks](https://img.shields.io/github/forks/itning/Student-Homework-Management-System.svg?style=social&label=Fork)](https://github.com/itning/Student-Homework-Management-System/network/members) 9 | [![GitHub watchers](https://img.shields.io/github/watchers/itning/Student-Homework-Management-System.svg?style=social&label=Watch)](https://github.com/itning/Student-Homework-Management-System/watchers) 10 | [![GitHub followers](https://img.shields.io/github/followers/itning.svg?style=social&label=Follow)](https://github.com/itning?tab=followers) 11 | 12 | [![GitHub issues](https://img.shields.io/github/issues/itning/Student-Homework-Management-System.svg)](https://github.com/itning/Student-Homework-Management-System/issues) 13 | [![GitHub license](https://img.shields.io/github/license/itning/Student-Homework-Management-System.svg)](https://github.com/itning/Student-Homework-Management-System/blob/master/LICENSE) 14 | [![GitHub last commit](https://img.shields.io/github/last-commit/itning/Student-Homework-Management-System.svg)](https://github.com/itning/Student-Homework-Management-System/commits) 15 | [![GitHub release](https://img.shields.io/github/release/itning/Student-Homework-Management-System.svg)](https://github.com/itning/Student-Homework-Management-System/releases) 16 | [![GitHub repo size in bytes](https://img.shields.io/github/repo-size/itning/Student-Homework-Management-System.svg)](https://github.com/itning/Student-Homework-Management-System) 17 | [![HitCount](https://hitcount.itning.top/?u=itning&r=Student-Homework-Management-System)](https://github.com/itning/hit-count) 18 | [![language](https://img.shields.io/badge/language-JAVA-green.svg)](https://github.com/itning/Student-Homework-Management-System) 19 | 20 | ### 原本功能 21 | 22 | 1. 管理员在后台数据库中准备好学生学号(10位)后,学生可以用学号登录系统,首次登录需要自行设置密码(大于8位) 23 | 2. 学生可以上传文件到系统中,上传功能基于bootstrap-fileinput 24 | 3. 后台统一命名存储文件 25 | 4. 管理员登陆后可以批量下载后台打包过后的文件 26 | 27 | ### 新增功能 28 | 29 | by tomriddle_1234 30 | 1. 添加截止时间设置,截止时间过后学生无法上传作业 31 | ``` 32 | ALTER TABLE `shw`.`orderinfo` 33 | ADD COLUMN `odeadline` DATETIME NOT NULL DEFAULT '2022-01-01 00:00:00' AFTER `otime`; 34 | ``` 35 | 2. 管理员删除作业任务时,增加确认对话框 36 | 3. 一些界面的小优化 37 | 4. 添加编辑作业任务功能 38 | 5. 作业名称可以用[]()添加链接 39 | 40 | ## 架构 41 | 42 | ### 前端 43 | 44 | 1. jQuery 45 | 2. Bootstrap3 46 | 3. Bootstrap-fileinput 47 | 4. moment.js 48 | 5. bootstrap-datepicker (bootstrap 3 v4) 49 | 50 | ### 后端 51 | 52 | 1. Spring MVC 53 | 2. Spring 54 | 3. Mybatis 55 | 4. Shiro (安全框架) 56 | 5. Druid(阿里巴巴的开源连接池) 57 | 6. MySql 58 | 59 | ## 部署 60 | 61 | 1. 下载源码 62 | 63 | 你可以在Git([Git是什么,如何使用?](https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/))输入以下命令进行clone项目到本地 64 | 65 | ``git clone https://github.com/itning/Student-Homework-Management-System.git`` 66 | 67 | 或者直接下载主分支的[源码](https://github.com/itning/Student-Homework-Management-System/archive/master.zip) 68 | 69 | 2. 使用编译器打开本项目 70 | 71 | 该项目使用IntelliJ IDEA编译器编写打包,建议同学们使用该编译器进行打开 72 | 73 | 项目使用JDK1.8进行编写,用到了JDK1.8+特性,所以最低JDK版本为1.8 74 | 75 | 3. 导入SQL文件 76 | 77 | 由于该项目不会自动建库建表,所以你需要手动导入SQL 78 | 79 | 更改JDBC连接信息(数据库名,用户名,密码) 80 | 81 | [context.properties](https://github.com/itning/Student-Homework-Management-System/blob/master/src/main/resources/context.properties) 82 | 83 | 其中 **user** 键为数据库的用户名 84 | 85 | 其中 **password** 键为数据库的密码 86 | 87 | 4. 更改上传文件存储目录 88 | 89 | 用户上传的文件需要持久化到硬盘上,你需要配置持久化目录 90 | 91 | [在这里配置](https://github.com/itning/Student-Homework-Management-System/blob/master/src/main/resources/context.properties#L8) 92 | 93 | 5. 安装QQ互联SDK 94 | 95 | 这一步是为了能够使用QQ进行登陆 96 | 97 | ~~[官方下载互联SDK](http://qzonestyle.gtimg.cn/qzone/vas/opensns/res/doc/qqConnect_Server_SDK_java_v2.0.zip)~~ 98 | 99 | **直接运行根目录下``install-qq-connect-dependency.bat``脚本即可** 100 | 101 | ```shell 102 | 直接运行install-qq-connect-dependency.bat即可,无需以下代码 103 | mvn install:install-file -Dfile=.jar -DgroupId=com.qq.connect -DartifactId=qq-connect -Dversion=2.0.0.RELEASE -Dpackaging=jar 104 | ``` 105 | 106 | 6. 运行 107 | 108 | ``` 109 | mvn install 110 | mvn package 111 | ``` 112 | 113 | 项目使用的Tomcat版本为8.5.20,你最好与我同步。[下载该版本](https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.20/bin/) 114 | 115 | 7. 查看Druid管理面板 116 | 117 | 默认用户名:``itning`` 118 | 119 | 默认密码:``kingston`` 120 | 121 | 页面:``http://localhost:8080/druid`` 122 | 123 | [如何更改用户名密码?](https://github.com/itning/Student-Homework-Management-System/blob/master/src/main/webapp/WEB-INF/web.xml#L84) 124 | 125 | ## SQL 126 | 127 | 1. 创建数据库 128 | 129 | ```sql 130 | CREATE DATABASE IF NOT EXISTS shw CHARACTER SET utf8mb4; 131 | USE shw; 132 | ``` 133 | 134 | 2. 导入表结构和数据 135 | 136 | ```sql 137 | SET FOREIGN_KEY_CHECKS=0; 138 | 139 | -- ---------------------------- 140 | -- Table structure for history 141 | -- ---------------------------- 142 | DROP TABLE IF EXISTS `history`; 143 | CREATE TABLE `history` ( 144 | `hid` varchar(255) NOT NULL, 145 | `huid` varchar(255) NOT NULL, 146 | `hoid` int(11) NOT NULL, 147 | `type` varchar(255) NOT NULL, 148 | `filepath` varchar(255) NOT NULL, 149 | `uptime` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, 150 | `filesize` double NOT NULL, 151 | PRIMARY KEY (`hid`), 152 | KEY `FK_hoid_oid` (`hoid`) USING BTREE, 153 | KEY `FK_huid_uid` (`huid`) USING BTREE, 154 | CONSTRAINT `history_ibfk_1` FOREIGN KEY (`hoid`) REFERENCES `orderinfo` (`oid`), 155 | CONSTRAINT `history_ibfk_2` FOREIGN KEY (`huid`) REFERENCES `user` (`uid`) 156 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 157 | 158 | -- ---------------------------- 159 | -- Table structure for orderinfo 160 | -- ---------------------------- 161 | DROP TABLE IF EXISTS `orderinfo`; 162 | CREATE TABLE `orderinfo` ( 163 | `oid` int(11) NOT NULL, 164 | `oname` varchar(255) NOT NULL, 165 | `osubject` varchar(255) NOT NULL, 166 | `ostate` bit(1) NOT NULL, 167 | `otime` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, 168 | `odeadline` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, 169 | PRIMARY KEY (`oid`) 170 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 171 | 172 | -- ---------------------------- 173 | -- Records of orderinfo 174 | -- ---------------------------- 175 | INSERT INTO `orderinfo` VALUES ('1492109980', '第二次作业', 'UI交互设计', 1, '2018-11-28 14:48:53'); 176 | INSERT INTO `orderinfo` VALUES ('795960272', '第二次作业', '软件测试', 1, '2018-11-28 14:38:11'); 177 | 178 | -- ---------------------------- 179 | -- Table structure for user 180 | -- ---------------------------- 181 | DROP TABLE IF EXISTS `user`; 182 | CREATE TABLE `user` ( 183 | `uid` varchar(255) NOT NULL, 184 | `username` varchar(255) NOT NULL, 185 | `password` varchar(255) NOT NULL, 186 | `headimg` varchar(255) DEFAULT NULL, 187 | `firstlogin` bit(1) NOT NULL DEFAULT b'1', 188 | `name` varchar(255) NOT NULL, 189 | `percode` varchar(255) NOT NULL, 190 | `userOpenID` varchar(255) DEFAULT NULL, 191 | PRIMARY KEY (`uid`) 192 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 193 | 194 | -- ---------------------------- 195 | -- Records of user 196 | -- ---------------------------- 197 | INSERT INTO `user` VALUES ('1', '000000000000', '0123456789', null, 1, '管理员', 'admin', null); 198 | INSERT INTO `user` VALUES ('2', '111111111111', '123456789', null, 1, '用户1', 'user', null); 199 | ``` 200 | 201 | ## 预览 202 | 203 | ![登陆](https://raw.githubusercontent.com/itning/Student-Homework-Management-System/master/pic/denglu.png) 204 | 205 | ![管理界面](https://raw.githubusercontent.com/itning/Student-Homework-Management-System/master/pic/guanli.png) 206 | 207 | ![上传界面](https://raw.githubusercontent.com/itning/Student-Homework-Management-System/master/pic/sahngchuan.png) 208 | 209 | ![添加课程](https://raw.githubusercontent.com/itning/Student-Homework-Management-System/master/pic/addkemu.png) 210 | 211 | ![druid](https://raw.githubusercontent.com/itning/Student-Homework-Management-System/master/pic/druid.png) 212 | -------------------------------------------------------------------------------- /src/main/java/com/ning/file/action/FileAction.java: -------------------------------------------------------------------------------- 1 | package com.ning.file.action; 2 | 3 | import com.ning.exception.file.FileException; 4 | import com.ning.exception.login.LoginException; 5 | import com.ning.file.entity.History; 6 | import com.ning.file.entity.OrderInfo; 7 | import com.ning.file.service.FileService; 8 | import com.ning.login.entity.User; 9 | import com.ning.login.service.UserService; 10 | import com.ning.util.properties.PropertiesUtil; 11 | import org.apache.commons.io.IOUtils; 12 | import org.apache.shiro.SecurityUtils; 13 | import org.aspectj.weaver.ast.Or; 14 | import org.springframework.beans.propertyeditors.CustomDateEditor; 15 | import org.springframework.stereotype.Controller; 16 | import org.springframework.ui.Model; 17 | import org.springframework.web.bind.WebDataBinder; 18 | import org.springframework.web.bind.annotation.*; 19 | import org.springframework.web.multipart.MultipartFile; 20 | 21 | import javax.annotation.Resource; 22 | import javax.servlet.http.HttpServletResponse; 23 | import javax.servlet.http.HttpSession; 24 | import java.io.*; 25 | import java.nio.charset.StandardCharsets; 26 | import java.text.SimpleDateFormat; 27 | import java.util.Date; 28 | import java.util.HashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | /** 33 | * 文件Action 34 | * 35 | * @author wangn 36 | * @date 2017/5/19 37 | */ 38 | @Controller 39 | public class FileAction { 40 | private static final String ADMIN = "admin"; 41 | private static final String FIRST_LOGIN_VALUE = "1"; 42 | private static final int MIN_PASSWORD_LENGTH = 8; 43 | 44 | @Resource 45 | private UserService userService; 46 | 47 | @Resource 48 | private FileService fileService; 49 | 50 | /** 51 | * 自定义类型转换器 52 | * 53 | * @param binder {@link WebDataBinder} 54 | * @throws Exception Exception 55 | */ 56 | @InitBinder 57 | public void initBinder(WebDataBinder binder) throws Exception { 58 | binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true)); 59 | } 60 | 61 | /** 62 | * 文件上传主页入口方法 63 | * 64 | * @param model {@link Model} 65 | * @return JSP页面 66 | */ 67 | @RequestMapping("fileupload") 68 | public String index(Model model) { 69 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 70 | if (user.getPercode().equals(ADMIN)) { 71 | return ADMIN; 72 | } 73 | boolean firstLogin = userService.isFirstLogin(user.getUid()); 74 | if (firstLogin) { 75 | return "jsp/firstpd.jsp"; 76 | } 77 | //用户上传历史实体 78 | List userHistoryList = fileService.getUserHistoryByUserId(user.getUid()); 79 | 80 | //Student浏览区数据 81 | // orderInfoList already filtered with state 82 | model.addAttribute("orderInfoStudentFullList", fileService.getOrderInfoFullEntity()); 83 | 84 | //下拉框数据 85 | model.addAttribute("orderInfoList", fileService.getOrderInfoEntity()); 86 | model.addAttribute("user", user); 87 | model.addAttribute("userHistoryList", userHistoryList); 88 | return "jsp/fileupload.jsp"; 89 | } 90 | 91 | /** 92 | * 更改密码方法 93 | * 94 | * @param model {@link Model} 95 | * @param password 新密码 96 | * @param firstlogin 如果是第一次登陆,该值为1 97 | * @param session {@link HttpSession} 98 | * @return JSP页面 99 | * @throws Exception Exception 100 | */ 101 | @RequestMapping(value = "changePassword", method = RequestMethod.POST) 102 | public String changePassword(Model model, String password, String firstlogin, HttpSession session) throws Exception { 103 | if (password == null || "".equals(password)) { 104 | throw new LoginException("修改密码失败:参数为空"); 105 | } 106 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 107 | 108 | // 条件判断 开始 109 | if (password.length() < MIN_PASSWORD_LENGTH) { 110 | model.addAttribute("user", user); 111 | model.addAttribute("errorinfo", "密码不能小于8位!"); 112 | if (FIRST_LOGIN_VALUE.equals(firstlogin)) { 113 | return "jsp/firstpd.jsp"; 114 | } 115 | return "jsp/cpasswd.jsp"; 116 | } 117 | String uid = user.getUid(); 118 | Map map = new HashMap<>(2); 119 | map.put("uid", uid); 120 | map.put("password", password); 121 | String passwdById = userService.getPasswdById(uid); 122 | if (passwdById.equals(password)) { 123 | model.addAttribute("errorinfo", "新密码不能和原密码相同,请重新输入!"); 124 | if (FIRST_LOGIN_VALUE.equals(firstlogin)) { 125 | return "jsp/firstpd.jsp"; 126 | } 127 | return "jsp/cpasswd.jsp"; 128 | } 129 | // 条件判断 结束 130 | 131 | userService.setUserPasswd(map); 132 | if (FIRST_LOGIN_VALUE.equals(firstlogin)) { 133 | Map isfirst = new HashMap<>(2); 134 | isfirst.put("uid", uid); 135 | isfirst.put("isfirst", false); 136 | userService.setFirstLogin(isfirst); 137 | session.removeAttribute("uid"); 138 | } 139 | return "fileupload"; 140 | } 141 | 142 | /** 143 | * 更改密码入口方法 144 | * 145 | * @param model {@link Model} 146 | * @return jsp/cpasswd.jsp 147 | */ 148 | @RequestMapping("cpasswd") 149 | public String cpasswd(Model model) { 150 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 151 | model.addAttribute("user", user); 152 | return "jsp/cpasswd.jsp"; 153 | } 154 | 155 | /** 156 | * 根据课程名查找所有课程作业信息 157 | * 158 | * @param subject 课程名 159 | * @return 课程作业信息集合 160 | * @throws Exception Exception 161 | */ 162 | @RequestMapping("getOnameBysubject") 163 | @ResponseBody 164 | public List getOnameBysubject(String subject) throws Exception { 165 | if (subject == null || "".equals(subject)) { 166 | throw new FileException("获取失败:参数错误"); 167 | } 168 | return fileService.getONameBySubject(subject); 169 | } 170 | 171 | /** 172 | * 文件上传方法 173 | * 174 | * @param file {@link MultipartFile} 175 | * @return index.jsp 176 | * @throws Exception Exception 177 | */ 178 | @RequestMapping("fileup") 179 | public String upfileByID(MultipartFile[] file) throws Exception { 180 | if (file == null) { 181 | throw new FileException("上传失败:未获取到上传内容!"); 182 | } 183 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 184 | for (MultipartFile file1 : file) { 185 | if (user.getUserSelectOid() != null && !(file1.isEmpty())) { 186 | fileService.uploadFile(file1, user); 187 | } 188 | } 189 | return "index.jsp"; 190 | } 191 | 192 | /** 193 | * 设置用户选择上传的课程ID 194 | * 195 | * @param userSelectOid 课程名称ID 196 | * @return 设置成功返回true 197 | */ 198 | @RequestMapping("userselect") 199 | @ResponseBody 200 | public boolean userSelect(@RequestParam("userselect_oid") Integer userSelectOid) { 201 | if (userSelectOid != null) { 202 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 203 | user.setUserSelectOid(userSelectOid); 204 | return user.getUserSelectOid() != null; 205 | } 206 | return false; 207 | } 208 | 209 | /** 210 | * 删除文件方法 211 | * 212 | * @param delHid 历史记录ID 213 | * @return 删除是否成功 214 | * @throws Exception Exception 215 | */ 216 | @RequestMapping("delEntityByHID") 217 | @ResponseBody 218 | public boolean delEntityByHID(String delHid) throws Exception { 219 | if (delHid == null || "".equals(delHid)) { 220 | throw new FileException("删除失败:参数为空"); 221 | } 222 | User user = (User) SecurityUtils.getSubject().getPrincipal(); 223 | return fileService.deleteFile(user, delHid); 224 | } 225 | 226 | /** 227 | * 下载作业 228 | * 229 | * @param hid 课程名称ID 230 | * @param response {@link HttpServletResponse} 231 | * @throws Exception Exception 232 | */ 233 | @RequestMapping("downFile") 234 | public void downLoadFile(String hid, HttpServletResponse response) throws Exception { 235 | if (hid == null || "".equals(hid)) { 236 | throw new FileException("下载失败:参数为空!"); 237 | } 238 | History history = fileService.getEntityByHID(hid); 239 | String filename = PropertiesUtil.getUpLoadFilePath() + history.getFilepath(); 240 | File file = new File(filename); 241 | response.setHeader("Accept-Ranges", "bytes"); 242 | response.setHeader("Content-Disposition", "attachment;filename=" + new String(history.getFilepath().getBytes(), StandardCharsets.ISO_8859_1)); 243 | response.setHeader("Content-Length", file.length() + ""); 244 | response.setContentType(history.getType()); 245 | try (OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); 246 | InputStream fis = new BufferedInputStream(new FileInputStream(file))) { 247 | IOUtils.copy(fis, toClient); 248 | toClient.flush(); 249 | } catch (Exception e) { 250 | if (!e.getMessage().contains("连接")) { 251 | throw e; 252 | } 253 | } 254 | } 255 | 256 | } -------------------------------------------------------------------------------- /src/main/java/com/ning/admin/action/AdminAction.java: -------------------------------------------------------------------------------- 1 | package com.ning.admin.action; 2 | 3 | import com.ning.admin.service.AdminService; 4 | import com.ning.exception.file.FileException; 5 | import com.ning.file.entity.History; 6 | import com.ning.file.entity.OrderInfo; 7 | import com.ning.file.service.FileService; 8 | import com.ning.util.properties.PropertiesUtil; 9 | import org.apache.commons.io.IOUtils; 10 | import org.apache.shiro.SecurityUtils; 11 | import org.apache.shiro.authz.annotation.RequiresPermissions; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.Model; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | 17 | import javax.annotation.Resource; 18 | import javax.servlet.http.HttpServletResponse; 19 | import javax.servlet.http.HttpSession; 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.InputStream; 23 | import java.nio.charset.StandardCharsets; 24 | import java.text.DateFormat; 25 | import java.text.SimpleDateFormat; 26 | import java.util.*; 27 | import java.util.zip.ZipEntry; 28 | import java.util.zip.ZipOutputStream; 29 | 30 | /** 31 | * 管理员Action 32 | * 33 | * @author wangn 34 | * @date 2017/5/23 35 | */ 36 | @Controller 37 | public class AdminAction { 38 | /** 39 | * 课程名称状态名 40 | */ 41 | private static final String O_STATE = "ostate"; 42 | 43 | @Resource 44 | private FileService fileService; 45 | 46 | @Resource 47 | private AdminService adminService; 48 | 49 | /** 50 | * 后台入口方法 51 | * 管理员权限访问 52 | * 53 | * @param model 模型 54 | * @return jsp/admin.jsp 55 | */ 56 | @RequestMapping("admin") 57 | @RequiresPermissions("admin") 58 | public String admin(Model model) { 59 | //下拉框数据 60 | model.addAttribute("orderInfoList", fileService.getOrderInfoEntityOfAll()); 61 | //登录用户信息实体(User) 62 | model.addAttribute("user", SecurityUtils.getSubject().getPrincipal()); 63 | return "jsp/admin.jsp"; 64 | } 65 | 66 | /** 67 | * 根据课程名查找所有课程信息 68 | * 69 | * @param subject 课程名 70 | * @return 所有课程信息集合 71 | * @throws Exception Exception 72 | */ 73 | @RequestMapping("getOnameBysubjectOfAll") 74 | public @ResponseBody 75 | List getOnameBysubjectOfAll(String subject) throws Exception { 76 | if (subject == null || "".equals(subject)) { 77 | throw new FileException("获取失败:参数错误"); 78 | } 79 | return fileService.getOnameBysubjectOfAll(subject); 80 | } 81 | 82 | /** 83 | * 后台入口方法 84 | * 管理员权限访问 85 | * 86 | * @param model 模型 87 | * @return jsp/subjectui.jsp 88 | */ 89 | @RequestMapping("subjectui") 90 | @RequiresPermissions("admin") 91 | public String subjectui(Model model) { 92 | //OrderInfo实体集合 93 | model.addAttribute("allOrderInfo", adminService.getOrderInfoEntity()); 94 | return "jsp/subjectui.jsp"; 95 | } 96 | 97 | /** 98 | * 获取已上传文件列表方法 99 | * 管理员权限访问 100 | * 101 | * @param hoid 作业名称ID 102 | * @param model 模型 103 | * @param session HttpSession 104 | * @return jsp/downfileui.jsp 105 | * @throws Exception Exception 106 | */ 107 | @RequestMapping("getFileList") 108 | @RequiresPermissions("admin") 109 | public String getFileList(Integer hoid, Model model, HttpSession session) throws Exception { 110 | if (hoid == null) { 111 | throw new FileException("参数错误:hoid为空!"); 112 | } 113 | //在Session中存储用户当前查看的文件列表 114 | session.setAttribute("hoid", hoid); 115 | List list = adminService.getAllUploadedByHoid(hoid); 116 | model.addAttribute("fileListByHoid", list); 117 | return "jsp/downfileui.jsp"; 118 | } 119 | 120 | /** 121 | * 下载所有已上传的文件 122 | * 该方法需要管理员权限 123 | * 124 | * @param response HttpServletResponse 125 | * @param session HttpSession 126 | * @throws Exception Exception 127 | */ 128 | @RequestMapping("downAllFile") 129 | @RequiresPermissions("admin") 130 | public void downAllFile(HttpServletResponse response, HttpSession session) throws Exception { 131 | //所有的已上传文件实体集合 132 | List fileListByHoid = adminService.findFileListByHoid((Integer) session.getAttribute("hoid")); 133 | if (fileListByHoid == null) { 134 | throw new FileException("下载失败:未找到数据!"); 135 | } 136 | OrderInfo orderInfo = fileService.getOrderInfoEntityByOID(fileListByHoid.get(0).getHoid()); 137 | 138 | String filteredOname = PropertiesUtil.filterOutUrl(orderInfo.getOname()); 139 | String zipfilename = orderInfo.getOsubject() + "_" + filteredOname; 140 | 141 | List filesname = new ArrayList<>(fileListByHoid.size()); 142 | for (History history : fileListByHoid) { 143 | filesname.add(history.getFilepath()); 144 | } 145 | response.setHeader("Content-Disposition", "attachment;filename=" + new String((zipfilename + ".zip").getBytes(), StandardCharsets.ISO_8859_1)); 146 | response.setContentType("application/octet-stream"); 147 | ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream()); 148 | for (String filename : filesname) { 149 | File file = new File(PropertiesUtil.getUpLoadFilePath() + filename); 150 | InputStream input = new FileInputStream(file); 151 | zipOut.putNextEntry(new ZipEntry(file.getName())); 152 | IOUtils.copy(input, zipOut); 153 | input.close(); 154 | } 155 | zipOut.close(); 156 | } 157 | 158 | // 更改截止时间 159 | 160 | @RequestMapping("updateDeadlineByOID") 161 | @RequiresPermissions("admin") 162 | public @ResponseBody 163 | Boolean updateDeadlineByOID(Integer oid, Date deadlineDate) throws Exception{ 164 | if (oid == null || deadlineDate == null){ 165 | throw new FileException("更改失败:参数不正确"); 166 | } 167 | 168 | Map map = new HashMap<>(2); 169 | map.put("odeadline", deadlineDate); 170 | map.put("oid", oid); 171 | 172 | adminService.updateDeadlineByOID(map); 173 | return true; 174 | } 175 | 176 | /** 177 | * 更改课程名称启用状态 178 | * 该方法需要管理员权限 179 | * 180 | * @param oid 课程名称ID 181 | * @param key key 182 | * @param value value 183 | * @return 更改是否成功 184 | * @throws Exception Exception 185 | */ 186 | @RequestMapping("changeKeyByOID") 187 | @RequiresPermissions("admin") 188 | public @ResponseBody 189 | Boolean changeKeyByOID(Integer oid, String key, String value) throws Exception { 190 | if (oid == null || key == null || "".equals(key) || value == null || "".equals(value)) { 191 | throw new FileException("更改失败:参数不正确"); 192 | } 193 | Map map = new HashMap<>(2); 194 | map.put("oid", oid); 195 | if (O_STATE.equals(key)) { 196 | map.put(key, Boolean.parseBoolean(value)); 197 | } else { 198 | map.put(key, value); 199 | } 200 | adminService.changeKeyByOID(map); 201 | return true; 202 | } 203 | 204 | 205 | @RequestMapping("updateOrderByOID") 206 | @RequiresPermissions("admin") 207 | public @ResponseBody 208 | Boolean updateOrderByOID(Integer oid, String osubject, String oname, String ostate, String odeadlinestr) throws Exception{ 209 | 210 | if (oid == null || 211 | osubject == null || "".equals(osubject) || 212 | oname == null || "".equals(oname) || 213 | ostate == null || "".equals(ostate) || 214 | odeadlinestr == null || "".equals(odeadlinestr)) { 215 | throw new FileException("更改失败:参数不正确"); 216 | } 217 | 218 | Map map = new HashMap<>(6); 219 | map.put("oid", oid); 220 | map.put("osubject", osubject); 221 | map.put("oname", oname); 222 | map.put("ostate", Boolean.parseBoolean(ostate)); 223 | map.put("otime", new Date()); 224 | 225 | map.put("odeadline", new Date(Long.parseLong(odeadlinestr) * 1000)); 226 | 227 | adminService.updateOrderByOID(map); 228 | return true; 229 | } 230 | 231 | /** 232 | * 根据名称ID删除名称 233 | * 该方法需要管理员权限 234 | * 235 | * @param oid 名称ID 236 | * @return ResponseBody 是否删除成功 237 | * @throws Exception Exception 238 | */ 239 | @RequestMapping("delOrderinfoByOID") 240 | @RequiresPermissions("admin") 241 | public @ResponseBody 242 | Boolean delOrderinfoByOID(Integer oid) throws Exception { 243 | if (oid == null) { 244 | throw new FileException("删除失败:参数不正确"); 245 | } 246 | adminService.delOrderInfosAndFilesByOID(oid); 247 | return true; 248 | } 249 | 250 | /** 251 | * 添加课程名称信息 252 | * 该方法需要管理员权限 253 | * 254 | * @param orderInfo 课程名称实体 255 | * @return 是否添加成功 256 | * @throws Exception Exception 257 | */ 258 | @RequestMapping("addOrderInfo") 259 | @RequiresPermissions("admin") 260 | public @ResponseBody 261 | Boolean addOrderInfo(OrderInfo orderInfo) throws Exception { 262 | if (orderInfo == null) { 263 | throw new FileException("添加失败:参数为空"); 264 | } 265 | if (orderInfo.getOsubject() == null || "".equals(orderInfo.getOsubject())) { 266 | return false; 267 | } 268 | if (orderInfo.getOname() == null) { 269 | return false; 270 | } 271 | if (orderInfo.getOstate() == null) { 272 | return false; 273 | } 274 | if (orderInfo.getOdeadlinestr() == null){ 275 | return false; 276 | } 277 | 278 | // here is problem, could get negative result because oname too long and causing overflow 279 | // this is fine for MySQL, should be fine for url encoding, change it is easy but maybe not necessary 280 | int oid = (orderInfo.getOname().hashCode()) + (orderInfo.getOsubject().hashCode()); 281 | 282 | orderInfo.setOid(oid); 283 | orderInfo.setOtime(new Date()); 284 | 285 | orderInfo.setOdeadlineFromStr(orderInfo.getOdeadlinestr()); 286 | adminService.addOrderInfo(orderInfo); 287 | return true; 288 | } 289 | } 290 | --------------------------------------------------------------------------------