• Java项目:SSM课堂听课记录管理系统


    作者主页:夜未央5788

     简介:Java领域优质创作者、Java项目、学习资料、技术互助

    文末获取源码

    项目介绍

    管理员:
    登录,修改个人资料,用户管理,公告管理,教室管理,科目管理,听课记录管理等功能。

    用户角色包含以下功能:
    用户登录,修改个人资料,查看公告,查看听课记录等功能。

    环境需要

    1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
    2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
    3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
    4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 

    5.数据库:MySql 5.7版本;

    技术栈

    1. 后端:Spring+SpringMVC+Mybatis

    2. 前端:HTML+CSS+JavaScript+jsp

    使用说明

    1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;
    2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行;
    3. 将项目中application.yml配置文件中的数据库配置改为自己的配置;

    4. 运行项目,http://localhost:8080/shop/index

    运行截图

     

     

     

     

     

     

     

     

    相关代码

    学生信息

    1. package com.taohan.online.exam.charts;
    2. import java.util.Map;
    3. import java.util.Set;
    4. import org.springframework.stereotype.Repository;
    5. import com.github.abel533.echarts.axis.CategoryAxis;
    6. import com.github.abel533.echarts.axis.ValueAxis;
    7. import com.github.abel533.echarts.code.Magic;
    8. import com.github.abel533.echarts.code.Tool;
    9. import com.github.abel533.echarts.code.Trigger;
    10. import com.github.abel533.echarts.code.X;
    11. import com.github.abel533.echarts.code.Y;
    12. import com.github.abel533.echarts.feature.MagicType;
    13. import com.github.abel533.echarts.json.GsonOption;
    14. import com.github.abel533.echarts.series.Line;
    15. import com.taohan.online.exam.po.ClassInfo;
    16. /**
    17. *
    18. *

      Title: StudentCount

    19. *

      Description: (年级下/所有)班级的学生总量 相关图表Json数据生成

    20. * @author: taohan
    21. * @date: 2018-9-17
    22. * @time: 下午7:03:13
    23. * @version: 1.0
    24. */
    25. @Repository
    26. public class StudentCount {
    27. /**
    28. * 班级对应学生人数折线图
    29. * @param data
    30. * @return
    31. */
    32. public static String createBarJson(Map data) {
    33. Set set = data.keySet();
    34. GsonOption option = new GsonOption();
    35. option.title().text("班级学生数量统计").x(X.center).y(Y.top).borderWidth(1).textStyle().color("#438EB9");
    36. option.toolbox().show(true).feature(Tool.mark, Tool.restore, new MagicType(Magic.bar, Magic.line), Tool.saveAsImage).x(X.right).y(Y.top);
    37. //数据默认触发, 鼠标移入显示竖线 trigger(Trigger.axis)
    38. option.tooltip().formatter("{b} {c}人").trigger(Trigger.axis);
    39. option.legend().data("班级总人数").x(X.center).y(Y.bottom).borderWidth(1);
    40. Line line = new Line("班级总人数");
    41. //值轴
    42. ValueAxis valueAxis = new ValueAxis();
    43. valueAxis.axisLabel().formatter("{value}人").textStyle().color("#438EB9");
    44. //valueAxis.min(0);
    45. option.yAxis(valueAxis);
    46. //类目轴
    47. CategoryAxis categoryAxis = new CategoryAxis();
    48. //interval(0):设置横轴信息全部显示
    49. //rotate(-30):设置 -30 度角倾斜显示
    50. categoryAxis.axisLabel().interval(0).rotate(-30).textStyle().color("#438EB9");
    51. for (String className : set) {
    52. categoryAxis.data(className);
    53. ClassInfo classInfo = (ClassInfo)data.get(className);
    54. line.data(classInfo.getClassId());
    55. }
    56. option.xAxis(categoryAxis);
    57. line.smooth(true);
    58. option.series(line);
    59. option.grid().x(100);
    60. System.out.println(option.toString());
    61. return option.toString();
    62. }
    63. }

    学生成绩

    1. package com.taohan.online.exam.charts;
    2. import java.util.List;
    3. import com.github.abel533.echarts.axis.CategoryAxis;
    4. import com.github.abel533.echarts.axis.ValueAxis;
    5. import com.github.abel533.echarts.code.Magic;
    6. import com.github.abel533.echarts.code.PointerType;
    7. import com.github.abel533.echarts.code.Tool;
    8. import com.github.abel533.echarts.code.Trigger;
    9. import com.github.abel533.echarts.code.X;
    10. import com.github.abel533.echarts.code.Y;
    11. import com.github.abel533.echarts.feature.MagicType;
    12. import com.github.abel533.echarts.json.GsonOption;
    13. import com.github.abel533.echarts.series.Bar;
    14. import com.github.abel533.echarts.series.Line;
    15. import com.taohan.online.exam.po.StudentExamInfo;
    16. /**
    17. *
    18. *

      Title: StudentExamInfoCharts

    19. *

      Description: 学生考试信息 图表 Json 数据 生成

    20. * @author: taohan
    21. * @date: 2018-9-19
    22. * @time: 上午10:26:55
    23. * @version: 1.0
    24. */
    25. public class StudentExamInfoCharts {
    26. public static String createExamCountBarJson(List examInfos) {
    27. GsonOption option = new GsonOption();
    28. option.title().text("学生考试次数统计").x(X.center).y(Y.top).borderWidth(1).textStyle().color("#438EB9");
    29. option.toolbox().show(true).feature(Tool.mark, Tool.restore, new MagicType(Magic.bar, Magic.line), Tool.saveAsImage).x(X.right).y(Y.top);
    30. option.tooltip().show(true).formatter("{b} {c}次");
    31. option.legend().data("学生考试次数统计").x(X.center).y(Y.bottom);
    32. Bar bar = new Bar();
    33. //值轴
    34. ValueAxis valueAxis = new ValueAxis();
    35. //设置y轴不出现小数值
    36. valueAxis.interval(1);
    37. valueAxis.axisLabel().formatter("{value} 次");
    38. option.yAxis(valueAxis);
    39. //类目轴
    40. CategoryAxis categoryAxis = new CategoryAxis();
    41. categoryAxis.axisLabel().interval(0);
    42. for (StudentExamInfo studentExamInfo : examInfos) {
    43. bar.data(studentExamInfo.getExamSum());
    44. categoryAxis.data(studentExamInfo.getStudentName());
    45. }
    46. bar.barCategoryGap("20");
    47. option.xAxis(categoryAxis);
    48. option.series(bar);
    49. return option.toString();
    50. }
    51. public static String createAvgCountLineJson(List examInfos) {
    52. GsonOption option = new GsonOption();
    53. option.title().text("学生考试平均成绩统计").x(X.center).y(Y.top).borderWidth(1).textStyle().color("#438EB9");
    54. option.toolbox().show(true).feature(Tool.mark, Tool.restore, new MagicType(Magic.bar, Magic.line), Tool.saveAsImage).x(X.right).y(Y.top);
    55. option.tooltip().show(true).trigger(Trigger.axis).axisPointer().type(PointerType.cross).crossStyle().color("#999");
    56. option.legend().data("考试次数", "平均分").x(X.center).y(Y.bottom);
    57. Line line = new Line("考试次数").smooth(true);
    58. Bar bar = new Bar("平均分");
    59. //值轴
    60. ValueAxis valueAxis = new ValueAxis();
    61. //设置y轴不出现小数值
    62. valueAxis.interval(1);
    63. valueAxis.axisLabel().formatter("{value} 次");
    64. //option.yAxis(valueAxis);
    65. ValueAxis valueAxis1 = new ValueAxis();
    66. valueAxis1.interval(1);
    67. valueAxis1.axisLabel().formatter("{value} 分");
    68. option.yAxis(valueAxis, valueAxis1);
    69. //类目轴
    70. CategoryAxis categoryAxis = new CategoryAxis();
    71. categoryAxis.axisLabel().interval(0);
    72. for (StudentExamInfo studentExamInfo : examInfos) {
    73. if (studentExamInfo.getAvgScore() != null || studentExamInfo.getExamSum() != 0) {
    74. bar.data(studentExamInfo.getAvgScore()/studentExamInfo.getExamSum());
    75. } else {
    76. bar.data("暂无记录");
    77. }
    78. line.data(studentExamInfo.getExamSum());
    79. categoryAxis.data(studentExamInfo.getStudentName());
    80. }
    81. //实现双 y 轴,使用 yAxisIndex() 指定应用到哪个 y 轴
    82. bar.barCategoryGap("20").yAxisIndex(1);
    83. option.xAxis(categoryAxis);
    84. option.series(bar, line);
    85. return option.toString();
    86. }
    87. public static String createStudentExamLineJson(List examInfos) {
    88. GsonOption option = new GsonOption();
    89. option.title().text("学生考试试卷得分统计").x(X.center).y(Y.top).borderWidth(1).textStyle().color("#438EB9");
    90. option.toolbox().show(true).feature(Tool.mark, Tool.restore, new MagicType(Magic.bar, Magic.line), Tool.saveAsImage).x(X.right).y(Y.top);
    91. option.tooltip().show(true).formatter("{b} {c}分").trigger(Trigger.axis);
    92. option.legend().data("得分").x(X.center).y(Y.bottom);
    93. Line line = new Line("试卷得分");
    94. //值轴
    95. ValueAxis valueAxis = new ValueAxis();
    96. //设置y轴不出现小数值
    97. valueAxis.interval(1);
    98. valueAxis.axisLabel().formatter("{value} 分");
    99. option.yAxis(valueAxis);
    100. //类目轴
    101. CategoryAxis categoryAxis = new CategoryAxis();
    102. categoryAxis.axisLabel().interval(0).rotate(-30);
    103. for (StudentExamInfo studentExamInfo : examInfos) {
    104. line.data(studentExamInfo.getExamScore());
    105. categoryAxis.data(studentExamInfo.getExamPaperName());
    106. }
    107. option.xAxis(categoryAxis);
    108. option.series(line);
    109. System.out.println(option.toString());
    110. return option.toString();
    111. }
    112. }

    试卷试题

    1. package com.taohan.online.exam.handler;
    2. import java.io.IOException;
    3. import java.util.ArrayList;
    4. import java.util.HashMap;
    5. import java.util.List;
    6. import java.util.Map;
    7. import java.util.Random;
    8. import javax.security.auth.Subject;
    9. import javax.servlet.http.HttpServletResponse;
    10. import javax.servlet.http.HttpSession;
    11. import org.apache.log4j.Logger;
    12. import org.springframework.beans.factory.annotation.Autowired;
    13. import org.springframework.context.annotation.Scope;
    14. import org.springframework.stereotype.Controller;
    15. import org.springframework.web.bind.annotation.RequestMapping;
    16. import org.springframework.web.bind.annotation.RequestMethod;
    17. import org.springframework.web.bind.annotation.RequestParam;
    18. import org.springframework.web.servlet.ModelAndView;
    19. import com.google.gson.Gson;
    20. import com.taohan.online.exam.po.CourseInfo;
    21. import com.taohan.online.exam.po.ExamPaperInfo;
    22. import com.taohan.online.exam.po.ExamSubjectMiddleInfo;
    23. import com.taohan.online.exam.po.GradeInfo;
    24. import com.taohan.online.exam.po.SubjectInfo;
    25. import com.taohan.online.exam.service.ExamPaperInfoService;
    26. import com.taohan.online.exam.service.ExamSubjectMiddleInfoService;
    27. import com.taohan.online.exam.service.SubjectInfoService;
    28. /**
    29. *
    30. *

      Title: ExamSubjectMiddleInfoHandler

    31. *

      Description: 试卷试题--关联

    32. * @author: taohan
    33. * @date: 2018-8-20
    34. * @time: 下午4:21:05
    35. * @version: 1.0
    36. */
    37. @Controller
    38. @Scope("prototype")
    39. @SuppressWarnings("all")
    40. public class ExamSubjectMiddleInfoHandler {
    41. @Autowired
    42. private ExamSubjectMiddleInfoService esmService;
    43. @Autowired
    44. private ExamPaperInfoService examPaperInfoService;
    45. @Autowired
    46. private SubjectInfoService subjectInfoService;
    47. @Autowired
    48. private ExamSubjectMiddleInfo esm;
    49. @Autowired
    50. private ExamPaperInfo examPaper;
    51. @Autowired
    52. private SubjectInfo subject;
    53. @Autowired
    54. private CourseInfo course;
    55. @Autowired
    56. private GradeInfo grade;
    57. @Autowired
    58. private Gson gson;
    59. private Logger logger = Logger.getLogger(ExamSubjectMiddleInfoHandler.class);
    60. /**
    61. * 查询试卷-试题信息
    62. * 根据多条件查询
    63. * @param examPaperId 试卷编号
    64. * @param courseName 科目名称
    65. * @param courseId 科目百年好
    66. * @param gradeId 年级编号
    67. * @param response
    68. * @throws IOException
    69. */
    70. @RequestMapping(value="/getESM", method={RequestMethod.GET, RequestMethod.POST})
    71. public void getExamPaperWithSubject(
    72. @RequestParam(value="examPaperId", required=false) Integer examPaperId,
    73. @RequestParam(value="courseName", required=false) String courseName,
    74. @RequestParam(value="courseId", required=false) Integer courseId,
    75. @RequestParam(value="gradeId", required=false) Integer gradeId,
    76. HttpServletResponse response) throws IOException {
    77. ModelAndView model = new ModelAndView();
    78. /*条件处理*/
    79. if (examPaperId != null) examPaper.setExamPaperId(examPaperId);
    80. if (courseName != null) course.setCourseName(courseName);
    81. if (courseId != null) course.setCourseId(courseId);
    82. if (gradeId != null) grade.setGradeId(gradeId);
    83. subject.setCourse(course);
    84. subject.setGrade(grade);
    85. esm.setExamPaper(examPaper);
    86. esm.setSubject(subject);
    87. logger.info("查询试卷试题信息 With "+esm);
    88. List esms = esmService.getExamPaperWithSubject(esm);
    89. response.getWriter().print(gson.toJson(esms));
    90. }
    91. /**
    92. * 手动添加试题
    93. * 手动将选择的试题添加到指定试卷中 -- 正式添加处理
    94. * @param examPaperId 试卷编号
    95. * @param session
    96. * @param response
    97. * @throws Exception
    98. */
    99. @RequestMapping(value="/handAdd", method={RequestMethod.GET, RequestMethod.POST})
    100. public void isHandAddSubjectToExamPaper(
    101. @RequestParam(value="examPaperId") Integer examPaperId,
    102. HttpSession session,
    103. HttpServletResponse response) throws Exception {
    104. //添加试题总分统计
    105. int scoreSum = 0;
    106. //添加试题总量统计
    107. int subjectSum = 0;
    108. Map map = new HashMap();
    109. map.put("examPaperId", examPaperId);
    110. ArrayList subjectIds = new ArrayList();
    111. //试题信息
    112. List ids = (List) session.getAttribute("ids");
    113. if (ids != null) {
    114. for (String is : ids) {
    115. //分割试题编号和分数
    116. String[] idAndScore = is.split(",");
    117. subjectIds.add(Integer.parseInt(idAndScore[0]));
    118. //累加试题分数
    119. scoreSum += Integer.parseInt(idAndScore[1]);
    120. //累加试题数量
    121. subjectSum += 1;
    122. }
    123. /** 需要添加试题集合 */
    124. map.put("subjectIds", subjectIds);
    125. } else {
    126. logger.error("试题集合为空,不能进行添加试题操作!");
    127. response.getWriter().print("需要添加的试题为空,操作失败!");
    128. return;
    129. }
    130. logger.info("添加试题集合到试卷 "+examPaperId);
    131. //总分和题目数量信息
    132. Map scoreWithNum = new HashMap();
    133. scoreWithNum.put("subjectNum", subjectSum);
    134. scoreWithNum.put("score", scoreSum);
    135. scoreWithNum.put("examPaperId", examPaperId);
    136. /** 修改试卷总分 */
    137. examPaperInfoService.isUpdateExamPaperScore(scoreWithNum);
    138. /** 修改试卷试题总量 */
    139. examPaperInfoService.isUpdateExamPaperSubjects(scoreWithNum);
    140. /** 添加试题到试卷中 */
    141. esmService.isAddESM(map);
    142. response.getWriter().print("试题已成功添加到试卷中!");
    143. }
    144. /**
    145. * 手动添加试题到试卷时 向 Session中存入试题信息
    146. * @param subjectId 试题编号
    147. * @param examPaperId 试卷编号
    148. * @param score 试题分数
    149. * @param handle 操作标识, 自动 OR 手动
    150. * @param session
    151. * @param response
    152. * @throws IOException
    153. */
    154. @RequestMapping("/getChooseSubId")
    155. public void getChooseSubjectId(
    156. @RequestParam("subjectId") Integer subjectId,
    157. @RequestParam("examPaperId") Integer examPaperId,
    158. @RequestParam("score") Integer score,
    159. @RequestParam(value="handle", required=false) Integer handle,
    160. HttpSession session, HttpServletResponse response) throws IOException {
    161. List ids = null;
    162. /*
    163. * 添加到 Session 中需先判断该试题是否已经存在该试卷中
    164. * 如果存在,则不进行添加;反之添加
    165. */
    166. examPaper.setExamPaperId(examPaperId);
    167. subject.setSubjectId(subjectId);
    168. esm.setExamPaper(examPaper);
    169. esm.setSubject(subject);
    170. /** 验证添加记录 是否已经存在 */
    171. Integer esmId = esmService.getEsmByExamIdWithSubjectId(esm);
    172. if (esmId == null) {
    173. logger.error("需要添加的试题 "+subjectId+" 暂不存在试卷 "+examPaperId+" 中,可进行添加");
    174. ids = (List) session.getAttribute("ids");
    175. /** Session 记录非空验证 */
    176. if (subjectId != null && score != null) {
    177. //第一次添加
    178. if (ids == null) {
    179. ids = new ArrayList();
    180. ids.add((subjectId+","+score));
    181. logger.info("Session 添加试题:是否手动"+handle+", 试题编号:"+subjectId+", 试题分数"+score);
    182. } else {
    183. //存在就移除,反之添加
    184. if (ids.contains((subjectId+","+score))) {
    185. ids.remove((subjectId+","+score));
    186. logger.info("Session 移除试题:是否手动"+handle+", 试题编号:"+subjectId+", 试题分数"+score);
    187. } else {
    188. ids.add((subjectId+","+score));
    189. logger.info("Session 添加试题:是否手动"+handle+", 试题编号:"+subjectId+", 试题分数"+score);
    190. }
    191. }
    192. } else {
    193. logger.error("添加试题 "+subjectId+" 到 Session 失败");
    194. response.getWriter().print("添加失败,试题编号或试题分数异常!");
    195. return;
    196. }
    197. } else {
    198. logger.error("需要添加的试题 "+subjectId+" 已经存在试卷 "+examPaperId+" 中了, 无法进行添加");
    199. //同时返回添加失败的题号,用于前台方便移除选中
    200. response.getWriter().print("f-exists-"+subjectId);
    201. return;
    202. }
    203. session.setAttribute("ids", ids);
    204. response.getWriter().print("编号为 "+subjectId+" 的试题添加成功");
    205. }
    206. /**
    207. * 清空Session中保存的试题编号集合
    208. * @param session
    209. * @return
    210. */
    211. @RequestMapping("/clearSubjectIdsWithSession")
    212. public String isClearChooseSubjectIds(HttpSession session) {
    213. logger.info("清空 Session 中需要添加的试题编号集合");
    214. session.removeAttribute("ids");
    215. return "redirect:examPapers";
    216. }
    217. /**
    218. * 从试卷中移除试题
    219. * @param subjectId 试题编号
    220. * @param examPaperId 试卷百年好
    221. * @param score 试题分数
    222. * @param response
    223. * @throws IOException
    224. */
    225. @RequestMapping(value="/removeSubjectFromPaper", method={RequestMethod.GET, RequestMethod.POST})
    226. public void removeSubjectWithExamPaper(
    227. @RequestParam("subjectId") Integer subjectId,
    228. @RequestParam("examPaperId") Integer examPaperId,
    229. @RequestParam("score") Integer score,
    230. HttpServletResponse response) throws IOException {
    231. logger.info("从试卷 "+examPaperId+" 中移除试题 "+subjectId+",试题分值:"+score);
    232. Map map = new HashMap();
    233. map.put("subjectNum", (-1));
    234. map.put("score", (-score));
    235. map.put("examPaperId", examPaperId);
    236. map.put("subjectId", subjectId);
    237. //修改试卷总分
    238. examPaperInfoService.isUpdateExamPaperScore(map);
    239. //修改试卷题目数量
    240. examPaperInfoService.isUpdateExamPaperSubjects(map);
    241. //从试卷中移除试题
    242. esmService.removeSubjectWithExamPaper(map);
    243. response.getWriter().print("t");
    244. }
    245. /**
    246. * 自动生成试题到试卷
    247. * @param examPaperId 试卷编号
    248. * @param subjectEasy 试题难易程度
    249. * @param courseId 科目编号
    250. * @param gradeId 年级编号
    251. * @param subjectSum 生成试题数量
    252. * @param response
    253. * @throws IOException
    254. */
    255. @RequestMapping("/autoAddSubject")
    256. public void isAutoAddSubjectToExamPaper(
    257. @RequestParam(value="examPaperId") Integer examPaperId,
    258. @RequestParam(value="subjectEasy", required=false) Integer subjectEasy,
    259. @RequestParam(value="courseId", required=false) Integer courseId,
    260. @RequestParam(value="gradeId", required=false) Integer gradeId,
    261. @RequestParam("subjectSum") Integer subjectSum,
    262. HttpServletResponse response) throws IOException {
    263. Random random = new Random();
    264. /*生成条件处理*/
    265. if (subjectEasy != null) {
    266. subject.setSubjectEasy(subjectEasy);
    267. }
    268. if (courseId != null) {
    269. course.setCourseId(courseId);
    270. subject.setCourse(course);
    271. }
    272. if (gradeId != null) {
    273. grade.setGradeId(gradeId);
    274. subject.setGrade(grade);
    275. }
    276. Map map = new HashMap();
    277. map.put("subject", subject);
    278. map.put("startIndex", null);
    279. map.put("pageShow", null);
    280. List subjects = subjectInfoService.getSubjects(map);
    281. int subjectTotal = subjects.size()-1;
    282. Map addMap = new HashMap();
    283. ArrayList indexs = new ArrayList();
    284. ArrayList subjectIds = new ArrayList();
    285. //添加试题总分
    286. int score = 0;
    287. for (int i=0; i
    288. //产生随机索引
    289. int index = random.nextInt(subjectTotal);
    290. if (indexs.contains(index)) { //随机索引已经存在
    291. i--;
    292. continue;
    293. } else {
    294. indexs.add(index);
    295. int subjectId = subjects.get(index).getSubjectId();
    296. subjectIds.add(subjectId);
    297. score += subjects.get(index).getSubjectScore();
    298. logger.info("索引 "+index+" 试题编号 "+subjectId+" 成立");
    299. }
    300. }
    301. //添加试题信息
    302. addMap.put("examPaperId", examPaperId);
    303. addMap.put("subjectIds", subjectIds);
    304. //总分和题目数量信息
    305. Map scoreWithNum = new HashMap();
    306. scoreWithNum.put("subjectNum", subjectSum);
    307. scoreWithNum.put("score", score);
    308. scoreWithNum.put("examPaperId", examPaperId);
    309. //修改试卷总分
    310. examPaperInfoService.isUpdateExamPaperScore(scoreWithNum);
    311. //修改试卷题目数量
    312. examPaperInfoService.isUpdateExamPaperSubjects(scoreWithNum);
    313. //添加
    314. logger.info("添加试题到试卷 "+examPaperId);
    315. esmService.isAddESM(addMap);
    316. response.getWriter().print("t");
    317. }
    318. }

    如果也想学习本系统,下面领取。回复:196ssm

  • 相关阅读:
    WEB漏洞-文件操作之文件包含漏洞
    python的几种数据类型的花样玩法(三)
    低代码如何构建支持OAuth2.0的后端Web API
    COMSOL空气反应 模型框架
    ReactNative安卓首屏白屏优化
    一题详解差分约束
    C++ Reference: Standard C++ Library reference: C Library: cctype: isalnum
    Android 13.0 自定义仿小米全面屏手势导航左右手势滑动返回UI效果
    软件测试技术之如何编写测试用例(6)
    Java多线程详解
  • 原文地址:https://blog.csdn.net/hanyunlong1989/article/details/126339620