From 4f5deeebb24531630965e4cff402c341668362db Mon Sep 17 00:00:00 2001 From: whb <17803890193@163.com> Date: Fri, 9 Aug 2024 16:21:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=99=E5=B8=88=E7=AB=AF=E7=AD=BE=E5=88=B0?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sztzjy/trade/config/Constant.java | 8 + .../controller/stu/StuSignInfoController.java | 64 +++ .../controller/tch/TchSignInfoController.java | 74 +++- .../com/sztzjy/trade/entity/IpAddress.java | 117 ++++++ .../TeacherOpenCourseStudentSigninLog.java | 14 +- ...cherOpenCourseStudentSigninLogExample.java | 30 +- .../sztzjy/trade/entity/dto/StuSignDTO.java | 45 +++ .../entity/dto/StudentSigninSettingDTO.java | 27 ++ .../trade/entity/dto/TchEndSignDTO.java | 18 + .../trade/entity/dto/TchManualSignDTO.java | 55 +++ .../entity/dto/TchManualSignSettingDTO.java | 43 ++ .../trade/entity/dto/TchManualSignVo.java | 25 ++ .../trade/entity/dto/TchSignInfoDTO.java | 31 ++ .../entity/dto/TchUpdateManualSignDTO.java | 32 ++ ...cherOpenCourseStudentSigninSettingDTO.java | 14 +- .../entity/dto/TeacherSigninSettingDTO.java | 69 ++++ .../trade/service/StuSignInfoService.java | 33 ++ ...TeacherOpenCourseStudentSigninService.java | 47 +++ .../service/impl/StuSignInfoServiceImpl.java | 231 +++++++++++ .../impl/TchHomeworkExamServiceImpl.java | 3 +- ...herOpenCourseStudentSigninServiceImpl.java | 368 +++++++++++++++++- .../java/com/sztzjy/trade/util/IpUtils.java | 178 +++++++++ ...eacherOpenCourseStudentSigninLogMapper.xml | 14 +- src/test/java/com/sztzjy/Tset.java | 22 ++ 24 files changed, 1527 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/sztzjy/trade/controller/stu/StuSignInfoController.java create mode 100644 src/main/java/com/sztzjy/trade/entity/IpAddress.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/StuSignDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/StudentSigninSettingDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TchEndSignDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TchManualSignDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TchManualSignSettingDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TchManualSignVo.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TchSignInfoDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TchUpdateManualSignDTO.java create mode 100644 src/main/java/com/sztzjy/trade/entity/dto/TeacherSigninSettingDTO.java create mode 100644 src/main/java/com/sztzjy/trade/service/StuSignInfoService.java create mode 100644 src/main/java/com/sztzjy/trade/service/impl/StuSignInfoServiceImpl.java create mode 100644 src/main/java/com/sztzjy/trade/util/IpUtils.java create mode 100644 src/test/java/com/sztzjy/Tset.java diff --git a/src/main/java/com/sztzjy/trade/config/Constant.java b/src/main/java/com/sztzjy/trade/config/Constant.java index 8516bd9..a2a876d 100644 --- a/src/main/java/com/sztzjy/trade/config/Constant.java +++ b/src/main/java/com/sztzjy/trade/config/Constant.java @@ -18,4 +18,12 @@ public class Constant { + + public static final String CODE = "code"; + public static final String IP = "ip"; + public static final String END = "END"; + public static final String READY = "READY"; + + + public static final String MANUAL = "manual"; } diff --git a/src/main/java/com/sztzjy/trade/controller/stu/StuSignInfoController.java b/src/main/java/com/sztzjy/trade/controller/stu/StuSignInfoController.java new file mode 100644 index 0000000..8416400 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/controller/stu/StuSignInfoController.java @@ -0,0 +1,64 @@ +package com.sztzjy.trade.controller.stu; + +import com.sztzjy.trade.annotation.AnonymousAccess; +import com.sztzjy.trade.entity.dto.StuSignDTO; +import com.sztzjy.trade.service.StuSignInfoService; +import com.sztzjy.trade.util.ResultEntity; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.checkerframework.checker.units.qual.A; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * @author 17803 + * @date 2024-08-08 10:20 + */ + +@RequestMapping("api/stu/signInfo") +@RestController +@Api(tags = "学生签到") +public class StuSignInfoController { + + @Autowired + private StuSignInfoService service; + + + //查询所有签到信息 根据课程ID,班级id,分页展示 + @GetMapping("/getSignInfoByUserId") + @ApiOperation("课程内查询用户所有签到信息") + @AnonymousAccess + public ResultEntity getSignInfoByUserId(String userId, @ApiParam("课程ID") Long courseId, String classId, Integer size, Integer page){ + + + return service.getSignInfoByUserId(userId,courseId,classId,size,page); + } + + +// 三种方式: + //根据IP, 需要request + // 根据code,需要code + // 手动签到 不用自己操作,抽到自己老师给点是否签到,没抽到自动添加签到记录表中 + + @PostMapping("sign") + @ApiOperation("用户签到操作") + @AnonymousAccess + public ResultEntity sign(HttpServletRequest request + , @RequestBody @Valid StuSignDTO stuSignDTO ){ + + + return service.sign(stuSignDTO,request); + + } + + + + + + + +} diff --git a/src/main/java/com/sztzjy/trade/controller/tch/TchSignInfoController.java b/src/main/java/com/sztzjy/trade/controller/tch/TchSignInfoController.java index dc7b811..e14a66d 100644 --- a/src/main/java/com/sztzjy/trade/controller/tch/TchSignInfoController.java +++ b/src/main/java/com/sztzjy/trade/controller/tch/TchSignInfoController.java @@ -1,18 +1,17 @@ package com.sztzjy.trade.controller.tch; import com.sztzjy.trade.annotation.AnonymousAccess; +import com.sztzjy.trade.entity.dto.TchEndSignDTO; +import com.sztzjy.trade.entity.dto.TchManualSignDTO; import com.sztzjy.trade.entity.dto.TeacherOpenCourseStudentSigninSettingDTO; import com.sztzjy.trade.service.TeacherOpenCourseStudentSigninService; import com.sztzjy.trade.util.ResultEntity; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.BindingResult; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -38,7 +37,7 @@ public class TchSignInfoController { * @param teacherOpenCourseStudentSigninSettingDTO * @return */ - @PostMapping("/add.do") + @PostMapping("/add") @ApiOperation("教师端-发起签到(统一签到接口,根据类型验证)") @AnonymousAccess public ResultEntity addDo(@Valid @RequestBody TeacherOpenCourseStudentSigninSettingDTO teacherOpenCourseStudentSigninSettingDTO){ @@ -48,6 +47,67 @@ public class TchSignInfoController { } return teacherOpenCourseStudentSigninService.addDo(teacherOpenCourseStudentSigninSettingDTO); } + + + @PostMapping("/openStartState") + @ApiOperation("教师端开始签到") + @AnonymousAccess + public ResultEntity openStartState(Long teacherOpenCourseStudentSigninSettingId){ + + + return teacherOpenCourseStudentSigninService.openStartState(teacherOpenCourseStudentSigninSettingId); + } + + + + + @PostMapping("/endSign") + @ApiOperation("教师端结束签到") + @AnonymousAccess + public ResultEntity endSign(@RequestBody + TchEndSignDTO tchEndSignDTO){ + + + return teacherOpenCourseStudentSigninService.endSign(tchEndSignDTO); } + + @PostMapping("/manualSignByRandom") + @ApiOperation("手动签到随机抽取") + @AnonymousAccess + public ResultEntity manualSignByRandom(@RequestBody @Valid + @ApiParam("只传参:classIds") TchManualSignDTO tchManualSignDTO){ + + + return teacherOpenCourseStudentSigninService.manualSignByRandom(tchManualSignDTO); + } + + + + @PostMapping("/manualSignSure") + @ApiOperation("手动签到确认按钮") + @AnonymousAccess + @Transactional + public ResultEntity manualSignSure(@RequestBody @Valid + TchManualSignDTO tchManualSignDTO){ + + + return teacherOpenCourseStudentSigninService.manualSignSure(tchManualSignDTO); + } + + + + //查询所有签到信息 根据课程ID,班级id,分页展示 + @GetMapping("/getSignInfoByTeacher") + @ApiOperation("课程内查询签到信息") + @AnonymousAccess + public ResultEntity getSignInfoByTeacher(@ApiParam("课程ID") Long courseId, @ApiParam("学校ID") Long orgId,Integer page,Integer size){ + + + return teacherOpenCourseStudentSigninService.getSignInfoByTeacher(courseId,orgId,page,size); + } + +} + + diff --git a/src/main/java/com/sztzjy/trade/entity/IpAddress.java b/src/main/java/com/sztzjy/trade/entity/IpAddress.java new file mode 100644 index 0000000..1d504ee --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/IpAddress.java @@ -0,0 +1,117 @@ +package com.sztzjy.trade.entity; + + +import javax.validation.constraints.NotNull; + +/* +* +* gen by Spring Boot2 Admin 2020-12-04 +*/ +public class IpAddress { + + //id + private Integer id ; + + //ip + + private String ip ; + + //省 + + private String province ; + + //市 + + private String city ; + + //区 + + private String district ; + + //备注 + + private String remark ; + + public IpAddress(){ + } + + /**id + *@return + */ + public Integer getId(){ + return id; + } + /**id + *@param id + */ + public void setId(Integer id){ + this.id = id; + } + + /**ip + *@return + */ + public String getIp(){ + return ip; + } + /**ip + *@param ip + */ + public void setIp(String ip){ + this.ip = ip; + } + + /**省 + *@return + */ + public String getProvince(){ + return province; + } + /**省 + *@param province + */ + public void setProvince(String province){ + this.province = province; + } + + /**市 + *@return + */ + public String getCity(){ + return city; + } + /**市 + *@param city + */ + public void setCity(String city){ + this.city = city; + } + + /**区 + *@return + */ + public String getDistrict(){ + return district; + } + /**区 + *@param district + */ + public void setDistrict(String district){ + this.district = district; + } + + /**备注 + *@return + */ + public String getRemark(){ + return remark; + } + /**备注 + *@param remark + */ + public void setRemark(String remark){ + this.remark = remark; + } + + +} diff --git a/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLog.java b/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLog.java index a854b4d..5ef48b4 100644 --- a/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLog.java +++ b/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLog.java @@ -3,12 +3,18 @@ package com.sztzjy.trade.entity; import java.util.Date; import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + /** * 教师-我的课程-开课-学生签到记录 * * @author whb * teacher_open_course_student_signin_log */ + +@Data +@Builder public class TeacherOpenCourseStudentSigninLog { @ApiModelProperty("ID") private Long teacherOpenCourseStudentSigninLogId; @@ -20,7 +26,7 @@ public class TeacherOpenCourseStudentSigninLog { private Date teacherOpenCourseStudentSigninSettingSessionTime; @ApiModelProperty("学生ID") - private Long studentId; + private String studentId; @ApiModelProperty("开课ID") private Long teacherOpenCourseId; @@ -73,12 +79,12 @@ public class TeacherOpenCourseStudentSigninLog { this.teacherOpenCourseStudentSigninSettingSessionTime = teacherOpenCourseStudentSigninSettingSessionTime; } - public Long getStudentId() { + public String getStudentId() { return studentId; } - public void setStudentId(Long studentId) { - this.studentId = studentId; + public void setStudentId(String studentId) { + this.studentId = studentId == null ? null : studentId.trim(); } public Long getTeacherOpenCourseId() { diff --git a/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLogExample.java b/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLogExample.java index 28bd2d9..7c0fb7d 100644 --- a/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLogExample.java +++ b/src/main/java/com/sztzjy/trade/entity/TeacherOpenCourseStudentSigninLogExample.java @@ -295,52 +295,62 @@ public class TeacherOpenCourseStudentSigninLogExample { return (Criteria) this; } - public Criteria andStudentIdEqualTo(Long value) { + public Criteria andStudentIdEqualTo(String value) { addCriterion("student_id =", value, "studentId"); return (Criteria) this; } - public Criteria andStudentIdNotEqualTo(Long value) { + public Criteria andStudentIdNotEqualTo(String value) { addCriterion("student_id <>", value, "studentId"); return (Criteria) this; } - public Criteria andStudentIdGreaterThan(Long value) { + public Criteria andStudentIdGreaterThan(String value) { addCriterion("student_id >", value, "studentId"); return (Criteria) this; } - public Criteria andStudentIdGreaterThanOrEqualTo(Long value) { + public Criteria andStudentIdGreaterThanOrEqualTo(String value) { addCriterion("student_id >=", value, "studentId"); return (Criteria) this; } - public Criteria andStudentIdLessThan(Long value) { + public Criteria andStudentIdLessThan(String value) { addCriterion("student_id <", value, "studentId"); return (Criteria) this; } - public Criteria andStudentIdLessThanOrEqualTo(Long value) { + public Criteria andStudentIdLessThanOrEqualTo(String value) { addCriterion("student_id <=", value, "studentId"); return (Criteria) this; } - public Criteria andStudentIdIn(List values) { + public Criteria andStudentIdLike(String value) { + addCriterion("student_id like", value, "studentId"); + return (Criteria) this; + } + + public Criteria andStudentIdNotLike(String value) { + addCriterion("student_id not like", value, "studentId"); + return (Criteria) this; + } + + public Criteria andStudentIdIn(List values) { addCriterion("student_id in", values, "studentId"); return (Criteria) this; } - public Criteria andStudentIdNotIn(List values) { + public Criteria andStudentIdNotIn(List values) { addCriterion("student_id not in", values, "studentId"); return (Criteria) this; } - public Criteria andStudentIdBetween(Long value1, Long value2) { + public Criteria andStudentIdBetween(String value1, String value2) { addCriterion("student_id between", value1, value2, "studentId"); return (Criteria) this; } - public Criteria andStudentIdNotBetween(Long value1, Long value2) { + public Criteria andStudentIdNotBetween(String value1, String value2) { addCriterion("student_id not between", value1, value2, "studentId"); return (Criteria) this; } diff --git a/src/main/java/com/sztzjy/trade/entity/dto/StuSignDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/StuSignDTO.java new file mode 100644 index 0000000..dbc0342 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/StuSignDTO.java @@ -0,0 +1,45 @@ +package com.sztzjy.trade.entity.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author 17803 + * @date 2024-08-08 10:54 + */ + +@Data +public class StuSignDTO { + + @ApiModelProperty("用户ID") + @NotNull + String userId; + + @ApiModelProperty("用户ID") + @NotNull + String studentId; + + + @ApiModelProperty("课程ID") + @NotNull + Long courseId; + + @ApiModelProperty("班级ID") + @NotNull + String classId; + + @ApiModelProperty("签到类型") + @NotNull + String type; + + @ApiModelProperty("验证码") + @NotNull + String value; + + + @ApiModelProperty("签到表的ID") + @NotNull + Long teacherOpenCourseStudentSigninSettingId; +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/StudentSigninSettingDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/StudentSigninSettingDTO.java new file mode 100644 index 0000000..a773310 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/StudentSigninSettingDTO.java @@ -0,0 +1,27 @@ +package com.sztzjy.trade.entity.dto; + +import com.sztzjy.trade.entity.TeacherOpenCourseStudentSigninSetting; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author 17803 + * @date 2024-08-08 13:39 + */ + +@Data +public class StudentSigninSettingDTO { + + + private TeacherOpenCourseStudentSigninSetting studentSigninSetting; + + @ApiModelProperty("标记 10已签到 20缺勤 ") + private Integer teacherOpenCourseStudentSigninLogTag; + + + + + + + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TchEndSignDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TchEndSignDTO.java new file mode 100644 index 0000000..83b68dd --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TchEndSignDTO.java @@ -0,0 +1,18 @@ +package com.sztzjy.trade.entity.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author 17803 + * @date 2024-08-08 14:47 + */ + +@Data +public class TchEndSignDTO { + + @ApiModelProperty("ID") + private Long teacherOpenCourseStudentSigninSettingId; + + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignDTO.java new file mode 100644 index 0000000..f02898d --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignDTO.java @@ -0,0 +1,55 @@ +package com.sztzjy.trade.entity.dto; + +import com.sztzjy.trade.enums.StartStatusEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; +import java.util.List; + +/** + * @author 17803 + * @date 2024-08-08 15:33 + */ + +@Data +public class TchManualSignDTO { + + @ApiModelProperty("签到表ID") + @NotNull(message = "签到表ID不能为空") + private Long teacherOpenCourseStudentSigninSettingId; + + @ApiModelProperty("课程ID") + @NotNull(message = "课程ID不能为空") + private Long teacherOpenCourseId; + + + @ApiModelProperty("签到的班级") + @NotNull(message = "签到的班级能为空") + private String classIds; + + + @ApiModelProperty("场次时间") + @NotNull(message = "场次时间不能为空") + private Date teacherOpenCourseStudentSigninSettingSessionTime; + + @ApiModelProperty("教师ID") + @NotNull(message = "教师ID不能为空") + private Long userId; + + + @ApiModelProperty("用户签到数据") + private List tchManualSignSettingDTOList; + + + + + + + + + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignSettingDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignSettingDTO.java new file mode 100644 index 0000000..601eea1 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignSettingDTO.java @@ -0,0 +1,43 @@ +package com.sztzjy.trade.entity.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * @author 17803 + * @date 2024-08-09 10:28 + */ + +@Data +public class TchManualSignSettingDTO { + + + @ApiModelProperty("用户ID") + private Long userId; + + + + @ApiModelProperty("标记 10签到 20缺勤((缺勤理由不能为空))") + private Integer teacherOpenCourseStudentSigninLogTag; + + + @ApiModelProperty("学生ID") + private String studentId; + + @ApiModelProperty("班级ID") + private Long schoolClassId; + + @ApiModelProperty("签到日期") + private Date teacherOpenCourseStudentSigninLogAddTime; + + + @ApiModelProperty("备注(缺勤理由)") + private String teacherOpenCourseStudentSigninLogRemark; + + + + + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignVo.java b/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignVo.java new file mode 100644 index 0000000..04505bb --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TchManualSignVo.java @@ -0,0 +1,25 @@ +package com.sztzjy.trade.entity.dto; + +import com.sztzjy.trade.entity.StuUser; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author 17803 + * @date 2024-08-09 10:18 + */ + +@Data +public class TchManualSignVo { + + @ApiModelProperty("签到表ID") + private Long teacherOpenCourseStudentSigninSettingId; + + + @ApiModelProperty("用户数据") + List userList; + + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TchSignInfoDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TchSignInfoDTO.java new file mode 100644 index 0000000..f85cc96 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TchSignInfoDTO.java @@ -0,0 +1,31 @@ +package com.sztzjy.trade.entity.dto; + +import com.github.pagehelper.PageInfo; +import com.sztzjy.trade.entity.TeacherOpenCourseStudentSigninSetting; +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author 17803 + * @date 2024-08-09 14:19 + */ + +@Data +@Builder +public class TchSignInfoDTO { + @ApiModelProperty("合计签到次数") + private int sum; + @ApiModelProperty("合计签到人数") + private int signCount; + @ApiModelProperty("合计缺勤人数") + private int missStudent; + @ApiModelProperty("合计到课率") + private double totalAttendRate; + + + private PageInfo signinSettingList; + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TchUpdateManualSignDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TchUpdateManualSignDTO.java new file mode 100644 index 0000000..57bd738 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TchUpdateManualSignDTO.java @@ -0,0 +1,32 @@ +package com.sztzjy.trade.entity.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author 17803 + * @date 2024-08-09 10:13 + */ + +@Data +public class TchUpdateManualSignDTO { + + + @ApiModelProperty("课程ID") + private Long teacherOpenCourseId; + + @ApiModelProperty("签到的班级") + @NotNull(message = "签到的班级能为空") + private String classId; + + + @ApiModelProperty("用户ID") + private Long userId; + + @ApiModelProperty("签到表ID") + private Long teacherOpenCourseStudentSigninSettingId; + +} diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TeacherOpenCourseStudentSigninSettingDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TeacherOpenCourseStudentSigninSettingDTO.java index 60dbadf..0f5e10e 100644 --- a/src/main/java/com/sztzjy/trade/entity/dto/TeacherOpenCourseStudentSigninSettingDTO.java +++ b/src/main/java/com/sztzjy/trade/entity/dto/TeacherOpenCourseStudentSigninSettingDTO.java @@ -7,7 +7,6 @@ import com.sztzjy.trade.entity.TeacherOpenCourseStudentSigninSetting; import com.sztzjy.trade.enums.StartStatusEnum; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import org.springframework.data.jpa.repository.Query; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -72,6 +71,17 @@ public class TeacherOpenCourseStudentSigninSettingDTO { @ApiModelProperty("用户ID") private Long userId; + @ApiModelProperty("学校ID") + private Long orgId; + + + + public TeacherOpenCourseStudentSigninSettingDTO(){ + this.teacherOpenCourseStudentSigninSettingSessionTime = new Date(); + this.teacherOpenCourseStudentSigninSettingAddTime = new Date(); + this.teacherOpenCourseStudentSigninSettingStatus = 1; + } + public TeacherOpenCourseStudentSigninSetting pojo(){ TeacherOpenCourseStudentSigninSetting pojo = new TeacherOpenCourseStudentSigninSetting(); pojo.setTeacherOpenCourseId(this.getTeacherOpenCourseId()); @@ -84,6 +94,8 @@ public class TeacherOpenCourseStudentSigninSettingDTO { pojo.setTeacherOpenCourseStudentSigninSettingStatus(this.getTeacherOpenCourseStudentSigninSettingStatus()); pojo.setTeacherOpenCourseStudentSigninSettingSessionTime(this.getTeacherOpenCourseStudentSigninSettingSessionTime()); pojo.setTeacherOpenCourseStudentSigninSettingSigninTime(this.getTeacherOpenCourseStudentSigninSettingSigninTime()); + pojo.setOrgId(this.getOrgId()); + pojo.setUserId(this.getUserId()); return pojo; } diff --git a/src/main/java/com/sztzjy/trade/entity/dto/TeacherSigninSettingDTO.java b/src/main/java/com/sztzjy/trade/entity/dto/TeacherSigninSettingDTO.java new file mode 100644 index 0000000..5eb14af --- /dev/null +++ b/src/main/java/com/sztzjy/trade/entity/dto/TeacherSigninSettingDTO.java @@ -0,0 +1,69 @@ +package com.sztzjy.trade.entity.dto;/** + * @author 17803 + * @date 2024-08-09 14:23 + */ + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; + +@Data + +public class TeacherSigninSettingDTO { + + + + @ApiModelProperty("ID") + private Long teacherOpenCourseStudentSigninSettingId; + + @ApiModelProperty("场次时间") + private Date teacherOpenCourseStudentSigninSettingSessionTime; + + @ApiModelProperty("开课ID") + private Long teacherOpenCourseId; + + @ApiModelProperty("班级ID集合") + private String schoolClassIds; + + @ApiModelProperty("签到方式 (数据字典 student_signin_type)") + private String teacherOpenCourseStudentSigninSettingType; + + @ApiModelProperty("设置的值:数据例子:IP: x.x.x.x-x.x.x.x,验证码:xxxx,手动签到:无需设置") + private String teacherOpenCourseStudentSigninSettingValue; + + @ApiModelProperty("创建时间") + private Date teacherOpenCourseStudentSigninSettingAddTime; + + @ApiModelProperty("状态 1正常 2删除") + private Integer teacherOpenCourseStudentSigninSettingStatus; + + @ApiModelProperty("开启状态 (枚举 StartStatusEnum)") + private String teacherOpenCourseStudentSigninSettingStartStatus; + + @ApiModelProperty("开始时间") + private Date teacherOpenCourseStudentSigninSettingStartTime; + + @ApiModelProperty("结束时间") + private Date teacherOpenCourseStudentSigninSettingEndTime; + + @ApiModelProperty("组织ID") + private Long orgId; + + @ApiModelProperty("用户ID") + private Long userId; + + @ApiModelProperty("学生签到时间") + private Date teacherOpenCourseStudentSigninSettingSigninTime; + + @ApiModelProperty("签到人数") + private Integer signCount; + @ApiModelProperty("缺勤人数") + private Integer missStudent; + @ApiModelProperty("总人数") + private Integer sum; + @ApiModelProperty("到课率") + private double totalAttendRate; + +} diff --git a/src/main/java/com/sztzjy/trade/service/StuSignInfoService.java b/src/main/java/com/sztzjy/trade/service/StuSignInfoService.java new file mode 100644 index 0000000..cc4b43d --- /dev/null +++ b/src/main/java/com/sztzjy/trade/service/StuSignInfoService.java @@ -0,0 +1,33 @@ +package com.sztzjy.trade.service; + +import com.sztzjy.trade.entity.dto.StuSignDTO; +import com.sztzjy.trade.util.ResultEntity; +import org.apache.ibatis.annotations.Param; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author 17803 + * @date 2024-08-08 10:31 + */ +public interface StuSignInfoService { + /** + * 课程内查询用户所有签到信息 + * @param userId + * @param courseId + * @param classId + * @param size + * @param page + * @return + */ + + ResultEntity getSignInfoByUserId(String userId, Long courseId, String classId, Integer size, Integer page); + + /** + * 用户签到操作 + * @param request + * @return + */ + + ResultEntity sign(StuSignDTO stuSignDTO, HttpServletRequest request); +} diff --git a/src/main/java/com/sztzjy/trade/service/TeacherOpenCourseStudentSigninService.java b/src/main/java/com/sztzjy/trade/service/TeacherOpenCourseStudentSigninService.java index cfc7ab2..8e650c7 100644 --- a/src/main/java/com/sztzjy/trade/service/TeacherOpenCourseStudentSigninService.java +++ b/src/main/java/com/sztzjy/trade/service/TeacherOpenCourseStudentSigninService.java @@ -1,7 +1,11 @@ package com.sztzjy.trade.service; +import com.sztzjy.trade.entity.dto.TchEndSignDTO; +import com.sztzjy.trade.entity.dto.TchManualSignDTO; +import com.sztzjy.trade.entity.dto.TchUpdateManualSignDTO; import com.sztzjy.trade.entity.dto.TeacherOpenCourseStudentSigninSettingDTO; import com.sztzjy.trade.util.ResultEntity; +import org.apache.ibatis.annotations.Param; /** * @author 17803 @@ -9,4 +13,47 @@ import com.sztzjy.trade.util.ResultEntity; */ public interface TeacherOpenCourseStudentSigninService { ResultEntity addDo(TeacherOpenCourseStudentSigninSettingDTO teacherOpenCourseStudentSigninSettingDTO); + + /** + * 教师端开始签到 + * @param teacherOpenCourseStudentSigninSettingId + * @return + */ + + ResultEntity openStartState(Long teacherOpenCourseStudentSigninSettingId); + + /** + * 教师端结束签到 + * @param tchEndSignDTO + * @return + */ + + ResultEntity endSign(TchEndSignDTO tchEndSignDTO); + + + /** + * 发起手动签到 + * @param tchManualSignDTO + * @return + */ + + ResultEntity manualSignByRandom(TchManualSignDTO tchManualSignDTO); + + /** + * 手动签到确认 + * @param tchManualSignDTO + * @return + */ + + ResultEntity manualSignSure(TchManualSignDTO tchManualSignDTO); + + + /** + * 课程内查询签到信息 + * @param courseId + * @param orgId + * @return + */ + + ResultEntity getSignInfoByTeacher(@Param("courseId") Long courseId, @Param("orgId") Long orgId,Integer page,Integer size); } diff --git a/src/main/java/com/sztzjy/trade/service/impl/StuSignInfoServiceImpl.java b/src/main/java/com/sztzjy/trade/service/impl/StuSignInfoServiceImpl.java new file mode 100644 index 0000000..be03798 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/service/impl/StuSignInfoServiceImpl.java @@ -0,0 +1,231 @@ +package com.sztzjy.trade.service.impl;/** + * @author 17803 + * @date 2024-08-08 10:31 + */ + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Assert; +import com.github.pagehelper.PageHelper; +import com.sztzjy.trade.config.Constant; +import com.sztzjy.trade.entity.*; +import com.sztzjy.trade.entity.dto.StuSignDTO; +import com.sztzjy.trade.entity.dto.StudentSigninSettingDTO; +import com.sztzjy.trade.entity.dto.TeacherOpenCourseStudentSigninSettingDTO; +import com.sztzjy.trade.mapper.TeacherOpenCourseStudentSigninLogMapper; +import com.sztzjy.trade.mapper.TeacherOpenCourseStudentSigninSettingMapper; +import com.sztzjy.trade.service.StuSignInfoService; +import com.sztzjy.trade.util.IpUtils; +import com.sztzjy.trade.util.ResultEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import static cn.hutool.core.net.NetUtil.ipv4ToLong; +import static com.sztzjy.trade.util.IpUtils.getIpAddr; +import static com.sztzjy.trade.util.IpUtils.isRangeInner; + +@Service +public class StuSignInfoServiceImpl implements StuSignInfoService { + + + @Autowired + private TeacherOpenCourseStudentSigninSettingMapper teacherOpenCourseStudentSigninSettingMapper; + + @Autowired + private TeacherOpenCourseStudentSigninLogMapper teacherOpenCourseStudentSigninLogMapper; + + /** + * 课程内查询用户所有签到信息 + * + * @param userId + * @param courseId + * @param classId + * @param size + * @param page + * @return + */ + + @Override + public ResultEntity getSignInfoByUserId(String userId, Long courseId, String classId, Integer size, Integer page) { + //开启分页 + PageHelper.startPage(page, size); + + List list = new ArrayList<>(); + + //查询签到记录 + TeacherOpenCourseStudentSigninSettingExample courseStudentSigninSettingExample = new TeacherOpenCourseStudentSigninSettingExample(); + courseStudentSigninSettingExample.createCriteria().andTeacherOpenCourseIdEqualTo(courseId); + List teacherOpenCourseStudentSigninSettingList = teacherOpenCourseStudentSigninSettingMapper.selectByExample(courseStudentSigninSettingExample); + if (teacherOpenCourseStudentSigninSettingList.isEmpty()) { + return new ResultEntity<>(HttpStatus.OK); + } + for (TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting : teacherOpenCourseStudentSigninSettingList) { + //一个课程所有的班级ID + String[] classIds = openCourseStudentSigninSetting.getSchoolClassIds().split(","); + //是否包含用户的classId + if (Arrays.asList(classIds).contains(classId)) { + + StudentSigninSettingDTO studentSigninSettingDTO = new StudentSigninSettingDTO(); + studentSigninSettingDTO.setStudentSigninSetting(openCourseStudentSigninSetting); + //需要展示这一条数据 + list.add(studentSigninSettingDTO); + + } + } + //已经签到了或者缺勤 + for (StudentSigninSettingDTO studentSigninSettingDTO : list) { + //todo 查询自己签到记录 如果没有匹配数据,而且当前时间大于结束时间 就是缺勤 + // 手动签到没有记录处理 + + TeacherOpenCourseStudentSigninLogExample openCourseStudentSigninLogExample = new TeacherOpenCourseStudentSigninLogExample(); + openCourseStudentSigninLogExample.createCriteria().andUserIdEqualTo(Convert.toLong(userId)).andTeacherOpenCourseIdEqualTo(courseId); + List teacherOpenCourseStudentSigninLogList = teacherOpenCourseStudentSigninLogMapper.selectByExample(openCourseStudentSigninLogExample); + + //没有查询到签到记录 + if (teacherOpenCourseStudentSigninLogList.isEmpty()) { + //当前时间 + Date date = new Date(); + + //签到没有结束 //还可以签到 + if (studentSigninSettingDTO.getStudentSigninSetting().getTeacherOpenCourseStudentSigninSettingEndTime() == null) { + studentSigninSettingDTO.setTeacherOpenCourseStudentSigninLogTag(null); + continue; + } + + //签到结束 + Date endTime = studentSigninSettingDTO.getStudentSigninSetting().getTeacherOpenCourseStudentSigninSettingEndTime(); + //签到结束 //判断是缺勤 还是签到方式为:手动签到 + if (date.after(endTime)) { + + //判断签到方式为手动 + if (Constant.MANUAL.equals(studentSigninSettingDTO.getStudentSigninSetting().getTeacherOpenCourseStudentSigninSettingType())) { + studentSigninSettingDTO.setTeacherOpenCourseStudentSigninLogTag(10); + } + studentSigninSettingDTO.setTeacherOpenCourseStudentSigninLogTag(20); + continue; + } + + } + for (TeacherOpenCourseStudentSigninLog teacherOpenCourseStudentSigninLog : teacherOpenCourseStudentSigninLogList) { + if (studentSigninSettingDTO.getStudentSigninSetting().getTeacherOpenCourseStudentSigninSettingId() + .equals(teacherOpenCourseStudentSigninLog.getTeacherOpenCourseStudentSigninSettingId())) { + studentSigninSettingDTO.setTeacherOpenCourseStudentSigninLogTag(teacherOpenCourseStudentSigninLog.getTeacherOpenCourseStudentSigninLogTag()); + } + } + + } + return new ResultEntity(HttpStatus.OK, list); + } + + /** + * 用户签到操作 + * + * @param request + * @return + */ + @Override + public ResultEntity sign(StuSignDTO stuSignDTO, HttpServletRequest request) { + + //判断是否重复签到 + TeacherOpenCourseStudentSigninLogExample openCourseStudentSigninLogExample = new TeacherOpenCourseStudentSigninLogExample(); + + openCourseStudentSigninLogExample.createCriteria().andUserIdEqualTo(Long.valueOf(stuSignDTO.getUserId())).andTeacherOpenCourseStudentSigninSettingIdEqualTo(stuSignDTO.getTeacherOpenCourseStudentSigninSettingId()); + + List teacherOpenCourseStudentSigninLogList = teacherOpenCourseStudentSigninLogMapper.selectByExample(openCourseStudentSigninLogExample); + if (!teacherOpenCourseStudentSigninLogList.isEmpty()) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "您已成功签到!"); + } + + + TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting = teacherOpenCourseStudentSigninSettingMapper.selectByPrimaryKey(stuSignDTO.getTeacherOpenCourseStudentSigninSettingId()); + + String settingValue = openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingValue(); + + //判断是否结束 + if (openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingStartStatus().equals(Constant.END)) { + + return new ResultEntity<>(HttpStatus.OK, "签到已经结束"); + } + + //判断是否结束 + if (openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingStartStatus().equals(Constant.READY)) { + + return new ResultEntity<>(HttpStatus.OK, "签到还未开始"); + } + + //根据签到类型操作 code + if (Constant.CODE.equals(stuSignDTO.getType())) { + //校验code值是否正确 + if (!stuSignDTO.getValue().equals(settingValue)) { + return new ResultEntity<>(HttpStatus.OK, "验证码错误"); + } + //签到 + signByStudent(null, openCourseStudentSigninSetting, stuSignDTO); + + + } + + //根据签到类型操作 ip + if (Constant.IP.equals(stuSignDTO.getType())) { + String ip = request.getRemoteAddr(); + +// 判断ip地址是否符合条件 + // 获取到真实的IP + String myIpAddress = getIpAddr(request); + + // 断言,如果IP不在指定的IP段内,则添加失败,异常信息丢给前台 + Assert.isTrue(isRangeInner(myIpAddress, settingValue), + "您的IP地址:{},不在指定的IP段内!", myIpAddress); + + signByStudent(ip, openCourseStudentSigninSetting, stuSignDTO); + + } + + + return new ResultEntity<>(HttpStatus.OK, "签到成功!"); + } + + + public void signByStudent(String ipAddress, TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting, StuSignDTO stuSignDTO) { + + TeacherOpenCourseStudentSigninLog studentSigninLog = TeacherOpenCourseStudentSigninLog.builder(). + //场次时间 + teacherOpenCourseStudentSigninSettingSessionTime(openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingSessionTime()). + //签到配置ID + teacherOpenCourseStudentSigninSettingId(openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingId()). + //开课ID + teacherOpenCourseId(openCourseStudentSigninSetting.getTeacherOpenCourseId()).teacherOpenCourseStudentSigninLogTag(10) + .schoolClassId(Long.valueOf(stuSignDTO.getClassId())) + .studentId(stuSignDTO.getStudentId()) + .userId(Long.valueOf(stuSignDTO.getUserId())) + .teacherOpenCourseStudentSigninLogAddTime(new Date()).build(); + + //ipAddress不为空的时候 + if (StringUtils.hasText(ipAddress)) { + + studentSigninLog.setTeacherOpenCourseStudentSigninLogType(Constant.IP); + studentSigninLog.setTeacherOpenCourseStudentSigninLogIp(ipAddress); + + + } else { + + studentSigninLog.setTeacherOpenCourseStudentSigninLogType(Constant.CODE); + + + } + + teacherOpenCourseStudentSigninLogMapper.insertSelective(studentSigninLog); + + + } + + +} diff --git a/src/main/java/com/sztzjy/trade/service/impl/TchHomeworkExamServiceImpl.java b/src/main/java/com/sztzjy/trade/service/impl/TchHomeworkExamServiceImpl.java index 205dc07..cc89206 100644 --- a/src/main/java/com/sztzjy/trade/service/impl/TchHomeworkExamServiceImpl.java +++ b/src/main/java/com/sztzjy/trade/service/impl/TchHomeworkExamServiceImpl.java @@ -10,6 +10,7 @@ import com.sztzjy.trade.mapper.*; import com.sztzjy.trade.service.TchHomeworkExamService; import com.sztzjy.trade.util.ConvertUtil; import com.sztzjy.trade.util.PageUtil; +import com.sztzjy.trade.util.file.IFileUtil; import com.sztzjy.trade.util.file.LocalFileUtil; import org.apache.poi.ss.formula.functions.T; import org.springframework.http.HttpStatus; @@ -33,7 +34,7 @@ public class TchHomeworkExamServiceImpl implements TchHomeworkExamService { ConvertUtil convertUtil; @Resource - LocalFileUtil localFileUtil; + IFileUtil localFileUtil; @Resource TchExamManageMapper examManageMapper; diff --git a/src/main/java/com/sztzjy/trade/service/impl/TeacherOpenCourseStudentSigninServiceImpl.java b/src/main/java/com/sztzjy/trade/service/impl/TeacherOpenCourseStudentSigninServiceImpl.java index 78a4a46..86e7d41 100644 --- a/src/main/java/com/sztzjy/trade/service/impl/TeacherOpenCourseStudentSigninServiceImpl.java +++ b/src/main/java/com/sztzjy/trade/service/impl/TeacherOpenCourseStudentSigninServiceImpl.java @@ -3,28 +3,45 @@ package com.sztzjy.trade.service.impl;/** * @date 2024-08-08 9:24 */ -import com.sztzjy.trade.entity.TeacherOpenCourseStudentSigninSetting; -import com.sztzjy.trade.entity.dto.TeacherOpenCourseStudentSigninSettingDTO; +import cn.hutool.core.util.IdUtil; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.sztzjy.trade.config.Constant; +import com.sztzjy.trade.entity.*; +import com.sztzjy.trade.entity.dto.*; import com.sztzjy.trade.enums.StartStatusEnum; +import com.sztzjy.trade.mapper.StuUserMapper; +import com.sztzjy.trade.mapper.TeacherOpenCourseStudentSigninLogMapper; import com.sztzjy.trade.mapper.TeacherOpenCourseStudentSigninSettingMapper; import com.sztzjy.trade.service.TeacherOpenCourseStudentSigninService; import com.sztzjy.trade.util.ResultEntity; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; -import java.util.Date; +import java.util.*; +import java.util.stream.Collectors; @Service public class TeacherOpenCourseStudentSigninServiceImpl implements TeacherOpenCourseStudentSigninService { @Autowired private TeacherOpenCourseStudentSigninSettingMapper teacherOpenCourseStudentSigninSettingMapper; + @Autowired + private StuUserMapper stuUserMapper; + + @Autowired + private TeacherOpenCourseStudentSigninLogMapper teacherOpenCourseStudentSigninLogMapper; + @Override public ResultEntity addDo(TeacherOpenCourseStudentSigninSettingDTO teacherOpenCourseStudentSigninSettingDTO) { + TeacherOpenCourseStudentSigninSetting teacherOpenCourseStudentSigninSetting = teacherOpenCourseStudentSigninSettingDTO.pojo(); teacherOpenCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingAddTime(new Date()); + // 默认是未开始的状态 teacherOpenCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStartStatus(String.valueOf(StartStatusEnum.READY)); //获取现在时间 只保留到分钟 @@ -33,12 +50,353 @@ public class TeacherOpenCourseStudentSigninServiceImpl implements TeacherOpenCou String nowTime = dateFormat.format(now); try { now = dateFormat.parse(nowTime); - }catch (Exception e){ + } catch (Exception e) { throw new RuntimeException("时间转换异常", e); } teacherOpenCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingSessionTime(now); teacherOpenCourseStudentSigninSettingMapper.insertSelective(teacherOpenCourseStudentSigninSetting); - return new ResultEntity<>(HttpStatus.OK,"创建成功"); + return new ResultEntity<>(HttpStatus.OK, "创建成功"); + } + + /** + * 教师端开始签到 + * + * @param teacherOpenCourseStudentSigninSettingId + * @return + */ + + @Override + public ResultEntity openStartState(Long teacherOpenCourseStudentSigninSettingId) { + // + + //开始状态 teacher_open_course_student_signin_setting_start_status + // 签到开始日期 teacherOpenCourseStudentSigninSettingStartTime + + TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting = teacherOpenCourseStudentSigninSettingMapper.selectByPrimaryKey(teacherOpenCourseStudentSigninSettingId); + if (openCourseStudentSigninSetting == null) { + throw new RuntimeException("ID不存在!"); + } + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStartTime(new Date()); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStartStatus(String.valueOf(StartStatusEnum.ING)); + + + teacherOpenCourseStudentSigninSettingMapper.updateByPrimaryKeySelective(openCourseStudentSigninSetting); + + return new ResultEntity<>(HttpStatus.OK); + } + + /** + * 教师端结束签到 + * + * @param tchEndSignDTO + * @return + */ + + @Override + public ResultEntity endSign(TchEndSignDTO tchEndSignDTO) { + + //修改状态 添加结束时间 + TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting = + teacherOpenCourseStudentSigninSettingMapper.selectByPrimaryKey(tchEndSignDTO.getTeacherOpenCourseStudentSigninSettingId()); + + if (openCourseStudentSigninSetting == null) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "不存在的ID"); + } + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStartStatus(String.valueOf(StartStatusEnum.END)); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingEndTime(new Date()); + + teacherOpenCourseStudentSigninSettingMapper.updateByPrimaryKeySelective(openCourseStudentSigninSetting); + + + return null; + } + + /** + * 发起手动签到 + * + * @param tchManualSignDTO + * @return + */ + + @Override + public ResultEntity manualSignByRandom(TchManualSignDTO tchManualSignDTO) { + + + TchManualSignVo vo = new TchManualSignVo(); + + //签到表ID + vo.setTeacherOpenCourseStudentSigninSettingId(IdUtil.getSnowflakeNextId()); + + // 定义要随机抽取的数量 + int numberOfUsersToSelect = 6; + String[] split = tchManualSignDTO.getClassIds().split("."); + + for (String classId : split) { + numberOfUsersToSelect += 2; + } + List collect = Arrays.stream(split).collect(Collectors.toList()); + //根据班级列表查询对应所有用户数据 + StuUserExample stuUserExample = new StuUserExample(); + stuUserExample.createCriteria().andClassIdIn(collect); + List stuUserList = stuUserMapper.selectByExample(stuUserExample); + if (stuUserList.isEmpty()) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "暂无该班级"); + } + // 使用 Collections.shuffle 随机打乱列表 + Collections.shuffle(stuUserList); + + + // 检查列表大小是否大于等于要抽取的数量 + if (stuUserList.size() < numberOfUsersToSelect) { + + + // 抽取指定数量的元素 + List selectedUsers = stuUserList.subList(0, stuUserList.size()); + vo.setUserList(selectedUsers); + + return new ResultEntity<>(HttpStatus.OK, vo); + + } else { + + // 抽取指定数量的元素 + List selectedUsers = stuUserList.subList(0, numberOfUsersToSelect); + vo.setUserList(selectedUsers); + return new ResultEntity<>(HttpStatus.OK, vo); + } + + + } + + /** + * 手动签到确认 + * + * @param tchManualSignDTO + * @return + */ + + @Override + public ResultEntity manualSignSure(TchManualSignDTO tchManualSignDTO) { + //查询是否为多次插入 + TeacherOpenCourseStudentSigninSetting teacherOpenCourseStudentSigninSetting = + teacherOpenCourseStudentSigninSettingMapper.selectByPrimaryKey(tchManualSignDTO.getTeacherOpenCourseStudentSigninSettingId()); + + if (teacherOpenCourseStudentSigninSetting != null) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "请勿重复操作!"); + } else { + //创建签到表 + TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting = new TeacherOpenCourseStudentSigninSetting(); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingSessionTime(tchManualSignDTO.getTeacherOpenCourseStudentSigninSettingSessionTime()); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingId(tchManualSignDTO.getTeacherOpenCourseStudentSigninSettingId()); + openCourseStudentSigninSetting.setTeacherOpenCourseId(tchManualSignDTO.getTeacherOpenCourseId()); + openCourseStudentSigninSetting.setSchoolClassIds(tchManualSignDTO.getClassIds()); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingAddTime((new Date())); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStatus(1); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStartStatus(String.valueOf(StartStatusEnum.END)); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingStartTime(tchManualSignDTO.getTeacherOpenCourseStudentSigninSettingSessionTime()); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingEndTime(new Date()); + openCourseStudentSigninSetting.setTeacherOpenCourseStudentSigninSettingType(Constant.MANUAL); + openCourseStudentSigninSetting.setUserId(tchManualSignDTO.getUserId()); + + teacherOpenCourseStudentSigninSettingMapper.insertSelective(openCourseStudentSigninSetting); + + //批量插入学生信息 + + System.out.println(tchManualSignDTO.getTchManualSignSettingDTOList().size()); + tchManualSignDTO.getTchManualSignSettingDTOList().forEach(item -> { + + //判断是否缺勤或者签到 + TeacherOpenCourseStudentSigninLog studentSigninLog = TeacherOpenCourseStudentSigninLog.builder() + .teacherOpenCourseStudentSigninSettingId(tchManualSignDTO.getTeacherOpenCourseStudentSigninSettingId()) + .teacherOpenCourseStudentSigninSettingSessionTime(tchManualSignDTO.getTeacherOpenCourseStudentSigninSettingSessionTime()) + .studentId(item.getStudentId()) + .teacherOpenCourseStudentSigninLogTag(item.getTeacherOpenCourseStudentSigninLogTag()) + .teacherOpenCourseId(tchManualSignDTO.getTeacherOpenCourseId()) + .schoolClassId(item.getSchoolClassId()) + .teacherOpenCourseStudentSigninLogAddTime(item.getTeacherOpenCourseStudentSigninLogAddTime()) + .teacherOpenCourseStudentSigninLogType(Constant.MANUAL) + .teacherOpenCourseStudentSigninLogRemark(item.getTeacherOpenCourseStudentSigninLogRemark()) + .userId(item.getUserId()).build(); + teacherOpenCourseStudentSigninLogMapper.insertSelective(studentSigninLog); + + }); + + + } + + return new ResultEntity<>(HttpStatus.OK, "操作成功!"); + + } + + + // 课程内查询签到信息 + @Override + public ResultEntity getSignInfoByTeacher(Long courseId, Long orgId, Integer page, Integer size) { + + //查询签到次数,签到人数,缺勤人数 合计到课率 + int sum = 0; + int signCount = 0; + int missStudent = 0; + double totalAttendRate = 0.0; + + // 开启分页,确保分页在数据库查询之前 + PageHelper.startPage(page, size); + //根据课程ID查询所有签到数据 + TeacherOpenCourseStudentSigninSettingExample example = new TeacherOpenCourseStudentSigninSettingExample(); + example.createCriteria().andOrgIdEqualTo(orgId).andTeacherOpenCourseIdEqualTo(courseId); + List teacherOpenCourseStudentSigninSettingList = teacherOpenCourseStudentSigninSettingMapper.selectByExample(example); + + // 包装分页后的结果 + // PageInfo pageInfo = new PageInfo<>(teacherOpenCourseStudentSigninSettingList); + + if (teacherOpenCourseStudentSigninSettingList.isEmpty()) { + + + TchSignInfoDTO tchSignInfoDTO = TchSignInfoDTO.builder().signCount(signCount).sum(sum).missStudent(missStudent).totalAttendRate(totalAttendRate) + .signinSettingList(null).build(); + return new ResultEntity<>(HttpStatus.OK, tchSignInfoDTO); + + + } + + //合计老师开启签到次数 + sum = teacherOpenCourseStudentSigninSettingList.size(); + + //存储记录表List + List teacherSigninSettingDTOS = new ArrayList<>(); + + //合计签到人数 + for (TeacherOpenCourseStudentSigninSetting openCourseStudentSigninSetting : teacherOpenCourseStudentSigninSettingList) { + + + Integer countByClass = 0; + //班级总人数 根据班级idS查询 + String[] split = openCourseStudentSigninSetting.getSchoolClassIds().split(","); + + + //查询每个班级人数 + StuUserExample stuUserExample = new StuUserExample(); + stuUserExample.createCriteria().andClassIdIn(Arrays.stream(split).collect(Collectors.toList())); + + + //总人数 + countByClass =+stuUserMapper.selectByExample(stuUserExample).size(); + + + TeacherOpenCourseStudentSigninLogExample studentSigninLogExample = new TeacherOpenCourseStudentSigninLogExample(); + + studentSigninLogExample.createCriteria() + .andTeacherOpenCourseStudentSigninSettingIdEqualTo + (openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingId()); + + List teacherOpenCourseStudentSigninLogList = + teacherOpenCourseStudentSigninLogMapper.selectByExample(studentSigninLogExample); + if (!teacherOpenCourseStudentSigninLogList.isEmpty()) { + + //对手动签到做处理 + if (Constant.MANUAL.equals(openCourseStudentSigninSetting.getTeacherOpenCourseStudentSigninSettingType())) + { + TeacherSigninSettingDTO teacherSigninSettingDTO = new TeacherSigninSettingDTO(); + + BeanUtils.copyProperties(openCourseStudentSigninSetting, teacherSigninSettingDTO); + + + //缺勤签到人数 + int missSizeManual = teacherOpenCourseStudentSigninLogList.stream() + .filter(item -> item.getTeacherOpenCourseStudentSigninLogType().equals(Constant.MANUAL)) + .filter(item->item.getTeacherOpenCourseStudentSigninLogTag()==20) + .collect(Collectors.toList()).size(); + + + + // 先转换为浮点数进行除法运算 + double result = (double) missSizeManual / countByClass; + + // 四舍五入保留两位小数 + //总到课率 + double roundedResult = Math.round(result * 100.0) / 100.0; + + teacherSigninSettingDTO.setSum(countByClass); + teacherSigninSettingDTO.setSignCount(countByClass-missSizeManual); + teacherSigninSettingDTO.setMissStudent(missSizeManual); + teacherSigninSettingDTO.setTotalAttendRate(roundedResult); + + teacherSigninSettingDTOS.add(teacherSigninSettingDTO); + + continue; + } + + + + //签到人数 + int size1 = teacherOpenCourseStudentSigninLogList.stream().filter(item -> item.getTeacherOpenCourseStudentSigninLogTag() == 10).collect(Collectors.toList()).size(); + + + signCount =+size1; + + //缺勤人数 + int info = teacherOpenCourseStudentSigninLogList.size() - size1; + + missStudent =+info; + + + + TeacherSigninSettingDTO teacherSigninSettingDTO = new TeacherSigninSettingDTO(); + + BeanUtils.copyProperties(openCourseStudentSigninSetting, teacherSigninSettingDTO); + + + + //当前签到总人数 + teacherSigninSettingDTO.setSum(countByClass); + //当前签到缺勤人数 + teacherSigninSettingDTO.setMissStudent(missStudent); + //当前签到签到人数 + teacherSigninSettingDTO.setSignCount(size1); + + // 先转换为浮点数进行除法运算 + double result = (double) size1 / countByClass; + + // 四舍五入保留两位小数 + //总到课率 + double roundedResult = Math.round(result * 100.0) / 100.0; + + //合计到课率 + totalAttendRate = +roundedResult; + + teacherSigninSettingDTO.setTotalAttendRate(roundedResult); + + teacherSigninSettingDTOS.add(teacherSigninSettingDTO); + } else { + + //没人签到,未开始 + TeacherSigninSettingDTO teacherSigninSettingDTO = new TeacherSigninSettingDTO(); + BeanUtils.copyProperties(openCourseStudentSigninSetting, teacherSigninSettingDTO); + teacherSigninSettingDTO.setSum(0); + + teacherSigninSettingDTO.setSignCount(0); + teacherSigninSettingDTO.setMissStudent(0); + teacherSigninSettingDTO.setTotalAttendRate(0.0); + + teacherSigninSettingDTO.setSum(countByClass); + + teacherSigninSettingDTOS.add(teacherSigninSettingDTO); + + } + + } + //开启分页 + + // 包装分页后的结果列表 + PageInfo teacherSigninSettingDTOPageInfo = new PageInfo<>(teacherSigninSettingDTOS); + + + TchSignInfoDTO tchSignInfoDTO = TchSignInfoDTO.builder().signCount(signCount).sum(sum).missStudent(missStudent).totalAttendRate(totalAttendRate) + .signinSettingList(teacherSigninSettingDTOPageInfo).build(); + return new ResultEntity<>(HttpStatus.OK, tchSignInfoDTO); + } + + + } diff --git a/src/main/java/com/sztzjy/trade/util/IpUtils.java b/src/main/java/com/sztzjy/trade/util/IpUtils.java new file mode 100644 index 0000000..7b954c9 --- /dev/null +++ b/src/main/java/com/sztzjy/trade/util/IpUtils.java @@ -0,0 +1,178 @@ +package com.sztzjy.trade.util; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ReUtil; + +import com.sztzjy.trade.entity.IpAddress; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; + +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import static cn.hutool.core.net.NetUtil.ipv4ToLong; + + +public class IpUtils { + + + + // 分隔符1 + public static final String SEPARATOR = "\\,"; + // 分隔符2 + public static final String IP_SPLIT_MARK = "\\-"; + // 分隔符3 + public static final String IP_SPLIT_SEPARATOR = "\\."; + + private IpUtils() { + } + + /** + * 获取当前网络ip + * + * @param request + * @return + */ + public static String getIpAddr(HttpServletRequest request) { + String ipAddress = request.getHeader("x-forwarded-for"); + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) { + // 根据网卡取本机配置的IP + InetAddress inet = null; + try { + inet = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + ipAddress = inet.getHostAddress(); + } + } + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() = 15 + if (ipAddress.indexOf(",") > 0) { + ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); + } + } + + return ipAddress; + } + + /** + * 获得MAC地址 + * + * @param ip + * @return + */ + public static String getMACAddress(String ip) { + String str = ""; + String macAddress = ""; + try { + Process p = Runtime.getRuntime().exec("nbtstat -A " + ip); + InputStreamReader ir = new InputStreamReader(p.getInputStream()); + LineNumberReader input = new LineNumberReader(ir); + for (int i = 1; i < 100; i++) { + str = input.readLine(); + if (str != null) { + if (str.indexOf("MAC Address") > 1) { + macAddress = str.substring(str.indexOf("MAC Address") + 14); + break; + } + } + } + } catch (IOException e) { + e.printStackTrace(System.out); + } + return macAddress; + } + + /** + * 验证IP区间是否符合要求 + * + * + * @param ipRangeAddressList 支持格式:x.x.x.x-x.x.x.x,x.x.x.x-x.x.x.x。多个IP段逗号隔开 + */ + public static void verifyIpRange(String ipRangeAddressList) { + Assert.notBlank(ipRangeAddressList, "待验证的IP区间,不能为空!"); + for (String ipRange : ipRangeAddressList.split(SEPARATOR)) { + // IP区间的正则 + String reg = "^((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}" + + "-((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}$"; + Assert.isTrue(ReUtil.isMatch(reg, ipRange), + () -> new RuntimeException("ipRangeAddressList 参数格式化错误!支持格式如:192.168.1.1-192.168.1.100")); + } + } + + /** + * 验证IP是否符合要求 + * + * + * @param ipAddressList 支持格式:x.x.x.x 多个IP段逗号隔开 + */ + public static void verifyIp(String ipAddressList) { + Assert.notBlank(ipAddressList, "待验证的IP,不能为空!"); + for (String ip : ipAddressList.split(SEPARATOR)) { + // 单IP的正则 + String reg = "^((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}$"; + Assert.isTrue(ReUtil.isMatch(reg, ip), + () -> new RuntimeException("ipAddressList 参数格式化错误!支持格式:192.168.1.1-192.168.1.100")); + } + } + + /** + * ID是否在IP区间内 + * + * @param myIpAddress + * @param ipAddressList 支持格式:x.x.x.x-x.x.x.x,x.x.x.x-x.x.x.x。多个IP段逗号隔开 + * @return + */ + public static Boolean isRangeInner(String myIpAddress, String ipAddressList) throws RuntimeException { + + verifyIpRange(ipAddressList); + // 我的IPv4转long类型 + long myIpLong = ipv4ToLong(myIpAddress); + + // 是否在IP段区间 + Boolean isRangeInner = false; + // 处理IP段,判断IP是否在这个区间内 192.168.1.1-192.168.1.100,192.168.2.1-192.168.2.100 + for (String range : ipAddressList.split(SEPARATOR)) { + // 两个IP段。开始IP-结束IP + String[] ips = range.split(IP_SPLIT_MARK); + long startIpLong = ipv4ToLong(ips[0]); + long endIpLong = ipv4ToLong(ips[1]); + // 在区间内,则打标记 + if((myIpLong >= startIpLong) && (myIpLong <= endIpLong)) { + isRangeInner = true; + } + } + + return isRangeInner; + } + + + + +} \ No newline at end of file diff --git a/src/main/resources/mappers/TeacherOpenCourseStudentSigninLogMapper.xml b/src/main/resources/mappers/TeacherOpenCourseStudentSigninLogMapper.xml index 891c04c..fe820c0 100644 --- a/src/main/resources/mappers/TeacherOpenCourseStudentSigninLogMapper.xml +++ b/src/main/resources/mappers/TeacherOpenCourseStudentSigninLogMapper.xml @@ -5,7 +5,7 @@ - + @@ -119,7 +119,7 @@ teacher_open_course_student_signin_log_ip, teacher_open_course_student_signin_log_tag, org_id, user_id) values (#{teacherOpenCourseStudentSigninLogId,jdbcType=BIGINT}, #{teacherOpenCourseStudentSigninSettingId,jdbcType=BIGINT}, - #{teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, #{studentId,jdbcType=BIGINT}, + #{teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, #{studentId,jdbcType=VARCHAR}, #{teacherOpenCourseId,jdbcType=BIGINT}, #{schoolClassId,jdbcType=BIGINT}, #{teacherOpenCourseStudentSigninLogAddTime,jdbcType=TIMESTAMP}, #{teacherOpenCourseStudentSigninLogType,jdbcType=VARCHAR}, #{teacherOpenCourseStudentSigninLogRemark,jdbcType=VARCHAR}, #{teacherOpenCourseStudentSigninLogIp,jdbcType=VARCHAR}, #{teacherOpenCourseStudentSigninLogTag,jdbcType=INTEGER}, @@ -179,7 +179,7 @@ #{teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, - #{studentId,jdbcType=BIGINT}, + #{studentId,jdbcType=VARCHAR}, #{teacherOpenCourseId,jdbcType=BIGINT}, @@ -229,7 +229,7 @@ teacher_open_course_student_signin_setting_session_time = #{record.teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, - student_id = #{record.studentId,jdbcType=BIGINT}, + student_id = #{record.studentId,jdbcType=VARCHAR}, teacher_open_course_id = #{record.teacherOpenCourseId,jdbcType=BIGINT}, @@ -268,7 +268,7 @@ set teacher_open_course_student_signin_log_id = #{record.teacherOpenCourseStudentSigninLogId,jdbcType=BIGINT}, teacher_open_course_student_signin_setting_id = #{record.teacherOpenCourseStudentSigninSettingId,jdbcType=BIGINT}, teacher_open_course_student_signin_setting_session_time = #{record.teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, - student_id = #{record.studentId,jdbcType=BIGINT}, + student_id = #{record.studentId,jdbcType=VARCHAR}, teacher_open_course_id = #{record.teacherOpenCourseId,jdbcType=BIGINT}, school_class_id = #{record.schoolClassId,jdbcType=BIGINT}, teacher_open_course_student_signin_log_add_time = #{record.teacherOpenCourseStudentSigninLogAddTime,jdbcType=TIMESTAMP}, @@ -292,7 +292,7 @@ teacher_open_course_student_signin_setting_session_time = #{teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, - student_id = #{studentId,jdbcType=BIGINT}, + student_id = #{studentId,jdbcType=VARCHAR}, teacher_open_course_id = #{teacherOpenCourseId,jdbcType=BIGINT}, @@ -328,7 +328,7 @@ update teacher_open_course_student_signin_log set teacher_open_course_student_signin_setting_id = #{teacherOpenCourseStudentSigninSettingId,jdbcType=BIGINT}, teacher_open_course_student_signin_setting_session_time = #{teacherOpenCourseStudentSigninSettingSessionTime,jdbcType=TIMESTAMP}, - student_id = #{studentId,jdbcType=BIGINT}, + student_id = #{studentId,jdbcType=VARCHAR}, teacher_open_course_id = #{teacherOpenCourseId,jdbcType=BIGINT}, school_class_id = #{schoolClassId,jdbcType=BIGINT}, teacher_open_course_student_signin_log_add_time = #{teacherOpenCourseStudentSigninLogAddTime,jdbcType=TIMESTAMP}, diff --git a/src/test/java/com/sztzjy/Tset.java b/src/test/java/com/sztzjy/Tset.java new file mode 100644 index 0000000..d1c9968 --- /dev/null +++ b/src/test/java/com/sztzjy/Tset.java @@ -0,0 +1,22 @@ +package com.sztzjy;/** + * @author 17803 + * @date 2024-08-09 8:52 + */ + +import org.junit.jupiter.api.Test; + +/** + * @projectName: digital_trade + * @package: com.sztzjy + * @className: Tset + * @author: WangHaoBo + * @description: TODO + * @date: 2024/8/9 8:52 + */ +public class Tset { + + + + @Test + public void +}