项目演示
学生端:
登录:
学生主界面
家长登录
家长主页面
视频演示(前端效果很惊艳)
100以内学生家长端视频演示
项目介绍
1使用技术和代码包
前端使用html+css+javaScript
后端使用SSM
数据库 mysql
网关层 nginx(反向代理)
after_demo1:后端代码,个人的数据库信息需要在里面的.yml里面修改
\ArithmeticDemo1\nginx-1.20.2\html\login:login包是前端包,只不过我把它配置在了nginx里面
mysql里面是五个表,直接导入
项目全路径不能包含中文路径,否则,nginx启动失败
2项目定位
本项目就是为了满足二年级一下阶段小学生100以内的算式计算,并且家长可以查看自家孩子的做题记录,以及家长发布试题,
3项目内容及技术实现
3.1学生界面
登录—>主界面,主界面包含功能:+,-,*,/,混合试题,考试,退出登录,夜间模式
登录界面使用jwt进行前后端验证,以后端生成令牌的方式传送到前端,这样的作用是用户只有登录后才可以使用,而不是通过复制主界面网址直接跳转使用,
+,-,*,/,混合试题,
每个都是当用户点击后从后端请求返回100道对应的试题,例如当用户点击+时,前端的请求体内会带有对应的请求类型,当后端Controller层接收后,后调用Service层进行功能实现,service层会根据请求的算式类型,调用Utils组件里的算式生成方法,这个方法返回的是两个hashmap类型,一个hashmap存放的是例如1+1的算式,另一个hashmap存放的是这个算式对应的结果,算式和结果之间使用相同的key值联系,
除法混合实现逻辑举例
因为这是个前后端项目,所以在处理除法时,直接调用乘法实现,把乘法的结果当作被除数,把乘法的两个乘数分别当作除法算式的除数和结果,这样保证了一道算式的三个数都在1-100之间而且没有余数问题,即避开了整除问题
混合试题的生成就是随机调用+,-,*,/的方法
学生只要提交试题或练习,都会在界面显示正确率等信息,这些信息会保存到数据库,以便家长查询
学生考试
当用户点击考试后,前端会在请求体中加入当前学生姓名返回给后端,后端通过访问数据库,里面的试题库这个表,查询到对应的家长所发布的试题,这样前端返回的是家长发布的多套试卷,当用户选择其中一套试卷后,跳转考试界面,开始计时考试,在考试界面有导出为pdf功能和打印功能,
退出登录
当用户点击退出按钮后,系统会删除该用户的jwt令牌,之后跳转道登录界面
3.2家长界面
登录,欢迎页,孩子情况,对系统建议,退出
家长登录
登录,欢迎页,退出实现同上;
查看对应孩子答题信息
孩子情况界面,会从后端请求到对应的孩子信息,做题记录,时间,还可以通过折线统计图查看孩子正确率走势
建议界面
家长通过填写联系方式和建议信息从而向开发者提出建议
4数据库
各个数据库之间通过外键添加从而联系,除此之外用户的密码信息通过MD5加密后存入数据库
部分代码
添加微信 ershiqijian 获取源码
package com.arithmetic.controller.student_admin;
import com.arithmetic.result.EquationResult;
import com.arithmetic.result.PageResult;
import com.arithmetic.result.Result;
import com.arithmetic.service.studentService.GeneratePracticeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/student/Practice")
@Slf4j
public class GeneratePracticeController {
@Autowired
private GeneratePracticeService generatePracticeService;
//TODO:这里需要将参数100通过yml文件引入
int number=100;//生成题目数量
@GetMapping("/addition")
public Result<EquationResult> generateAddition() {
log.info("生成加法练习");
EquationResult equationResult = generatePracticeService.pageAddition(number);
return Result.success(equationResult);
}
@GetMapping("/subtraction")
public Result<EquationResult> generateSubtraction() {
log.info("生成减法练习,");
EquationResult equationResult = generatePracticeService.pageSubtraction(number);
return Result.success(equationResult);
}
@RequestMapping("/multiplication")
public Result<EquationResult> generateMultiplication() {
log.info("生成乘法练习,");
EquationResult equationResult = generatePracticeService.pageMultiplication(number);
return Result.success(equationResult);
}
@RequestMapping("/division")
public Result<EquationResult> generateDivision() {
log.info("生成除法练习,");
EquationResult equationResult = generatePracticeService.pageDivision(number);
return Result.success(equationResult);
}
@RequestMapping("/mix")
public Result<EquationResult> generateMix() {
log.info("生成混合练习,");
EquationResult equationResult = generatePracticeService.pageMix(number);
return Result.success(equationResult);
}
}
package com.arithmetic.service.studentService;
import com.arithmetic.result.EquationResult;
public interface GeneratePracticeService {
EquationResult pageAddition(int number);
EquationResult pageSubtraction(int number);
EquationResult pageMultiplication(int number);
EquationResult pageDivision(int number);
EquationResult pageMix(int number);
}
...
package com.arithmetic.service.studentService.impl;
import com.arithmetic.properties.EquationProperties;
import com.arithmetic.result.EquationResult;
import com.arithmetic.service.studentService.GeneratePracticeService;
import com.arithmetic.utils.EquationConstructionUtil;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Random;
@Service
public class GeneratePracticeServiceImpl implements GeneratePracticeService {
HashMap<Integer,String> hashMap1=new HashMap();
HashMap<Integer,Integer> hashMap2=new HashMap<>();
EquationConstructionUtil equationConstructionUtil=new EquationConstructionUtil();
public EquationResult pageAddition(int number) {
while(number>0) {
EquationProperties equationProperties = equationConstructionUtil.generationEquation("+");
hashMap1.put(number, equationProperties.getSuanshi());
hashMap2.put(number, equationProperties.getJieguo());
number--;
}
return new EquationResult(hashMap1,hashMap2);
}
public EquationResult pageSubtraction(int number) {
while(number>0) {
EquationProperties equationProperties = equationConstructionUtil.generationEquation("-");
hashMap1.put(number, equationProperties.getSuanshi());
hashMap2.put(number, equationProperties.getJieguo());
number--;
}
return new EquationResult(hashMap1,hashMap2);
}
public EquationResult pageMultiplication(int number) {
while(number>0) {
EquationProperties equationProperties = equationConstructionUtil.generationEquation("*");
hashMap1.put(number, equationProperties.getSuanshi());
hashMap2.put(number, equationProperties.getJieguo());
number--;
}
return new EquationResult(hashMap1,hashMap2);
}
public EquationResult pageDivision(int number) {
while(number>0) {
EquationProperties equationProperties = equationConstructionUtil.generationEquation("/");
hashMap1.put(number, equationProperties.getSuanshi());
hashMap2.put(number, equationProperties.getJieguo());
number--;
}
return new EquationResult(hashMap1,hashMap2);
}
public EquationResult pageMix(int number) {
while(number>0) {
EquationProperties equationProperties = equationConstructionUtil.generationEquation("mix");
hashMap1.put(number, equationProperties.getSuanshi());
hashMap2.put(number, equationProperties.getJieguo());
number--;
}
return new EquationResult(hashMap1,hashMap2);
}
}
...
package com.arithmetic.interceptor;
import com.arithmetic.constant.JwtClaimsConstant;
import com.arithmetic.context.BaseContext;
import com.arithmetic.properties.JwtProperties;
import com.arithmetic.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* jwt令牌校验的拦截器
*/
@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {
@Autowired
private JwtProperties jwtProperties;
/**
* 校验jwt
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
//1、从请求头中获取令牌
String token = request.getHeader(jwtProperties.getAdminTokenName());
//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
Long stuId = Long.valueOf(claims.get(JwtClaimsConstant.Student_ID).toString());
log.info("当前id:", stuId);
// 将用户id存储到ThreadLocal
BaseContext.setCurrentId(stuId);
//3、通过,放行
return true;
} catch (Exception ex) {
//4、不通过,响应401状态码
response.setStatus(401);
return false;
}
}
}
...
package com.arithmetic.service.studentService.impl;
import com.alibaba.fastjson.JSONObject;
import com.arithmetic.dto.StudentTestDTO;
import com.arithmetic.entity.StudentTest;
import com.arithmetic.mapper.studentMapper.StudentTestMapper;
import com.arithmetic.service.studentService.GetTestService;
import com.arithmetic.utils.JacksonToHashMap;
import com.arithmetic.vo.StudentTestVO;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static com.arithmetic.utils.JacksonToHashMap.jsonToHashMap;
@Service
public class GetTestServiceImpl implements GetTestService {
@Autowired
StudentTestMapper studentTestMapper;
public List<StudentTestVO> getTest(StudentTestDTO studentTestDTO) {
List<StudentTest> studentTests =studentTestMapper.getTest(studentTestDTO);
List<StudentTestVO> studentTestVOS = new ArrayList<>();
for(int i=0;i<studentTests.size();i++){
//获取每行数据
String question= studentTests.get(i).getQuestion();
String answer=studentTests.get(i).getAnswer();
//String 转hashmap
// HashMap<Integer,String> map1 = jsonToHashMap(question);
// HashMap<Integer,Integer> map2 = jsonToHashMap(answer);
HashMap<Integer, String> map1 = JacksonToHashMap.jsonToHashMap(question, new TypeReference<HashMap<Integer, String>>() {});
HashMap<Integer, Integer> map2 = JacksonToHashMap.jsonToHashMap(answer, new TypeReference<HashMap<Integer, Integer>>() {});
//放入StudentTestVO
StudentTestVO studentTestVO = StudentTestVO.builder()
.question(map1)
.answer(map2)
.build();
//这里把处理好的数据放入
studentTestVOS.add(studentTestVO);
}
return studentTestVOS;
}
}
最后
需要交流学习,获取项目,微信联系方式 ershiqijian