main
cxy 1 month ago
parent d495df1a6f
commit 5b4ddc5bf8

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-log</artifactId>
<dependencies>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,39 @@
package com.cxy.classroll.common.annotaion;
import com.cxy.classroll.common.enums.BusinessType;
import com.cxy.classroll.common.enums.OperatorType;
import java.lang.annotation.*;
/**
*
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
*
*/
public String title() default "";
/**
*
*/
public BusinessType businessType() default BusinessType.OTHER;
/**
*
*/
public OperatorType operatorType() default OperatorType.MANAGE;
/**
*
*/
public boolean isSaveRequestData() default true;
/**
*
*/
public boolean isSaveResponseData() default true;
}

@ -0,0 +1,51 @@
package com.cxy.classroll.common.enums;
/**
*
*/
public enum BusinessType {
/**
*
*/
OTHER,
/**
*
*/
INSERT,
/**
*
*/
UPDATE,
/**
*
*/
DELETE,
/**
*
*/
ASSGIN,
/**
*
*/
EXPORT,
/**
*
*/
IMPORT,
/**
*
*/
STATUS,
/**
*
*/
CLEAN,
}

@ -0,0 +1,20 @@
package com.cxy.classroll.common.enums;
/**
*
*/
public enum OperatorType {
/**
*
*/
OTHER,
/**
*
*/
MANAGE,
/**
*
*/
MOBILE
}

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-util</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,77 @@
package com.cxy.classroll.common.result;
import lombok.Data;
@Data
public class Result<T> {
//返回码
private Integer code;
//返回消息
private String message;
//返回数据
private T data;
public Result(){}
// 返回数据
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null)
result.setData(data);
return result;
}
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = build(body);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
return result;
}
public static<T> Result<T> ok(){
return Result.ok(null);
}
/**
*
* @param data baseCategory1List
* @param <T>
* @return
*/
public static<T> Result<T> ok(T data){
return build(data, ResultCodeEnum.SUCCESS);
}
public static<T> Result<T> fail(){
return Result.fail(null);
}
/**
*
* @param data
* @param <T>
* @return
*/
public static<T> Result<T> fail(T data){
return build(data, ResultCodeEnum.FAIL);
}
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
}

@ -0,0 +1,32 @@
package com.cxy.classroll.common.result;
import lombok.Getter;
@Getter
public enum ResultCodeEnum {
SUCCESS(200,"成功"),
FAIL(201, "失败"),
SERVICE_ERROR(2012, "服务异常"),
DATA_ERROR(204, "数据异常"),
ILLEGAL_REQUEST(205, "非法请求"),
REPEAT_SUBMIT(206, "重复提交"),
FEIGN_FAIL(207, "远程调用失败"),
UPDATE_ERROR(204, "数据更新失败"),
ARGUMENT_VALID_ERROR(210, "参数校验异常"),
LOGIN_AUTH(208, "未登陆"),
PERMISSION(209, "没有权限"),
ACCOUNT_ERROR(214, "账号不正确"),
PASSWORD_ERROR(215, "密码不正确"),
;
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}

@ -0,0 +1,19 @@
package com.cxy.classroll.common.util;
/**
*
*/
public class AuthContextHolder {
private static ThreadLocal<Long> userId = new ThreadLocal<Long>();
public static void setUserId(Long _userId) {
userId.set(_userId);
}
public static Long getUserId() {
return userId.get();
}
public static void removeUserId() {
userId.remove();
}
}

@ -0,0 +1,29 @@
package com.cxy.classroll.common.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5 {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错+" + e);
}
}
}

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<packaging>pom</packaging>
<modules>
<module>common-log</module>
<module>common-util</module>
<module>service-util</module>
</modules>
</project>

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-util</artifactId>
<dependencies>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<!-- 校验参数 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 服务调用feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<scope>provided </scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,34 @@
package com.cxy.classroll.common.config.knife4j;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public GroupedOpenApi webApi() {
return GroupedOpenApi.builder()
.group("web-api")
.pathsToMatch("/**")
.build();
}
/***
* @description
*/
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("课堂点名小程序接口文档")
.version("1.0")
.description("课堂点名小程序接口文档")
.contact(new Contact().name("cxy")));
}
}

@ -0,0 +1,30 @@
package com.cxy.classroll.common.config.mybatisPlus;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MybatisPlus
*
*/
@EnableTransactionManagement
@Configuration
@MapperScan("com.cxy.classroll.*.mapper")
public class MybatisPlusConfig {
/**
*
* @return
*/
@Bean
public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//向Mybatis过滤器链中添加分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

@ -0,0 +1,89 @@
package com.cxy.classroll.common.config.redis;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import java.lang.reflect.Method;
import java.time.Duration;
/**
* Redis
*
*/
@Configuration
@EnableCaching
public class RedisConfig {
// 使用默认标签做缓存
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@Bean
@Primary
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//String的序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 使用GenericJackson2JsonRedisSerializer 替换默认序列化(默认采用的是JDK序列化)
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//序列号key value
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600000))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}

@ -0,0 +1,45 @@
package com.cxy.classroll.common.config.redisson;
import lombok.Data;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedissonConfig {
private String host;
private String password;
private String port;
private int timeout = 3000;
private static String ADDRESS_PREFIX = "redis://";
/**
*
*
*/
@Bean
RedissonClient redissonSingle() {
Config config = new Config();
if(!StringUtils.hasText(host)){
throw new RuntimeException("host is empty");
}
SingleServerConfig serverConfig = config.useSingleServer()
.setAddress(ADDRESS_PREFIX + this.host + ":" + port)
.setTimeout(this.timeout);
if(StringUtils.hasText(this.password)) {
serverConfig.setPassword(this.password);
}
return Redisson.create(config);
}
}

@ -0,0 +1,10 @@
package com.cxy.classroll.common.constant;
public class RedisConstant {
//用户登录
public static final String USER_LOGIN_KEY_PREFIX = "user:login:";
public static final String USER_LOGIN_REFRESH_KEY_PREFIX = "user:login:refresh:";
public static final int USER_LOGIN_KEY_TIMEOUT = 60 * 60 * 24 * 100;
public static final int USER_LOGIN_REFRESH_KEY_TIMEOUT = 60 * 60 * 24 * 365;
}

@ -0,0 +1,40 @@
package com.cxy.classroll.common.execption;
import com.cxy.classroll.common.result.ResultCodeEnum;
import lombok.Data;
@Data
public class CxyException extends RuntimeException{
private Integer code;
private String message;
/**
*
* @param code
* @param message
*/
public CxyException(Integer code, String message) {
super(message);
this.code = code;
this.message = message;
}
/**
*
* @param resultCodeEnum
*/
public CxyException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
this.message = resultCodeEnum.getMessage();
}
@Override
public String toString() {
return "GuliException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}

@ -0,0 +1,98 @@
package com.cxy.classroll.common.handler;
import com.cxy.classroll.common.execption.CxyException;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.common.result.ResultCodeEnum;
import feign.codec.DecodeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e){
e.printStackTrace();
return Result.fail();
}
/**
*
* @param e
* @return
*/
@ExceptionHandler(CxyException.class)
@ResponseBody
public Result error(CxyException e){
e.printStackTrace();
return Result.build(null,e.getCode(), e.getMessage());
}
@ExceptionHandler(DecodeException.class)
@ResponseBody
public Result error(DecodeException e){
e.printStackTrace();
return Result.build(null,e.status(), e.getMessage());
}
@ExceptionHandler({IllegalArgumentException.class})
@ResponseBody
public Result llegalArgumentException(Exception e) {
e.printStackTrace();
log.error("触发异常拦截: " + e.getMessage(), e);
return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
}
// /**
// * spring security异常
// * @param e
// * @return
// */
// @ExceptionHandler(AccessDeniedException.class)
// @ResponseBody
// public Result error(AccessDeniedException e) throws AccessDeniedException {
// return Result.build(null, ResultCodeEnum.PERMISSION);
// }
@ExceptionHandler(value = BindException.class)
@ResponseBody
public Result error(BindException exception) {
BindingResult result = exception.getBindingResult();
Map<String, Object> errorMap = new HashMap<>();
List<FieldError> fieldErrors = result.getFieldErrors();
fieldErrors.forEach(error -> {
log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
errorMap.put(error.getField(), error.getDefaultMessage());
});
return Result.build(errorMap, ResultCodeEnum.ARGUMENT_VALID_ERROR);
}
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseBody
public Result error(MethodArgumentNotValidException exception) {
BindingResult result = exception.getBindingResult();
Map<String, Object> errorMap = new HashMap<>();
List<FieldError> fieldErrors = result.getFieldErrors();
fieldErrors.forEach(error -> {
log.error("field: " + error.getField() + ", msg:" + error.getDefaultMessage());
errorMap.put(error.getField(), error.getDefaultMessage());
});
return Result.build(errorMap, ResultCodeEnum.ARGUMENT_VALID_ERROR);
}
}

@ -0,0 +1,12 @@
package com.cxy.classroll.common.login;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//登录判断
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CxyLogin {
}

@ -0,0 +1,55 @@
package com.cxy.classroll.common.login;
import com.cxy.classroll.common.constant.RedisConstant;
import com.cxy.classroll.common.execption.CxyException;
import com.cxy.classroll.common.result.ResultCodeEnum;
import com.cxy.classroll.common.util.AuthContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Component
@Aspect //切面类
public class CxyLoginAspect {
@Autowired
private RedisTemplate redisTemplate;
//环绕通知,登录判断
//切入点表达式:指定对哪些规则的方法进行增强
@Around("execution(* com.cxy.classroll.*.controller.*.*(..)) && @annotation(cxyLogin)")
public Object login(ProceedingJoinPoint proceedingJoinPoint, CxyLogin cxyLogin) throws Throwable {
//1 获取request对象
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes)attributes;
HttpServletRequest request = sra.getRequest();
//2 从请求头获取token
String token = request.getHeader("token");
//3 判断token是否为空如果为空返回登录提示
if(!StringUtils.hasText(token)) {
throw new CxyException(ResultCodeEnum.LOGIN_AUTH);
}
//4 token不为空查询redis
String customerId = (String)redisTemplate.opsForValue()
.get(RedisConstant.USER_LOGIN_KEY_PREFIX+token);
//5 查询redis对应用户id把用户id放到ThreadLocal里面
if(StringUtils.hasText(customerId)) {
AuthContextHolder.setUserId(Long.parseLong(customerId));
}
//6 执行业务方法
return proceedingJoinPoint.proceed();
}
}

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>model</artifactId>
<dependencies>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided </scope>
</dependency>
<!-- 校验参数 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,37 @@
package com.cxy.classroll.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
@Schema(description = "lesson")
public class Lesson {
private static final long serialVersionUID = 1L;
@TableField("id")
@TableId(type = IdType.AUTO)
@Schema(description = "课程id")
private Long id;
@Schema(description = "课程名字")
@TableField("lesson_name")
private String lesson_name;
@Schema(description = "老师主键id")
@TableField("teacher_id")
private Long teacher_id;
@Schema(description = "课程状态0没上课1正在上课")
@TableField("status")
private Integer status;
@Schema(description = "点名状态0没点名1正在点名")
@TableField("roll")
private Integer roll;
}

@ -0,0 +1,21 @@
package com.cxy.classroll.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "stu_lesson")
public class Stu_lesson {
private static final long serialVersionUID = 1L;
@TableField(value = "student_no")
@Schema(description = "学生学号")
private String student_no;
@TableField(value = "lesson_name")
@Schema(description = "课程名")
private String lesson_name;
}

@ -0,0 +1,41 @@
package com.cxy.classroll.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "user")
public class User {
private static final long serialVersionUID = 1L;
@TableField("id")
@TableId(type = IdType.AUTO)
private Long id;
@Schema(description = "微信openid")
@TableField("wx_open_id")
private String wx_open_id;
@Schema(description = "学工号")
@TableField("no")
private String no;
@Schema(description = "姓名")
@TableField("name")
private String name;
@Schema(description = "学校")
@TableField("school")
private String school;
@Schema(description = "积分")
@TableField("score")
private int score;
@Schema(description = "身份")
@TableField("identify")
private int identify;
}

@ -0,0 +1,32 @@
package com.cxy.classroll.model.form;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
@Data
@Schema(description = "认证表单")
public class AuthenticationForm {
@Schema(description = "用户id")
@JsonProperty(value = "id")
private Long id;
@Schema(description = "用户姓名")
@JsonProperty(value = "name")
private String name;
@Schema(description = "用户学校")
@JsonProperty(value = "school")
private String school;
@Schema(description = "身份")
@JsonProperty(value = "identify")
private int identify;
@Schema(description = "学工号")
@JsonProperty(value = "no")
private String no;
}

@ -0,0 +1,19 @@
package com.cxy.classroll.model.vo;
import com.opencsv.bean.CsvBindByName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "课程名单csv数据")
public class CsvData {
@Schema(description = "学生学号")
@CsvBindByName(column = "学号")
private String student_no;
@Schema(description = "学生姓名")
@CsvBindByName(column = "姓名")
private String name;
}

@ -0,0 +1,25 @@
package com.cxy.classroll.model.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
public class CustomerLoginVo {
@Schema(description = "微信openid")
private String wx_open_id;
@Schema(description = "学工号")
private String no;
@Schema(description = "姓名")
private String name;
@Schema(description = "学校")
private String school;
@Schema(description = "积分")
private int score;
}

@ -0,0 +1,15 @@
package com.cxy.classroll.model.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
public class FileParam {
@JsonProperty(value = "lesson_name")
private String lesson_name;
@JsonProperty(value = "teacher_id")
private Long teacher_id;
private MultipartFile multipartFile;
}

@ -0,0 +1,9 @@
package com.cxy.classroll.model.vo;
import lombok.Data;
@Data
public class IdentifyAndID {
private int identify;
private Long id;
}

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
</parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<modules>
<module>common</module>
</modules>
<properties>
<java.version>17</java.version>
<cloud.version>2022.0.2</cloud.version>
<alibaba.version>2022.0.0.0-RC2</alibaba.version>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<mysql.version>8.0.30</mysql.version>
<knife4j.version>4.1.0</knife4j.version>
<fastjson.version>2.0.41</fastjson.version>
<vod_api.version>2.1.4</vod_api.version>
<minio.version>8.5.2</minio.version>
<jodatime.version>2.10.1</jodatime.version>
<xxl-job.version>2.4.0</xxl-job.version>
<wxpay.version>0.2.11</wxpay.version>
<weixin.miniapp.version>4.5.5.B</weixin.miniapp.version>
<tencentcloud.version>3.1.322</tencentcloud.version>
<cos_api.version>5.6.155</cos_api.version>
<redisson.version>3.23.3</redisson.version>
<commons-io.version>2.11.0</commons-io.version>
<!-- https://seata.io/zh-cn/docs/overview/what-is-seata.html -->
<seata.version>1.7.1</seata.version>
<drools.version>8.41.0.Final</drools.version>
</properties>
<!--配置dependencyManagement锁定依赖的版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--mybatis-plus 持久层-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--knife4j https://doc.xiaominfo.com/docs/quick-start-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 腾讯云VOD -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>vod_api</artifactId>
<version>${vod_api.version}</version>
</dependency>
<!-- minio -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime.version}</version>
</dependency>
<!-- xxl-job -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job.version}</version>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>${wxpay.version}</version>
</dependency>
<!-- redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>${weixin.miniapp.version}</version>
</dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>${tencentcloud.version}</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>${cos_api.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>${seata.version}</version>
</dependency>
<!-- drools lib -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.3.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>server-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>server-gateway</name>
<dependencies>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 服务调用feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 服务注册 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,17 @@
package com.cxy.classroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class ServerGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ServerGatewayApplication.class, args);
}
}

@ -0,0 +1,25 @@
package com.cxy.classroll.gateway.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}

@ -0,0 +1,7 @@
spring.application.name=server-gateway-classroll
spring.profiles.active=dev
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>service-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>service-student-client</module>
<module>service-teacher-client</module>
</modules>
<dependencies>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<!-- 服务调用feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-student-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
</project>

@ -0,0 +1,60 @@
package com.cxy.classroll.student.client;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.FileParam;
import com.cxy.classroll.model.vo.IdentifyAndID;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@FeignClient(value = "service-student")
public interface StudentFeignClient {
@GetMapping("/student/common/login/{code}")
public Result<IdentifyAndID> login(@PathVariable String code);
@PostMapping("/student/common/authentication")
public Result<Boolean> authentication(@RequestBody AuthenticationForm authenticationForm);
@GetMapping("/student/common/userinfo/{id}")
public Result<User> getUserInfo(@PathVariable Long id);
@GetMapping("/student/lessonlist/{id}")
public Result<List<Lesson>> getStudentLessons(@PathVariable Long id);
@GetMapping("/student/studentsignin/{userid}/{lessonid}")
public Result<Boolean> StudentSignInClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid);
@GetMapping("/student/studentsignout/{userid}/{lessonid}")
public Result<Boolean> StudentSignOutClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid);
@GetMapping("/student/lessonstatus/{lessonid}")
public Result<Integer> LessonStatus(@PathVariable Long lessonid);
@GetMapping("/student/lessonroll/{lessonid}")
public Result<Integer> LessonRoll(@PathVariable Long lessonid);
@PostMapping(value = "/student/uploadcsv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<Boolean> uploadCsv(@RequestPart("multipartFile") MultipartFile multipartFile ,
@RequestParam("teacher_id") Long teacher_id,
@RequestParam("lesson_name") String lesson_name);
@GetMapping("/student/classroll/{lessonid}/{roll_method}")
public Result<String> classRoll(@PathVariable(value = "lessonid") Long lessonid, @PathVariable(value = "roll_method")int roll_method);
@GetMapping("/student/scorerank")
public Result<List<User>> scoreRank();
@GetMapping("/student/comment/{lesson_id}/{student_no}/{score}")
public Result<Boolean> comment(@PathVariable(value = "lesson_id") Long lesson_id, @PathVariable(value = "student_no") String student_no,
@PathVariable(value = "score") int score);
@GetMapping("/student/getnolist/{lesson_id}")
public Result<List<String>> getNoList(@PathVariable(value = "lesson_id") Long lessonid);
}

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-teacher-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
</project>

@ -0,0 +1,22 @@
package com.cxy.classroll.teacher.client;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.model.entity.Lesson;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@FeignClient(value = "service-teacher")
public interface TeacherFeignClient {
@GetMapping("/teacher/getteacherlessonlist/{id}")
public Result<List<Lesson>> getTeacherLessonList(@PathVariable Long id);
@GetMapping("/teacher/classstart/{lessonid}")
public Result<Boolean> classStart(@PathVariable Long lessonid);
@GetMapping("/teacher/classend/{lessonid}")
public Result<Boolean> classEnd(@PathVariable Long lessonid);
}

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service</artifactId>
<packaging>pom</packaging>
<modules>
<module>service-student</module>
<module>service-teacher</module>
</modules>
<dependencies>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-log</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-student-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-teacher-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 服务调用feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 服务注册 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 流量控制 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-student</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.3.2</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,17 @@
package com.cxy.classroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceStudentApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceStudentApplication.class, args);
}
}

@ -0,0 +1,27 @@
package com.cxy.classroll.student.config;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class WxConfigOperator {
@Autowired
private WxConfigProperties wxConfigProperties;
@Bean
public WxMaService wxMaService() {
//微信小程序id和秘钥
WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
wxMaConfig.setAppid(wxConfigProperties.getAppId());
wxMaConfig.setSecret(wxConfigProperties.getSecret());
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(wxMaConfig);
return service;
}
}

@ -0,0 +1,13 @@
package com.cxy.classroll.student.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxConfigProperties {
private String appId;
private String secret;
}

@ -0,0 +1,117 @@
package com.cxy.classroll.student.controller;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.FileParam;
import com.cxy.classroll.model.vo.IdentifyAndID;
import com.cxy.classroll.student.service.CommonService;
import com.cxy.classroll.student.service.LessonInfoService;
import com.cxy.classroll.student.service.StuLessonService;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/student")
//不只有针对学生的服务接口,一些教师和学生共享的通用接口也放这
public class StudentController {
@Autowired
private StuLessonService studentService;
@Autowired
private CommonService commonService;
@Autowired
private LessonInfoService lessonInfoService;
//微信小程序登录接口
@Operation(summary = "小程序授权登录")
@GetMapping("/common/login/{code}")
public Result<IdentifyAndID> login(@PathVariable String code) {
return Result.ok(commonService.login(code));
}
@Operation(summary = "身份校验")
@PostMapping("/common/authentication")
public Result<Boolean> authentication(@RequestBody AuthenticationForm authenticationForm){
return Result.ok(commonService.authentication(authenticationForm));
}
@Operation(summary = "我的页面个人信息获取")
@GetMapping("/common/userinfo/{id}")
public Result<User> getUserInfo(@PathVariable Long id){
return Result.ok(commonService.getUserInfo(id));
}
@Operation(summary = "学生课程页面课程信息列表")
@GetMapping("/lessonlist/{id}")
public Result<List<Lesson>> getStudentLessons(@PathVariable Long id){
return Result.ok(studentService.getStudentLessons(id));
}
@Operation(summary = "学生课堂签到")
@GetMapping("/studentsignin/{userid}/{lessonid}")
public Result<Boolean> StudentSignInClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid){
return Result.ok(commonService.studentSignInClass(userid, lessonid));
}
@Operation(summary = "学生课堂签退")
@GetMapping("/studentsignout/{userid}/{lessonid}")
public Result<Boolean> StudentSignOutClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid){
return Result.ok(commonService.studentSignOutClass(userid, lessonid));
}
@Operation(summary = "监听课程状态")
@GetMapping("/lessonstatus/{lessonid}")
public Result<Integer> LessonStatus(@PathVariable Long lessonid){
return Result.ok(lessonInfoService.listenLessonStatus(lessonid));
}
@Operation(summary = "监听课程点名状态")
@GetMapping("/lessonroll/{lessonid}")
public Result<Integer> LessonRoll(@PathVariable Long lessonid){
return Result.ok(lessonInfoService.listenLessonRoll(lessonid));
}
@Operation(summary = "解析csv数据")
@PostMapping(value = "/uploadcsv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<Boolean> uploadCsv(@RequestPart("multipartFile") MultipartFile multipartFile ,
@RequestParam("teacher_id") Long teacher_id,
@RequestParam("lesson_name") String lesson_name){
return Result.ok(studentService.uploadCsvData(multipartFile,teacher_id,lesson_name));
}
@Operation(summary = "课堂随机点名")
@GetMapping("/classroll/{lessonid}/{roll_method}")
public Result<String> classRoll(@PathVariable(value = "lessonid") Long lessonid, @PathVariable(value = "roll_method")int roll_method){
return Result.ok(commonService.classroll(lessonid, roll_method));
}
@Operation(summary = "积分排行榜")
@GetMapping("/scorerank")
public Result<List<User>> scoreRank(){
return Result.ok(commonService.scoreRank());
}
@Operation(summary = "教师打分评价")
@GetMapping("/comment/{lesson_id}/{student_no}/{score}")
public Result<Boolean> comment(@PathVariable(value = "lesson_id") Long lesson_id, @PathVariable(value = "student_no") String student_no,
@PathVariable(value = "score") int score){
return Result.ok(commonService.teacherComment(lesson_id, student_no, score));
}
@Operation(summary = "获取课堂对应的学号信息")
@GetMapping("/getnolist/{lesson_id}")
public Result<List<String>> getNoList(@PathVariable(value = "lesson_id") Long lessonid){
return Result.ok(commonService.leesonStudentNoList(lessonid));
}
}

@ -0,0 +1,9 @@
package com.cxy.classroll.student.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxy.classroll.model.entity.Lesson;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface LessonInfoMapper extends BaseMapper<Lesson> {
}

@ -0,0 +1,9 @@
package com.cxy.classroll.student.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxy.classroll.model.entity.Stu_lesson;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StuLessonMapper extends BaseMapper<Stu_lesson> {
}

@ -0,0 +1,9 @@
package com.cxy.classroll.student.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxy.classroll.model.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

@ -0,0 +1,31 @@
package com.cxy.classroll.student.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.IdentifyAndID;
import java.util.List;
public interface CommonService extends IService<User> {
//微信小程序登录接口
IdentifyAndID login(String code);
Boolean authentication(AuthenticationForm authenticationForm);
User getUserInfo(Long id);
Boolean updateUserScore(Long id, int scoreChange);
Boolean studentSignInClass(Long user_id, Long lesson_id);
Boolean studentSignOutClass(Long user_id, Long lesson_id);
String classroll(Long lesson_id, int roll_method);
List<User> scoreRank();
Boolean teacherComment(Long lesosn_id, String student_no, int score);
List<String> leesonStudentNoList(Long lesson_id);
}

@ -0,0 +1,14 @@
package com.cxy.classroll.student.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cxy.classroll.model.entity.Lesson;
public interface LessonInfoService extends IService<Lesson> {
Lesson getLessonInfoByLessonName(String lesson_name);
Lesson getLessonInfoById(Long lesson_id);
Integer listenLessonStatus(Long lesson_id);
Integer listenLessonRoll(Long lesson_id);
}

@ -0,0 +1,17 @@
package com.cxy.classroll.student.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.Stu_lesson;
import com.cxy.classroll.model.vo.FileParam;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface StuLessonService extends IService<Stu_lesson> {
List<Lesson> getStudentLessons(Long id);
Boolean uploadCsvData(MultipartFile file,Long teacher_id,String lesson_name);
List<Stu_lesson> getStuLessonListByLessonName(String lesson_name);
}

@ -0,0 +1,241 @@
package com.cxy.classroll.student.service.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.Stu_lesson;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.IdentifyAndID;
import com.cxy.classroll.student.mapper.LessonInfoMapper;
import com.cxy.classroll.student.mapper.StuLessonMapper;
import com.cxy.classroll.student.mapper.UserMapper;
import com.cxy.classroll.student.service.CommonService;
import com.cxy.classroll.student.service.LessonInfoService;
import com.cxy.classroll.student.service.StuLessonService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
@Slf4j
@Service
public class CommonServiceImpl extends ServiceImpl<UserMapper, User> implements CommonService {
@Autowired
private WxMaService wxMaService;
@Autowired
private UserMapper userMapper;
@Autowired
private LessonInfoService lessonInfoService;
@Autowired
private StuLessonMapper stuLessonMapper;
@Autowired
private LessonInfoMapper lessonInfoMapper;
@Override
public IdentifyAndID login(String code) {
IdentifyAndID identifyAndID = new IdentifyAndID();
String openid = null;
try {
WxMaJscode2SessionResult sessionInfo =
wxMaService.getUserService().getSessionInfo(code);
openid = sessionInfo.getOpenid();
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getWx_open_id,openid);
User user = userMapper.selectOne(wrapper);
if (user == null){
user = new User();
user.setWx_open_id(openid);
user.setIdentify(0);
user.setScore(0);
userMapper.insert(user);
identifyAndID.setId(user.getId());
identifyAndID.setIdentify(0);
return identifyAndID;
}
identifyAndID.setId(user.getId());
identifyAndID.setIdentify(user.getIdentify());
return identifyAndID;
}
@Override
public Boolean authentication(AuthenticationForm authenticationForm) {
Long id = authenticationForm.getId();
User user = userMapper.selectById(id);
if (user == null){
return false;
}
user.setIdentify(authenticationForm.getIdentify());
user.setNo(authenticationForm.getNo());
user.setName(authenticationForm.getName());
user.setSchool(authenticationForm.getSchool());
user.setScore(1);
userMapper.updateById(user);
return true;
}
@Override
public User getUserInfo(Long id) {
User user = userMapper.selectById(id);
return user;
}
@Override
public Boolean updateUserScore(Long id, int scoreChange) {
User user = userMapper.selectById(id);
int score = user.getScore();
score += scoreChange;
user.setScore(score);
int i = userMapper.updateById(user);
if (i == 0){
return false;
}
return true;
}
@Override
public Boolean studentSignInClass(Long user_id, Long lesson_id) {
Integer status = lessonInfoService.listenLessonStatus(lesson_id);
if (status == 0){
return false;
}
Boolean updateRes = updateUserScore(user_id, 1);
if (!updateRes){
return false;
}
return true;
}
@Override
public Boolean studentSignOutClass(Long user_id, Long lesson_id) {
Integer status = lessonInfoService.listenLessonStatus(lesson_id);
if (status == 1 ){
return false;
}
return true;
}
@Override
public String classroll(Long lesson_id, int roll_method) {
List<User> students = new ArrayList<>();
Lesson lesson = lessonInfoService.getLessonInfoById(lesson_id);
LambdaQueryWrapper<Stu_lesson> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Stu_lesson::getLesson_name, lesson.getLesson_name());
List<Stu_lesson> stuLessonListByLessonName = stuLessonMapper.selectList(queryWrapper);
for(Stu_lesson stuLesson:stuLessonListByLessonName){
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getNo, stuLesson.getStudent_no());
User user = userMapper.selectOne(wrapper);
if (user == null){
continue;
}
students.add(user);
}
if (roll_method == 1){
double totalWeight = students.stream().mapToDouble(student -> 1.0 / student.getScore()).sum();
Random random = new Random();
double randomWeight = random.nextDouble();
double cumulativeWeight = 0.0;
for (User student : students) {
cumulativeWeight += (1.0 / student.getScore()) / totalWeight;
if (randomWeight < cumulativeWeight) {
LambdaUpdateWrapper<Lesson> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Lesson::getId,lesson.getId()).set(Lesson::getRoll,student.getNo());
lessonInfoMapper.update(null,updateWrapper);
return student.getNo();
}
}
return null;
}
if (roll_method == 2){
LocalDate today = LocalDate.now();
boolean isOddDay = today.getDayOfMonth() % 2 != 0;
// 根据日期的奇偶性调整权重
List<User> weightedStudents = students.stream()
.flatMap(student -> {
boolean isOddId = Integer.parseInt(student.getNo().trim()) % 2 != 0;
int weight = (isOddDay == isOddId) ? 3 : 1; // 奇数日奇数学生权重为3偶数学生权重为1
return java.util.stream.Stream.generate(() -> student).limit(weight);
}).collect(Collectors.toList());
// 从加权后的学生列表中随机选择一个学生
Random random = new Random();
int randomIndex = random.nextInt(weightedStudents.size());
LambdaUpdateWrapper<Lesson> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Lesson::getId,lesson.getId()).set(Lesson::getRoll,Integer.parseInt(weightedStudents.get(randomIndex).getNo()));
lessonInfoMapper.update(null,updateWrapper);
return weightedStudents.get(randomIndex).getNo();
}
return null;
}
@Override
public List<User> scoreRank() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getIdentify,1);
wrapper.orderByDesc(User::getScore);
return userMapper.selectList(wrapper);
}
@Override
public Boolean teacherComment(Long lesson_id, String student_no, int score) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getNo, student_no);
User user = userMapper.selectOne(wrapper);
if (user == null){
return false;
}
int score1 = user.getScore();
score1 += score;
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(User::getScore,score1)
.eq(User::getNo, student_no);
int update = userMapper.update(null, updateWrapper);
if (update == 0){
return false;
}
LambdaUpdateWrapper<Lesson> lessonUpdateWrapper = new LambdaUpdateWrapper<>();
lessonUpdateWrapper.set(Lesson::getRoll, 0)
.eq(Lesson::getId, lesson_id);
int updateLessonRoll = lessonInfoMapper.update(null, lessonUpdateWrapper);
if (updateLessonRoll == 0){
return false;
}
return true;
}
@Override
public List<String> leesonStudentNoList(Long lesson_id) {
List<String> studentNoList = new ArrayList<>();
Lesson lesson = lessonInfoService.getLessonInfoById(lesson_id);
LambdaQueryWrapper<Stu_lesson> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Stu_lesson::getLesson_name, lesson.getLesson_name());
List<Stu_lesson> stuLessonListByLessonName = stuLessonMapper.selectList(queryWrapper);
for(Stu_lesson stuLesson:stuLessonListByLessonName){
studentNoList.add(stuLesson.getStudent_no());
}
return studentNoList;
}
}

@ -0,0 +1,44 @@
package com.cxy.classroll.student.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.Stu_lesson;
import com.cxy.classroll.student.mapper.LessonInfoMapper;
import com.cxy.classroll.student.mapper.StuLessonMapper;
import com.cxy.classroll.student.service.LessonInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class LessonInfoServiceImpl extends ServiceImpl<LessonInfoMapper, Lesson> implements LessonInfoService {
@Autowired
LessonInfoMapper lessonInfoMapper;
@Override
public Lesson getLessonInfoByLessonName(String lesson_name) {
LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Lesson::getLesson_name, lesson_name);
Lesson lesson = lessonInfoMapper.selectOne(wrapper);
return lesson;
}
@Override
public Lesson getLessonInfoById(Long lesson_id) {
return lessonInfoMapper.selectById(lesson_id);
}
@Override
public Integer listenLessonStatus(Long lesson_id) {
Lesson lesson = lessonInfoMapper.selectById(lesson_id);
return lesson.getStatus();
}
@Override
public Integer listenLessonRoll(Long lesson_id) {
Lesson lesson = lessonInfoMapper.selectById(lesson_id);
return lesson.getRoll();
}
}

@ -0,0 +1,131 @@
package com.cxy.classroll.student.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.Stu_lesson;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.vo.CsvData;
import com.cxy.classroll.model.vo.FileParam;
import com.cxy.classroll.student.mapper.LessonInfoMapper;
import com.cxy.classroll.student.mapper.StuLessonMapper;
import com.cxy.classroll.student.mapper.UserMapper;
import com.cxy.classroll.student.service.CommonService;
import com.cxy.classroll.student.service.LessonInfoService;
import com.cxy.classroll.student.service.StuLessonService;
import com.cxy.classroll.student.util.CsvUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Slf4j
@Service
public class StuLessonServiceImpl extends ServiceImpl<StuLessonMapper, Stu_lesson> implements StuLessonService {
@Autowired
CommonService commonService;
@Autowired
LessonInfoService lessonInfoService;
@Autowired
StuLessonMapper stuLessonMapper;
@Autowired
UserMapper userMapper;
@Autowired
LessonInfoMapper lessonInfoMapper;
@Override
public List<Lesson> getStudentLessons(Long id) {
List<Lesson> lessons_list = new ArrayList<>();
User userInfo = commonService.getUserInfo(id);
String no = userInfo.getNo();
LambdaQueryWrapper<Stu_lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Stu_lesson::getStudent_no,no);
List<Stu_lesson> stuLessons = stuLessonMapper.selectList(wrapper);
for (Stu_lesson stuLesson : stuLessons) {
if (stuLesson != null) {
System.out.println(stuLesson);
String lessonName = stuLesson.getLesson_name();
Lesson lesson = lessonInfoService.getLessonInfoByLessonName(lessonName);
lessons_list.add(lesson);
}
}
return lessons_list;
}
@Override
public Boolean uploadCsvData(MultipartFile file,Long teacher_id,String lesson_name) {
int dotIndex = lesson_name.lastIndexOf('.');
if (dotIndex>0){
lesson_name=lesson_name.substring(0,dotIndex);
}
LambdaQueryWrapper<Lesson> lessonQueryWrapper = new LambdaQueryWrapper<>();
lessonQueryWrapper.eq(Lesson::getLesson_name,lesson_name);
lessonQueryWrapper.eq(Lesson::getTeacher_id,teacher_id);
Lesson lesson = lessonInfoMapper.selectOne(lessonQueryWrapper);
if (lesson == null){
Lesson lesson1 = new Lesson();
lesson1.setRoll(0);
lesson1.setStatus(0);
lesson1.setLesson_name(lesson_name);
lesson1.setTeacher_id(teacher_id);
int insert = lessonInfoMapper.insert(lesson1);
if (insert == 0){
return false;
}
}
CsvUtil csvUtil = new CsvUtil();
List<CsvData> csvDataList = csvUtil.getCsvDataManually(file);
for (CsvData csvData: csvDataList){
Stu_lesson stuLesson = new Stu_lesson();
LambdaQueryWrapper<Stu_lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Stu_lesson::getStudent_no,csvData.getStudent_no());
wrapper.eq(Stu_lesson::getLesson_name,lesson_name);
Stu_lesson res = stuLessonMapper.selectOne(wrapper);
if (res == null){
stuLesson.setLesson_name(lesson_name);
stuLesson.setStudent_no(csvData.getStudent_no());
int insert = stuLessonMapper.insert(stuLesson);
if (insert == 0){
return false;
}
}
}
// for (CsvData csvData: csvDataList){
// Random random = new Random();
// User user = new User();
// LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
// wrapper.eq(User::getNo,csvData.getStudent_no());
// wrapper.eq(User::getName,csvData.getName());
// User res = userMapper.selectOne(wrapper);
// if (res == null){
// user.setName(csvData.getName());
// user.setIdentify(1);
// user.setNo(csvData.getStudent_no());
// user.setSchool("福州大学");
// user.setScore(random.nextInt(100) + 1);
// int insert = userMapper.insert(user);
// if (insert == 0){
// return false;
// }
// }
// }
return true;
}
@Override
public List<Stu_lesson> getStuLessonListByLessonName(String lesson_name) {
LambdaQueryWrapper<Stu_lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Stu_lesson::getLesson_name, lesson_name);
return stuLessonMapper.selectList(wrapper);
}
}

@ -0,0 +1,38 @@
package com.cxy.classroll.student.util;
import com.cxy.classroll.common.execption.CxyException;
import com.cxy.classroll.model.vo.CsvData;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class CsvUtil {
public <T> List<CsvData> getCsvDataManually(MultipartFile file) {
List<CsvData> csvDataList = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
String headerLine = reader.readLine(); // 读取并跳过第一行
String line;
while ((line = reader.readLine()) != null) {
String[] values = line.split(",");
CsvData csvData = new CsvData();
csvData.setStudent_no(values[0]);
csvData.setName(values[1]);
csvDataList.add(csvData);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return csvDataList;
}
}

@ -0,0 +1,8 @@
spring.application.name=service-student
spring.profiles.active=dev
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.shared-configs[0].data-id=common-account.yaml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-teacher</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,17 @@
package com.cxy.classroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceTeacherApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceTeacherApplication.class, args);
}
}

@ -0,0 +1,27 @@
package com.cxy.classroll.teacher.config;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class WxConfigOperator {
@Autowired
private WxConfigProperties wxConfigProperties;
@Bean
public WxMaService wxMaService() {
//微信小程序id和秘钥
WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
wxMaConfig.setAppid(wxConfigProperties.getAppId());
wxMaConfig.setSecret(wxConfigProperties.getSecret());
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(wxMaConfig);
return service;
}
}

@ -0,0 +1,13 @@
package com.cxy.classroll.teacher.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxConfigProperties {
private String appId;
private String secret;
}

@ -0,0 +1,44 @@
package com.cxy.classroll.teacher.controller;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.vo.IdentifyAndID;
import com.cxy.classroll.teacher.service.TeacherLessonService;
import io.swagger.v3.oas.annotations.Operation;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/teacher")
//教师数据接口
public class TeacherController {
@Autowired
TeacherLessonService teacherLessonService;
@Operation(summary = "教师教授课程列表获取")
@GetMapping("/getteacherlessonlist/{id}")
public Result<List<Lesson>> getTeacherLessonList(@PathVariable Long id) {
return Result.ok(teacherLessonService.getTeacherLessons(id));
}
@Operation(summary = "开始上课")
@GetMapping("/classstart/{lessonid}")
public Result<Boolean> classStart(@PathVariable Long lessonid){
return Result.ok(teacherLessonService.lessonStart(lessonid));
}
@Operation(summary = "结束上课")
@GetMapping("/classend/{lessonid}")
public Result<Boolean> classEnd(@PathVariable Long lessonid){
return Result.ok(teacherLessonService.lessonEnd(lessonid));
}
}

@ -0,0 +1,9 @@
package com.cxy.classroll.teacher.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxy.classroll.model.entity.Lesson;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TeacherLessonMapper extends BaseMapper<Lesson> {
}

@ -0,0 +1,9 @@
package com.cxy.classroll.teacher.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxy.classroll.model.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

@ -0,0 +1,14 @@
package com.cxy.classroll.teacher.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cxy.classroll.model.entity.Lesson;
import java.util.List;
public interface TeacherLessonService extends IService<Lesson> {
List<Lesson> getTeacherLessons(Long teacher_id);
Boolean lessonStart(Long lesson_id);
Boolean lessonEnd(Long lesson_id);
}

@ -0,0 +1,8 @@
package com.cxy.classroll.teacher.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cxy.classroll.model.entity.User;
public interface UserService extends IService<User> {
Boolean updateUserScore(Long id, int scoreChange);
}

@ -0,0 +1,71 @@
package com.cxy.classroll.teacher.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.teacher.mapper.TeacherLessonMapper;
import com.cxy.classroll.teacher.service.TeacherLessonService;
import com.cxy.classroll.teacher.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.rmi.dgc.Lease;
import java.util.List;
@Service
@Slf4j
public class TeacherLessonServiceImpl extends ServiceImpl<TeacherLessonMapper, Lesson> implements TeacherLessonService {
@Autowired
TeacherLessonMapper teacherLessonMapper;
@Autowired
UserService userService;
@Override
public List<Lesson> getTeacherLessons(Long teacher_id) {
LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Lesson::getTeacher_id, teacher_id);
return teacherLessonMapper.selectList(wrapper);
}
@Override
public Boolean lessonStart(Long lesson_id) {
LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Lesson::getId,lesson_id);
Lesson lesson = teacherLessonMapper.selectOne(wrapper);
Integer status = lesson.getStatus();
if (status == 1){
return false;
}
lesson.setStatus(1);
int i = teacherLessonMapper.updateById(lesson);
if (i==0){
return false;
}
Long teacherId = lesson.getTeacher_id();
Boolean res = userService.updateUserScore(teacherId, 1);
if (!res){
return false;
}
return true;
}
@Override
public Boolean lessonEnd(Long lesson_id) {
LambdaQueryWrapper<Lesson> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Lesson::getId,lesson_id);
Lesson lesson = teacherLessonMapper.selectOne(wrapper);
Integer status = lesson.getStatus();
if (status == 0){
return false;
}
lesson.setStatus(0);
int i = teacherLessonMapper.updateById(lesson);
if (i==0){
return false;
}
return true;
}
}

@ -0,0 +1,29 @@
package com.cxy.classroll.teacher.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.teacher.mapper.UserMapper;
import com.cxy.classroll.teacher.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
UserMapper userMapper;
@Override
public Boolean updateUserScore(Long id, int scoreChange) {
User user = userMapper.selectById(id);
int score = user.getScore();
score += scoreChange;
user.setScore(score);
int i = userMapper.updateById(user);
if (i == 0){
return false;
}
return true;
}
}

@ -0,0 +1,8 @@
spring.application.name=service-teacher
spring.profiles.active=dev
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.shared-configs[0].data-id=common-account.yaml

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>classroll-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>common-log</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-teacher-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cxy.classroll</groupId>
<artifactId>service-student-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 服务注册 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 流量控制 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>web</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>web-student</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>web-student</name>
<description>web-student</description>
<packaging>jar</packaging>
<build>
<finalName>web-student</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,18 @@
package com.cxy.classroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableFeignClients
@EnableDiscoveryClient
public class WebStudentApplication {
public static void main(String[] args) {
SpringApplication.run(WebStudentApplication.class, args);
}
}

@ -0,0 +1,116 @@
package com.cxy.classroll.student.controller;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.FileParam;
import com.cxy.classroll.model.vo.IdentifyAndID;
import com.cxy.classroll.student.service.CommonWebService;
import com.cxy.classroll.student.service.StudentWebService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.annotation.MultipartConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@Slf4j
@Tag(name = "学生及通用API接口管理")
@RestController
@RequestMapping("/student")
public class StudentWebController {
@Autowired
private CommonWebService commonWebService;
@Autowired
private StudentWebService studentWebService;
@Operation(summary = "小程序授权登录")
@GetMapping("/common/login/{code}")
public Result<IdentifyAndID> wxLogin(@PathVariable String code) {
return Result.ok(commonWebService.login(code));
}
@Operation(summary = "身份登记验证")
@PostMapping("/common/authentication")
public Result<Boolean> authentication(@RequestBody AuthenticationForm authenticationForm){
return Result.ok(commonWebService.authentication(authenticationForm));
}
@Operation(summary = "我的主页用户信息获取")
@GetMapping("/common/getUserInfo/{id}")
public Result<User> getUserInfo(@PathVariable Long id){
return Result.ok(commonWebService.getUserInfo(id));
}
@Operation(summary = "学生课程列表信息获取")
@GetMapping("/lessonlist/{id}")
public Result<List<Lesson>> getStudentLessons(@PathVariable Long id){
return Result.ok(studentWebService.getStudentLessons(id));
}
@Operation(summary = "学生课堂签到")
@GetMapping("/studentsignin/{userid}/{lessonid}")
public Result<Boolean> StudentSignInClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid){
return Result.ok(commonWebService.studentSignInClass(userid, lessonid));
}
@Operation(summary = "学生课堂签退")
@GetMapping("/studentsignout/{userid}/{lessonid}")
public Result<Boolean> StudentSignOutClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid){
return Result.ok(commonWebService.studentSignOutClass(userid, lessonid));
}
@Operation(summary = "监听课程状态")
@GetMapping("/lessonstatus/{lessonid}")
public Result<Integer> LessonStatus(@PathVariable Long lessonid){
return Result.ok(commonWebService.listenLessonStatus(lessonid));
}
@Operation(summary = "监听课程点名")
@GetMapping("/lessonroll/{lessonid}")
public Result<Integer> LessonRoll(@PathVariable Long lessonid){
return Result.ok(commonWebService.listenLessonRoll(lessonid));
}
@Operation(summary = "上传学生csv名单文件")
@PostMapping("/uploadcsv")
public Result<Boolean> uploadCsv(@RequestParam("multipartFile") MultipartFile multipartFile ,
@RequestParam("teacher_id") Long teacher_id,
@RequestParam("lesson_name") String lesson_name){
System.out.println(teacher_id);
System.out.println(lesson_name);
return Result.ok(studentWebService.uploadCsvData(multipartFile,teacher_id, lesson_name));
}
@Operation(summary = "课堂点名")
@GetMapping("/classroll/{lessonid}/{roll_method}")
public Result<String> classRoll(@PathVariable(value = "lessonid") Long lessonid, @PathVariable(value = "roll_method")int roll_method){
return Result.ok(commonWebService.classRoll(lessonid, roll_method));
}
@Operation(summary = "积分排行榜")
@GetMapping("/scorerank")
public Result<List<User>> scoreRank(){
return Result.ok(commonWebService.scoreRank());
}
@Operation(summary = "教师打分评价")
@GetMapping("/comment/{lesson_id}/{student_no}/{score}")
public Result<Boolean> comment(@PathVariable(value = "lesson_id") Long lesson_id, @PathVariable(value = "student_no") String student_no,
@PathVariable(value = "score") int score){
return Result.ok(commonWebService.teacherComment(lesson_id, student_no, score));
}
@Operation(summary = "获取对应课程的学号列表")
@GetMapping("/getnolist/{lesson_id}")
public Result<List<String>> getNoList(@PathVariable(value = "lesson_id") Long lessonid){
return Result.ok(commonWebService.leesonStudentNoList(lessonid));
}
}

@ -0,0 +1,31 @@
package com.cxy.classroll.student.service;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.IdentifyAndID;
import java.util.List;
public interface CommonWebService {
IdentifyAndID login(String code);
Boolean authentication(AuthenticationForm authenticationForm);
User getUserInfo(Long id);
Boolean studentSignInClass(Long user_id, Long lesson_id);
Boolean studentSignOutClass(Long user_id, Long lesson_id);
Integer listenLessonStatus(Long lesson_id);
Integer listenLessonRoll(Long lesson_id);
String classRoll(Long lesson_id, int roll_method);
List<User> scoreRank();
Boolean teacherComment(Long lesosn_id, String student_no, int score);
List<String> leesonStudentNoList(Long lesson_id);
}

@ -0,0 +1,14 @@
package com.cxy.classroll.student.service;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.vo.FileParam;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface StudentWebService {
List<Lesson> getStudentLessons(Long id);
Boolean uploadCsvData(MultipartFile multipartFile, Long teacher_id, String lesson_name);
}

@ -0,0 +1,170 @@
package com.cxy.classroll.student.service.impl;
import com.cxy.classroll.common.execption.CxyException;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.common.result.ResultCodeEnum;
import com.cxy.classroll.model.entity.User;
import com.cxy.classroll.model.form.AuthenticationForm;
import com.cxy.classroll.model.vo.IdentifyAndID;
import com.cxy.classroll.student.client.StudentFeignClient;
import com.cxy.classroll.student.service.CommonWebService;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class CommonWebServiceImpl implements CommonWebService {
@Autowired
private StudentFeignClient client;
@Autowired
private StudentFeignClient studentFeignClient;
@Override
public IdentifyAndID login(String code) {
Result<IdentifyAndID> loginResult = client.login(code);
Integer codeResult = loginResult.getCode();
if (codeResult!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
IdentifyAndID data = loginResult.getData();
Long id = data.getId();
if (id == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Boolean authentication(AuthenticationForm authenticationForm) {
Result<Boolean> result = studentFeignClient.authentication(authenticationForm);
if (result.getData()){
return true;
}else {
return false;
}
}
@Override
public User getUserInfo(Long id) {
Result<User> result = client.getUserInfo(id);
Integer code = result.getCode();
if (code!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
User data = result.getData();
if (data == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Boolean studentSignInClass(Long user_id, Long lesson_id) {
Result<Boolean> result = studentFeignClient.StudentSignInClass(user_id, lesson_id);
Integer code = result.getCode();
if (code!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
Boolean data = result.getData();
if (data == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Boolean studentSignOutClass(Long user_id, Long lesson_id) {
Result<Boolean> result = studentFeignClient.StudentSignOutClass(user_id, lesson_id);
Integer code = result.getCode();
if (code!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
Boolean data = result.getData();
if (data == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Integer listenLessonStatus(Long lesson_id) {
Result<Integer> result = studentFeignClient.LessonStatus(lesson_id);
if (result.getCode()!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
if (result.getData() == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
@Override
public Integer listenLessonRoll(Long lesson_id) {
Result<Integer> result = studentFeignClient.LessonRoll(lesson_id);
if (result.getCode()!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
if (result.getData() ==null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
@Override
public String classRoll(Long lesson_id, int roll_method) {
Result<String> result = studentFeignClient.classRoll(lesson_id, roll_method);
if (result.getCode() != 200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
if (result.getData() ==null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
@Override
public List<User> scoreRank() {
Result<List<User>> result = studentFeignClient.scoreRank();
if (result.getCode() != 200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
if (result.getData() == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
@Override
public Boolean teacherComment(Long lesosn_id, String student_no, int score) {
Result<Boolean> result = studentFeignClient.comment(lesosn_id, student_no, score);
if (result.getCode() != 200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
if (result.getData() == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
@Override
public List<String> leesonStudentNoList(Long lesson_id) {
Result<List<String>> result = studentFeignClient.getNoList(lesson_id);
if (result.getCode() != 200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
if (result.getData() == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
}

@ -0,0 +1,53 @@
package com.cxy.classroll.student.service.impl;
import com.cxy.classroll.common.execption.CxyException;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.common.result.ResultCodeEnum;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.vo.FileParam;
import com.cxy.classroll.student.client.StudentFeignClient;
import com.cxy.classroll.student.service.StudentWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class StudentWebServiceImpl implements StudentWebService {
@Autowired
private StudentFeignClient studentFeignClient;
@Override
public List<Lesson> getStudentLessons(Long id) {
Result<List<Lesson>> result = studentFeignClient.getStudentLessons(id);
Integer code = result.getCode();
if (code!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
List<Lesson> data = result.getData();
if (data == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Boolean uploadCsvData(MultipartFile multipartFile,Long teacher_id, String lesson_name) {
FileParam fileParam = new FileParam();
fileParam.setMultipartFile(multipartFile);
fileParam.setLesson_name(lesson_name);
fileParam.setTeacher_id(teacher_id);
Result<Boolean> result = studentFeignClient.uploadCsv(multipartFile, teacher_id, lesson_name);
if (result.getCode()!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return result.getData();
}
}

@ -0,0 +1,8 @@
spring.application.name=web-student
spring.profiles.active=dev
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.shared-configs[0].data-id=common-account.yaml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.cxy.classroll</groupId>
<artifactId>web</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>web-teacher</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>web-teacher</name>
<description>web-teacher</description>
<packaging>jar</packaging>
<build>
<finalName>web-teacher</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,18 @@
package com.cxy.classroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
@EnableFeignClients
public class WebTeacherApplication {
public static void main(String[] args) {
SpringApplication.run(WebTeacherApplication.class, args);
}
}

@ -0,0 +1,44 @@
package com.cxy.classroll.teacher.controller;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.model.vo.IdentifyAndID;
import com.cxy.classroll.teacher.service.TeacherWebService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@Tag(name = "教师接口管理")
@RestController
@RequestMapping("/teacher")
public class TeacherWebController {
@Autowired
TeacherWebService teacherWebService;
@Operation(summary = "教师教授课程列表")
@GetMapping("/getteacherlessonlist/{id}")
public Result<List<Lesson>> getTeacherLessonList(@PathVariable Long id) {
return Result.ok(teacherWebService.getTeacherLessonsList(id));
}
@Operation(summary = "开始上课")
@GetMapping("/classstart/{leesonid}")
public Result<Boolean> classStart(@PathVariable Long leesonid){
return Result.ok(teacherWebService.lessonStart(leesonid));
}
@Operation(summary = "结束上课")
@GetMapping("/classend/{lessonid}")
public Result<Boolean> classEnd(@PathVariable Long lessonid){
return Result.ok(teacherWebService.lessonEnd(lessonid));
}
}

@ -0,0 +1,14 @@
package com.cxy.classroll.teacher.service;
import com.cxy.classroll.model.entity.Lesson;
import java.util.List;
public interface TeacherWebService {
List<Lesson> getTeacherLessonsList(Long id);
Boolean lessonStart(Long lesson_id);
Boolean lessonEnd(Long lesson_id);
}

@ -0,0 +1,61 @@
package com.cxy.classroll.teacher.service.impl;
import com.cxy.classroll.common.execption.CxyException;
import com.cxy.classroll.common.result.Result;
import com.cxy.classroll.common.result.ResultCodeEnum;
import com.cxy.classroll.model.entity.Lesson;
import com.cxy.classroll.teacher.client.TeacherFeignClient;
import com.cxy.classroll.teacher.service.TeacherWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class TeacherWebServiceImpl implements TeacherWebService {
@Autowired
TeacherFeignClient teacherFeignClient;
@Override
public List<Lesson> getTeacherLessonsList(Long id) {
Result<List<Lesson>> result = teacherFeignClient.getTeacherLessonList(id);
Integer code = result.getCode();
if (code != 200) {
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
List<Lesson> data = result.getData();
if (data == null) {
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Boolean lessonStart(Long lesson_id) {
Result<Boolean> result = teacherFeignClient.classStart(lesson_id);
if (result.getCode()!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
Boolean data = result.getData();
if (data == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
@Override
public Boolean lessonEnd(Long lesson_id) {
Result<Boolean> result = teacherFeignClient.classEnd(lesson_id);
if (result.getCode()!=200){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
Boolean data = result.getData();
if (data == null){
throw new CxyException(ResultCodeEnum.DATA_ERROR);
}
return data;
}
}

@ -0,0 +1,8 @@
spring.application.name=web-teacher
spring.profiles.active=dev
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.server-addr=192.168.176.125:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.shared-configs[0].data-id=common-account.yaml

@ -0,0 +1,43 @@
server:
port: 8600
feign:
sentinel:
enabled: true
spring:
cloud:
openfeign:
lazy-attributes-resolution: true
client:
config:
default:
connectTimeout: 30000
readTimeout: 30000
loggerLevel: basic
gateway:
discovery: #是否与服务发现组件进行结合,通过 serviceId(必须设置成大写) 转发到具体的服务实例。默认为false设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能。
locator: #路由访问方式http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问。
enabled: true
globalcors:
cors-configurations:
'[/**]':
allowedOriginPatterns: "*"
# 允许请求中携带的头信息
allowedHeaders: "*"
# 运行跨域的请求方式
allowedMethods: "*"
# 跨域检测的有效期,单位s
maxAge: 36000
routes:
# web 接口
- id: web-student
uri: lb://web-student
predicates:
- Path=/student-api/**
filters:
- StripPrefix=1
- id: web-teacher
uri: lb://teacher-driver
predicates:
- Path=/teacher-api/**
filters:
- StripPrefix=1

@ -0,0 +1,58 @@
server:
port: 8501
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
feign:
sentinel:
enabled: true
spring:
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
cloud:
openfeign:
lazy-attributes-resolution: true #开启懒加载,否则启动报错
client:
config:
default:
connectTimeout: 30000
readTimeout: 30000
loggerLevel: basic
data:
redis:
host: 192.168.176.125
port: 6379
database: 0
timeout: 1800000
password:
jedis:
pool:
max-active: 20 #最大连接数
max-wait: -1 #最大阻塞等待时间(负数表示没限制)
max-idle: 5 #最大空闲
min-idle: 0 #最小空闲
rabbitmq:
host: 192.168.176.125
port: 5672
username: guest
password: guest
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.176.125:3306/class_roll?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
hikari:
connection-test-query: SELECT 1
connection-timeout: 60000
idle-timeout: 500000
max-lifetime: 540000
maximum-pool-size: 10
minimum-idle: 5
pool-name: GuliHikariPool
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
seata:
tx-service-group: daijia_tx_group
enable-auto-data-source-proxy: false

@ -0,0 +1,58 @@
server:
port: 8501
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
feign:
sentinel:
enabled: true
spring:
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
cloud:
openfeign:
lazy-attributes-resolution: true #开启懒加载,否则启动报错
client:
config:
default:
connectTimeout: 30000
readTimeout: 30000
loggerLevel: basic
data:
redis:
host: 192.168.176.125
port: 6379
database: 0
timeout: 1800000
password:
jedis:
pool:
max-active: 20 #最大连接数
max-wait: -1 #最大阻塞等待时间(负数表示没限制)
max-idle: 5 #最大空闲
min-idle: 0 #最小空闲
rabbitmq:
host: 192.168.176.125
port: 5672
username: guest
password: guest
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.176.125:3306/class_roll?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
hikari:
connection-test-query: SELECT 1
connection-timeout: 60000
idle-timeout: 500000
max-lifetime: 540000
maximum-pool-size: 10
minimum-idle: 5
pool-name: GuliHikariPool
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
seata:
tx-service-group: daijia_tx_group
enable-auto-data-source-proxy: false

@ -0,0 +1,47 @@
server:
port: 8601
feign:
sentinel:
enabled: true
spring:
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
cloud:
openfeign:
lazy-attributes-resolution: true #开启懒加载,否则启动报错
client:
config:
default:
connectTimeout: 30000
readTimeout: 30000
loggerLevel: basic
rabbitmq:
host: 192.168.176.125
port: 5672
username: guest
password: guest
publisher-confirm-type: correlated
publisher-returns: true
data:
redis:
host: 192.168.176.125
port: 6379
database: 0
timeout: 1800000
password:
jedis:
pool:
max-active: 20 #最大连接数
max-wait: -1 #最大阻塞等待时间(负数表示没限制)
max-idle: 5 #最大空闲
min-idle: 0 #最小空闲
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
servlet:
multipart:
max-file-size: 10MB #单个文件最大限制
max-request-size: 20MB #多个文件最大限制
seata:
tx-service-group: daijia_tx_group
enable-auto-data-source-proxy: false

@ -0,0 +1,47 @@
server:
port: 8601
feign:
sentinel:
enabled: true
spring:
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
cloud:
openfeign:
lazy-attributes-resolution: true #开启懒加载,否则启动报错
client:
config:
default:
connectTimeout: 30000
readTimeout: 30000
loggerLevel: basic
rabbitmq:
host: 192.168.176.125
port: 5672
username: guest
password: guest
publisher-confirm-type: correlated
publisher-returns: true
data:
redis:
host: 192.168.176.125
port: 6379
database: 0
timeout: 1800000
password:
jedis:
pool:
max-active: 20 #最大连接数
max-wait: -1 #最大阻塞等待时间(负数表示没限制)
max-idle: 5 #最大空闲
min-idle: 0 #最小空闲
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
servlet:
multipart:
max-file-size: 10MB #单个文件最大限制
max-request-size: 20MB #多个文件最大限制
seata:
tx-service-group: daijia_tx_group
enable-auto-data-source-proxy: false
Loading…
Cancel
Save