diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -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 diff --git a/backend/classroll-parent/.gitignore b/backend/classroll-parent/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/backend/classroll-parent/.gitignore @@ -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/ diff --git a/backend/classroll-parent/common/common-log/pom.xml b/backend/classroll-parent/common/common-log/pom.xml new file mode 100644 index 0000000..13e4993 --- /dev/null +++ b/backend/classroll-parent/common/common-log/pom.xml @@ -0,0 +1,38 @@ + + + + com.cxy.classroll + common + 0.0.1-SNAPSHOT + + 4.0.0 + + common-log + + + + com.cxy.classroll + model + 0.0.1-SNAPSHOT + provided + + + com.cxy.classroll + common-util + 0.0.1-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter-web + provided + + + org.springframework.boot + spring-boot-starter-aop + provided + + + + diff --git a/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/annotaion/Log.java b/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/annotaion/Log.java new file mode 100644 index 0000000..3246b05 --- /dev/null +++ b/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/annotaion/Log.java @@ -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; +} diff --git a/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/enums/BusinessType.java b/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/enums/BusinessType.java new file mode 100644 index 0000000..c805ae1 --- /dev/null +++ b/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/enums/BusinessType.java @@ -0,0 +1,51 @@ +package com.cxy.classroll.common.enums; +/** + * 业务操作类型 + */ +public enum BusinessType { + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + ASSGIN, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + + /** + * 更新状态 + */ + STATUS, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/enums/OperatorType.java b/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/enums/OperatorType.java new file mode 100644 index 0000000..303ab80 --- /dev/null +++ b/backend/classroll-parent/common/common-log/src/main/java/com/cxy/classroll/common/enums/OperatorType.java @@ -0,0 +1,20 @@ +package com.cxy.classroll.common.enums; +/** + * 操作人类别 + */ +public enum OperatorType { + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/backend/classroll-parent/common/common-util/pom.xml b/backend/classroll-parent/common/common-util/pom.xml new file mode 100644 index 0000000..819ee57 --- /dev/null +++ b/backend/classroll-parent/common/common-util/pom.xml @@ -0,0 +1,38 @@ + + + + com.cxy.classroll + common + 0.0.1-SNAPSHOT + + 4.0.0 + + common-util + jar + + + + org.springframework.boot + spring-boot-starter-web + provided + + + org.projectlombok + lombok + + + com.alibaba + fastjson + + + joda-time + joda-time + + + commons-io + commons-io + + + + diff --git a/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/result/Result.java b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/result/Result.java new file mode 100644 index 0000000..b0f0a68 --- /dev/null +++ b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/result/Result.java @@ -0,0 +1,77 @@ +package com.cxy.classroll.common.result; + +import lombok.Data; + +@Data +public class Result { + //返回码 + private Integer code; + + //返回消息 + private String message; + + //返回数据 + private T data; + + public Result(){} + + // 返回数据 + protected static Result build(T data) { + Result result = new Result(); + if (data != null) + result.setData(data); + return result; + } + + public static Result build(T body, Integer code, String message) { + Result result = build(body); + result.setCode(code); + result.setMessage(message); + return result; + } + + public static Result build(T body, ResultCodeEnum resultCodeEnum) { + Result result = build(body); + result.setCode(resultCodeEnum.getCode()); + result.setMessage(resultCodeEnum.getMessage()); + return result; + } + + public static Result ok(){ + return Result.ok(null); + } + + /** + * 操作成功 + * @param data baseCategory1List + * @param + * @return + */ + public static Result ok(T data){ + return build(data, ResultCodeEnum.SUCCESS); + } + + public static Result fail(){ + return Result.fail(null); + } + + /** + * 操作失败 + * @param data + * @param + * @return + */ + public static Result fail(T data){ + return build(data, ResultCodeEnum.FAIL); + } + + public Result message(String msg){ + this.setMessage(msg); + return this; + } + + public Result code(Integer code){ + this.setCode(code); + return this; + } +} diff --git a/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/result/ResultCodeEnum.java b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/result/ResultCodeEnum.java new file mode 100644 index 0000000..ec2e91b --- /dev/null +++ b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/result/ResultCodeEnum.java @@ -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; + } +} diff --git a/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/util/AuthContextHolder.java b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/util/AuthContextHolder.java new file mode 100644 index 0000000..70bd609 --- /dev/null +++ b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/util/AuthContextHolder.java @@ -0,0 +1,19 @@ +package com.cxy.classroll.common.util; +/** + * 获取当前用户信息帮助类 + */ +public class AuthContextHolder { + private static ThreadLocal userId = new ThreadLocal(); + + public static void setUserId(Long _userId) { + userId.set(_userId); + } + + public static Long getUserId() { + return userId.get(); + } + + public static void removeUserId() { + userId.remove(); + } +} diff --git a/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/util/MD5.java b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/util/MD5.java new file mode 100644 index 0000000..8c68893 --- /dev/null +++ b/backend/classroll-parent/common/common-util/src/main/java/com/cxy/classroll/common/util/MD5.java @@ -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); + } + } +} diff --git a/backend/classroll-parent/common/pom.xml b/backend/classroll-parent/common/pom.xml new file mode 100644 index 0000000..1086f39 --- /dev/null +++ b/backend/classroll-parent/common/pom.xml @@ -0,0 +1,20 @@ + + + + com.cxy.classroll + classroll-parent + 0.0.1-SNAPSHOT + + 4.0.0 + + common + pom + + + common-log + common-util + service-util + + + diff --git a/backend/classroll-parent/common/service-util/pom.xml b/backend/classroll-parent/common/service-util/pom.xml new file mode 100644 index 0000000..bf9b29a --- /dev/null +++ b/backend/classroll-parent/common/service-util/pom.xml @@ -0,0 +1,76 @@ + + + + com.cxy.classroll + common + 0.0.1-SNAPSHOT + + 4.0.0 + + service-util + + + + com.cxy.classroll + common-util + 0.0.1-SNAPSHOT + + + com.cxy.classroll + model + 0.0.1-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-web + + + com.baomidou + mybatis-plus-boot-starter + + + + mysql + mysql-connector-java + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.redisson + redisson + + + + org.springframework.boot + spring-boot-starter-aop + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + provided + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + provided + + + + diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/knife4j/Knife4jConfig.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/knife4j/Knife4jConfig.java new file mode 100644 index 0000000..9fdc5e4 --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/knife4j/Knife4jConfig.java @@ -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"))); + } + +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/mybatisPlus/MybatisPlusConfig.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/mybatisPlus/MybatisPlusConfig.java new file mode 100644 index 0000000..1c6d6a3 --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/mybatisPlus/MybatisPlusConfig.java @@ -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; + } +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/redis/RedisConfig.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/redis/RedisConfig.java new file mode 100644 index 0000000..39944cb --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/redis/RedisConfig.java @@ -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 redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate 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 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; + } +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/redisson/RedissonConfig.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/redisson/RedissonConfig.java new file mode 100644 index 0000000..6ef8c7d --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/config/redisson/RedissonConfig.java @@ -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); + } +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/constant/RedisConstant.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/constant/RedisConstant.java new file mode 100644 index 0000000..fa3075e --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/constant/RedisConstant.java @@ -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; + +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/execption/CxyException.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/execption/CxyException.java new file mode 100644 index 0000000..92953e7 --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/execption/CxyException.java @@ -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() + + '}'; + } +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/handler/GlobalExceptionHandler.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..e002099 --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/handler/GlobalExceptionHandler.java @@ -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 errorMap = new HashMap<>(); + List 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 errorMap = new HashMap<>(); + List 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); + } + +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/login/CxyLogin.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/login/CxyLogin.java new file mode 100644 index 0000000..411bac7 --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/login/CxyLogin.java @@ -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 { +} diff --git a/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/login/CxyLoginAspect.java b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/login/CxyLoginAspect.java new file mode 100644 index 0000000..ae405e2 --- /dev/null +++ b/backend/classroll-parent/common/service-util/src/main/java/com/cxy/classroll/common/login/CxyLoginAspect.java @@ -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(); + } +} diff --git a/backend/classroll-parent/model/pom.xml b/backend/classroll-parent/model/pom.xml new file mode 100644 index 0000000..05d7c54 --- /dev/null +++ b/backend/classroll-parent/model/pom.xml @@ -0,0 +1,57 @@ + + + + com.cxy.classroll + classroll-parent + 0.0.1-SNAPSHOT + + 4.0.0 + + model + + + + + org.projectlombok + lombok + + + com.cxy.classroll + common-util + 0.0.1-SNAPSHOT + provided + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + provided + + + com.baomidou + mybatis-plus-boot-starter + provided + + + + org.springframework.boot + spring-boot-starter-validation + provided + + + org.springframework.boot + spring-boot-starter-data-elasticsearch + provided + + + org.springframework.boot + spring-boot-starter-data-mongodb + provided + + + com.opencsv + opencsv + + + + diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/Lesson.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/Lesson.java new file mode 100644 index 0000000..98717e8 --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/Lesson.java @@ -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; + +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/Stu_lesson.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/Stu_lesson.java new file mode 100644 index 0000000..9f07cac --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/Stu_lesson.java @@ -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; +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/User.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/User.java new file mode 100644 index 0000000..ddbed88 --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/entity/User.java @@ -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; +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/form/AuthenticationForm.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/form/AuthenticationForm.java new file mode 100644 index 0000000..e859591 --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/form/AuthenticationForm.java @@ -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; +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/CsvData.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/CsvData.java new file mode 100644 index 0000000..4770471 --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/CsvData.java @@ -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; + +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/CustomerLoginVo.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/CustomerLoginVo.java new file mode 100644 index 0000000..415e59b --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/CustomerLoginVo.java @@ -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; +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/FileParam.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/FileParam.java new file mode 100644 index 0000000..56502c3 --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/FileParam.java @@ -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; +} diff --git a/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/IdentifyAndID.java b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/IdentifyAndID.java new file mode 100644 index 0000000..027f5ef --- /dev/null +++ b/backend/classroll-parent/model/src/main/java/com/cxy/classroll/model/vo/IdentifyAndID.java @@ -0,0 +1,9 @@ +package com.cxy.classroll.model.vo; + +import lombok.Data; + +@Data +public class IdentifyAndID { + private int identify; + private Long id; +} diff --git a/backend/classroll-parent/pom.xml b/backend/classroll-parent/pom.xml new file mode 100644 index 0000000..2c92c88 --- /dev/null +++ b/backend/classroll-parent/pom.xml @@ -0,0 +1,197 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.0.5 + + com.cxy.classroll + classroll-parent + pom + 0.0.1-SNAPSHOT + + + common + + + + 17 + 2022.0.2 + 2022.0.0.0-RC2 + 3.5.3.1 + 8.0.30 + 4.1.0 + 2.0.41 + 2.1.4 + 8.5.2 + 2.10.1 + 2.4.0 + + 0.2.11 + 4.5.5.B + 3.1.322 + 5.6.155 + + 3.23.3 + 2.11.0 + + + 1.7.1 + 8.41.0.Final + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${alibaba.version} + pom + import + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + mysql + mysql-connector-java + ${mysql.version} + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + ${knife4j.version} + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + com.qcloud + vod_api + ${vod_api.version} + + + + + io.minio + minio + ${minio.version} + + + + + joda-time + joda-time + ${jodatime.version} + + + + + com.xuxueli + xxl-job-core + ${xxl-job.version} + + + + com.github.wechatpay-apiv3 + wechatpay-java + ${wxpay.version} + + + + + org.redisson + redisson + ${redisson.version} + + + + com.github.binarywang + weixin-java-miniapp + ${weixin.miniapp.version} + + + + com.tencentcloudapi + tencentcloud-sdk-java + ${tencentcloud.version} + + + com.qcloud + cos_api + ${cos_api.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + io.seata + seata-all + ${seata.version} + + + + + org.drools + drools-core + ${drools.version} + + + org.drools + drools-compiler + ${drools.version} + + + org.drools + drools-decisiontables + ${drools.version} + + + org.drools + drools-mvel + ${drools.version} + + + com.opencsv + opencsv + 4.3.2 + + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + diff --git a/backend/classroll-parent/server-gateway/pom.xml b/backend/classroll-parent/server-gateway/pom.xml new file mode 100644 index 0000000..fb1e37d --- /dev/null +++ b/backend/classroll-parent/server-gateway/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + + com.cxy.classroll + classroll-parent + 0.0.1-SNAPSHOT + + + server-gateway + 0.0.1-SNAPSHOT + + jar + server-gateway + + + + com.cxy.classroll + common-util + 0.0.1-SNAPSHOT + + + com.cxy.classroll + model + 0.0.1-SNAPSHOT + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/backend/classroll-parent/server-gateway/src/main/java/com/cxy/classroll/ServerGatewayApplication.java b/backend/classroll-parent/server-gateway/src/main/java/com/cxy/classroll/ServerGatewayApplication.java new file mode 100644 index 0000000..847b2f2 --- /dev/null +++ b/backend/classroll-parent/server-gateway/src/main/java/com/cxy/classroll/ServerGatewayApplication.java @@ -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); + } + +} diff --git a/backend/classroll-parent/server-gateway/src/main/java/com/cxy/classroll/gateway/filter/AuthGlobalFilter.java b/backend/classroll-parent/server-gateway/src/main/java/com/cxy/classroll/gateway/filter/AuthGlobalFilter.java new file mode 100644 index 0000000..9187e6e --- /dev/null +++ b/backend/classroll-parent/server-gateway/src/main/java/com/cxy/classroll/gateway/filter/AuthGlobalFilter.java @@ -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 filter(ServerWebExchange exchange, GatewayFilterChain chain) { + return chain.filter(exchange); + } + + @Override + public int getOrder() { + return 0; + } +} \ No newline at end of file diff --git a/backend/classroll-parent/server-gateway/src/main/resources/bootstrap.properties b/backend/classroll-parent/server-gateway/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..7f349f3 --- /dev/null +++ b/backend/classroll-parent/server-gateway/src/main/resources/bootstrap.properties @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/service-client/pom.xml b/backend/classroll-parent/service-client/pom.xml new file mode 100644 index 0000000..0e093ab --- /dev/null +++ b/backend/classroll-parent/service-client/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + + com.cxy.classroll + classroll-parent + 0.0.1-SNAPSHOT + + + service-client + 0.0.1-SNAPSHOT + pom + + + service-student-client + service-teacher-client + + + + + com.cxy.classroll + common-util + 0.0.1-SNAPSHOT + + + com.cxy.classroll + model + 0.0.1-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-web + provided + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + provided + + + + diff --git a/backend/classroll-parent/service-client/service-student-client/pom.xml b/backend/classroll-parent/service-client/service-student-client/pom.xml new file mode 100644 index 0000000..baade32 --- /dev/null +++ b/backend/classroll-parent/service-client/service-student-client/pom.xml @@ -0,0 +1,15 @@ + + + + com.cxy.classroll + service-client + 0.0.1-SNAPSHOT + + 4.0.0 + + service-student-client + 0.0.1-SNAPSHOT + jar + + diff --git a/backend/classroll-parent/service-client/service-student-client/src/main/java/com/cxy/classroll/student/client/StudentFeignClient.java b/backend/classroll-parent/service-client/service-student-client/src/main/java/com/cxy/classroll/student/client/StudentFeignClient.java new file mode 100644 index 0000000..c1b213d --- /dev/null +++ b/backend/classroll-parent/service-client/service-student-client/src/main/java/com/cxy/classroll/student/client/StudentFeignClient.java @@ -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 login(@PathVariable String code); + + @PostMapping("/student/common/authentication") + public Result authentication(@RequestBody AuthenticationForm authenticationForm); + + @GetMapping("/student/common/userinfo/{id}") + public Result getUserInfo(@PathVariable Long id); + + @GetMapping("/student/lessonlist/{id}") + public Result> getStudentLessons(@PathVariable Long id); + + @GetMapping("/student/studentsignin/{userid}/{lessonid}") + public Result StudentSignInClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid); + + @GetMapping("/student/studentsignout/{userid}/{lessonid}") + public Result StudentSignOutClass(@PathVariable(value = "userid") Long userid,@PathVariable(value = "lessonid")Long lessonid); + + @GetMapping("/student/lessonstatus/{lessonid}") + public Result LessonStatus(@PathVariable Long lessonid); + + @GetMapping("/student/lessonroll/{lessonid}") + public Result LessonRoll(@PathVariable Long lessonid); + + @PostMapping(value = "/student/uploadcsv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public Result 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 classRoll(@PathVariable(value = "lessonid") Long lessonid, @PathVariable(value = "roll_method")int roll_method); + + @GetMapping("/student/scorerank") + public Result> scoreRank(); + + @GetMapping("/student/comment/{lesson_id}/{student_no}/{score}") + public Result 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> getNoList(@PathVariable(value = "lesson_id") Long lessonid); +} diff --git a/backend/classroll-parent/service-client/service-teacher-client/pom.xml b/backend/classroll-parent/service-client/service-teacher-client/pom.xml new file mode 100644 index 0000000..ca7ef89 --- /dev/null +++ b/backend/classroll-parent/service-client/service-teacher-client/pom.xml @@ -0,0 +1,15 @@ + + + + com.cxy.classroll + service-client + 0.0.1-SNAPSHOT + + 4.0.0 + + service-teacher-client + 0.0.1-SNAPSHOT + jar + + diff --git a/backend/classroll-parent/service-client/service-teacher-client/src/main/java/com/cxy/classroll/teacher/client/TeacherFeignClient.java b/backend/classroll-parent/service-client/service-teacher-client/src/main/java/com/cxy/classroll/teacher/client/TeacherFeignClient.java new file mode 100644 index 0000000..30929b7 --- /dev/null +++ b/backend/classroll-parent/service-client/service-teacher-client/src/main/java/com/cxy/classroll/teacher/client/TeacherFeignClient.java @@ -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> getTeacherLessonList(@PathVariable Long id); + + @GetMapping("/teacher/classstart/{lessonid}") + public Result classStart(@PathVariable Long lessonid); + + @GetMapping("/teacher/classend/{lessonid}") + public Result classEnd(@PathVariable Long lessonid); +} diff --git a/backend/classroll-parent/service/pom.xml b/backend/classroll-parent/service/pom.xml new file mode 100644 index 0000000..ea9d002 --- /dev/null +++ b/backend/classroll-parent/service/pom.xml @@ -0,0 +1,79 @@ + + + + com.cxy.classroll + classroll-parent + 0.0.1-SNAPSHOT + + 4.0.0 + + service + pom + + + service-student + service-teacher + + + + + com.cxy.classroll + service-util + 0.0.1-SNAPSHOT + + + com.cxy.classroll + common-log + 0.0.1-SNAPSHOT + + + com.cxy.classroll + service-student-client + 0.0.1-SNAPSHOT + + + com.cxy.classroll + service-teacher-client + 0.0.1-SNAPSHOT + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/backend/classroll-parent/service/service-student/pom.xml b/backend/classroll-parent/service/service-student/pom.xml new file mode 100644 index 0000000..f0cb4d1 --- /dev/null +++ b/backend/classroll-parent/service/service-student/pom.xml @@ -0,0 +1,41 @@ + + + + com.cxy.classroll + service + 0.0.1-SNAPSHOT + + 4.0.0 + + service-student + 0.0.1-SNAPSHOT + jar + + + true + + + + + com.github.binarywang + weixin-java-miniapp + + + com.opencsv + opencsv + 4.3.2 + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/ServiceStudentApplication.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/ServiceStudentApplication.java new file mode 100644 index 0000000..9ae0cbb --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/ServiceStudentApplication.java @@ -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); + } + +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/config/WxConfigOperator.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/config/WxConfigOperator.java new file mode 100644 index 0000000..e39dc39 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/config/WxConfigOperator.java @@ -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; + } +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/config/WxConfigProperties.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/config/WxConfigProperties.java new file mode 100644 index 0000000..321bbbb --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/config/WxConfigProperties.java @@ -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; +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/controller/StudentController.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/controller/StudentController.java new file mode 100644 index 0000000..ce00973 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/controller/StudentController.java @@ -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 login(@PathVariable String code) { + return Result.ok(commonService.login(code)); + } + + @Operation(summary = "身份校验") + @PostMapping("/common/authentication") + public Result authentication(@RequestBody AuthenticationForm authenticationForm){ + return Result.ok(commonService.authentication(authenticationForm)); + } + + @Operation(summary = "我的页面个人信息获取") + @GetMapping("/common/userinfo/{id}") + public Result getUserInfo(@PathVariable Long id){ + return Result.ok(commonService.getUserInfo(id)); + } + + @Operation(summary = "学生课程页面课程信息列表") + @GetMapping("/lessonlist/{id}") + public Result> getStudentLessons(@PathVariable Long id){ + return Result.ok(studentService.getStudentLessons(id)); + } + + @Operation(summary = "学生课堂签到") + @GetMapping("/studentsignin/{userid}/{lessonid}") + public Result 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 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 LessonStatus(@PathVariable Long lessonid){ + return Result.ok(lessonInfoService.listenLessonStatus(lessonid)); + } + + @Operation(summary = "监听课程点名状态") + @GetMapping("/lessonroll/{lessonid}") + public Result LessonRoll(@PathVariable Long lessonid){ + return Result.ok(lessonInfoService.listenLessonRoll(lessonid)); + } + + @Operation(summary = "解析csv数据") + @PostMapping(value = "/uploadcsv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public Result 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 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> scoreRank(){ + return Result.ok(commonService.scoreRank()); + } + + @Operation(summary = "教师打分评价") + @GetMapping("/comment/{lesson_id}/{student_no}/{score}") + public Result 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> getNoList(@PathVariable(value = "lesson_id") Long lessonid){ + return Result.ok(commonService.leesonStudentNoList(lessonid)); + } +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/LessonInfoMapper.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/LessonInfoMapper.java new file mode 100644 index 0000000..2175322 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/LessonInfoMapper.java @@ -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 { +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/StuLessonMapper.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/StuLessonMapper.java new file mode 100644 index 0000000..08afb67 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/StuLessonMapper.java @@ -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 { +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/UserMapper.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/UserMapper.java new file mode 100644 index 0000000..6662e2f --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/mapper/UserMapper.java @@ -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 { +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/CommonService.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/CommonService.java new file mode 100644 index 0000000..550c868 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/CommonService.java @@ -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 { + //微信小程序登录接口 + 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 scoreRank(); + + Boolean teacherComment(Long lesosn_id, String student_no, int score); + + List leesonStudentNoList(Long lesson_id); +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/LessonInfoService.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/LessonInfoService.java new file mode 100644 index 0000000..758ad6b --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/LessonInfoService.java @@ -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 getLessonInfoByLessonName(String lesson_name); + + Lesson getLessonInfoById(Long lesson_id); + + Integer listenLessonStatus(Long lesson_id); + + Integer listenLessonRoll(Long lesson_id); +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/StuLessonService.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/StuLessonService.java new file mode 100644 index 0000000..7974ba8 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/StuLessonService.java @@ -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 { + List getStudentLessons(Long id); + + Boolean uploadCsvData(MultipartFile file,Long teacher_id,String lesson_name); + + List getStuLessonListByLessonName(String lesson_name); +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/CommonServiceImpl.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..71d42d5 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/CommonServiceImpl.java @@ -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 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 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 students = new ArrayList<>(); + Lesson lesson = lessonInfoService.getLessonInfoById(lesson_id); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Stu_lesson::getLesson_name, lesson.getLesson_name()); + List stuLessonListByLessonName = stuLessonMapper.selectList(queryWrapper); + for(Stu_lesson stuLesson:stuLessonListByLessonName){ + LambdaQueryWrapper 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 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 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 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 scoreRank() { + LambdaQueryWrapper 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 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 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 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 leesonStudentNoList(Long lesson_id) { + List studentNoList = new ArrayList<>(); + Lesson lesson = lessonInfoService.getLessonInfoById(lesson_id); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Stu_lesson::getLesson_name, lesson.getLesson_name()); + List stuLessonListByLessonName = stuLessonMapper.selectList(queryWrapper); + for(Stu_lesson stuLesson:stuLessonListByLessonName){ + studentNoList.add(stuLesson.getStudent_no()); + } + return studentNoList; + } +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/LessonInfoServiceImpl.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/LessonInfoServiceImpl.java new file mode 100644 index 0000000..ef8419c --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/LessonInfoServiceImpl.java @@ -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 implements LessonInfoService { + @Autowired + LessonInfoMapper lessonInfoMapper; + + @Override + public Lesson getLessonInfoByLessonName(String lesson_name) { + LambdaQueryWrapper 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(); + } +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/StuLessonServiceImpl.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/StuLessonServiceImpl.java new file mode 100644 index 0000000..db5b9c5 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/service/impl/StuLessonServiceImpl.java @@ -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 implements StuLessonService { + + @Autowired + CommonService commonService; + + @Autowired + LessonInfoService lessonInfoService; + + @Autowired + StuLessonMapper stuLessonMapper; + + @Autowired + UserMapper userMapper; + + @Autowired + LessonInfoMapper lessonInfoMapper; + + @Override + public List getStudentLessons(Long id) { + List lessons_list = new ArrayList<>(); + User userInfo = commonService.getUserInfo(id); + String no = userInfo.getNo(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(Stu_lesson::getStudent_no,no); + List 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 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 csvDataList = csvUtil.getCsvDataManually(file); + for (CsvData csvData: csvDataList){ + Stu_lesson stuLesson = new Stu_lesson(); + LambdaQueryWrapper 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 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 getStuLessonListByLessonName(String lesson_name) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(Stu_lesson::getLesson_name, lesson_name); + return stuLessonMapper.selectList(wrapper); + } +} diff --git a/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/util/CsvUtil.java b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/util/CsvUtil.java new file mode 100644 index 0000000..4aed8e3 --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/java/com/cxy/classroll/student/util/CsvUtil.java @@ -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 List getCsvDataManually(MultipartFile file) { + List 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; + } + + +} diff --git a/backend/classroll-parent/service/service-student/src/main/resources/bootstrap.properties b/backend/classroll-parent/service/service-student/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..4cd271e --- /dev/null +++ b/backend/classroll-parent/service/service-student/src/main/resources/bootstrap.properties @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/service/service-teacher/pom.xml b/backend/classroll-parent/service/service-teacher/pom.xml new file mode 100644 index 0000000..eae21bf --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/pom.xml @@ -0,0 +1,36 @@ + + + + com.cxy.classroll + service + 0.0.1-SNAPSHOT + + 4.0.0 + + service-teacher + 0.0.1-SNAPSHOT + jar + + + true + + + + + com.github.binarywang + weixin-java-miniapp + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/ServiceTeacherApplication.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/ServiceTeacherApplication.java new file mode 100644 index 0000000..1fa9517 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/ServiceTeacherApplication.java @@ -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); + } + +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/config/WxConfigOperator.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/config/WxConfigOperator.java new file mode 100644 index 0000000..6d8be54 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/config/WxConfigOperator.java @@ -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; + } +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/config/WxConfigProperties.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/config/WxConfigProperties.java new file mode 100644 index 0000000..2affb70 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/config/WxConfigProperties.java @@ -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; +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/controller/TeacherController.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/controller/TeacherController.java new file mode 100644 index 0000000..e4e21f7 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/controller/TeacherController.java @@ -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> getTeacherLessonList(@PathVariable Long id) { + return Result.ok(teacherLessonService.getTeacherLessons(id)); + } + + @Operation(summary = "开始上课") + @GetMapping("/classstart/{lessonid}") + public Result classStart(@PathVariable Long lessonid){ + return Result.ok(teacherLessonService.lessonStart(lessonid)); + } + + @Operation(summary = "结束上课") + @GetMapping("/classend/{lessonid}") + public Result classEnd(@PathVariable Long lessonid){ + return Result.ok(teacherLessonService.lessonEnd(lessonid)); + } + +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/mapper/TeacherLessonMapper.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/mapper/TeacherLessonMapper.java new file mode 100644 index 0000000..8b93f3c --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/mapper/TeacherLessonMapper.java @@ -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 { +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/mapper/UserMapper.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/mapper/UserMapper.java new file mode 100644 index 0000000..b710815 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/mapper/UserMapper.java @@ -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 { +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/TeacherLessonService.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/TeacherLessonService.java new file mode 100644 index 0000000..3d97a7a --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/TeacherLessonService.java @@ -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 { + List getTeacherLessons(Long teacher_id); + + Boolean lessonStart(Long lesson_id); + + Boolean lessonEnd(Long lesson_id); +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/UserService.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/UserService.java new file mode 100644 index 0000000..4459d56 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/UserService.java @@ -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 { + Boolean updateUserScore(Long id, int scoreChange); +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/TeacherLessonServiceImpl.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/TeacherLessonServiceImpl.java new file mode 100644 index 0000000..21b4b7f --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/TeacherLessonServiceImpl.java @@ -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 implements TeacherLessonService { + + @Autowired + TeacherLessonMapper teacherLessonMapper; + + @Autowired + UserService userService; + + @Override + public List getTeacherLessons(Long teacher_id) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(Lesson::getTeacher_id, teacher_id); + return teacherLessonMapper.selectList(wrapper); + } + + @Override + public Boolean lessonStart(Long lesson_id) { + LambdaQueryWrapper 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 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; + } +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/UserServiceImpl.java b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..14d33f2 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/UserServiceImpl.java @@ -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 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; + } +} diff --git a/backend/classroll-parent/service/service-teacher/src/main/resources/bootstrap.properties b/backend/classroll-parent/service/service-teacher/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..d4da067 --- /dev/null +++ b/backend/classroll-parent/service/service-teacher/src/main/resources/bootstrap.properties @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/web/pom.xml b/backend/classroll-parent/web/pom.xml new file mode 100644 index 0000000..67bce4f --- /dev/null +++ b/backend/classroll-parent/web/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + + com.cxy.classroll + classroll-parent + 0.0.1-SNAPSHOT + + + + web + 0.0.1-SNAPSHOT + pom + + + + com.cxy.classroll + service-util + 0.0.1-SNAPSHOT + + + com.cxy.classroll + common-log + 0.0.1-SNAPSHOT + + + com.cxy.classroll + service-teacher-client + 0.0.1-SNAPSHOT + + + com.cxy.classroll + service-student-client + 0.0.1-SNAPSHOT + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/backend/classroll-parent/web/web-student/pom.xml b/backend/classroll-parent/web/web-student/pom.xml new file mode 100644 index 0000000..905b3d7 --- /dev/null +++ b/backend/classroll-parent/web/web-student/pom.xml @@ -0,0 +1,26 @@ + + + + com.cxy.classroll + web + 0.0.1-SNAPSHOT + + 4.0.0 + web-student + 0.0.1-SNAPSHOT + web-student + web-student + jar + + + web-student + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/WebStudentApplication.java b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/WebStudentApplication.java new file mode 100644 index 0000000..01e9353 --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/WebStudentApplication.java @@ -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); + } + +} diff --git a/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/controller/StudentWebController.java b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/controller/StudentWebController.java new file mode 100644 index 0000000..9cd42b2 --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/controller/StudentWebController.java @@ -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 wxLogin(@PathVariable String code) { + return Result.ok(commonWebService.login(code)); + } + + @Operation(summary = "身份登记验证") + @PostMapping("/common/authentication") + public Result authentication(@RequestBody AuthenticationForm authenticationForm){ + return Result.ok(commonWebService.authentication(authenticationForm)); + } + + @Operation(summary = "我的主页用户信息获取") + @GetMapping("/common/getUserInfo/{id}") + public Result getUserInfo(@PathVariable Long id){ + return Result.ok(commonWebService.getUserInfo(id)); + } + + @Operation(summary = "学生课程列表信息获取") + @GetMapping("/lessonlist/{id}") + public Result> getStudentLessons(@PathVariable Long id){ + return Result.ok(studentWebService.getStudentLessons(id)); + } + + @Operation(summary = "学生课堂签到") + @GetMapping("/studentsignin/{userid}/{lessonid}") + public Result 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 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 LessonStatus(@PathVariable Long lessonid){ + return Result.ok(commonWebService.listenLessonStatus(lessonid)); + } + + @Operation(summary = "监听课程点名") + @GetMapping("/lessonroll/{lessonid}") + public Result LessonRoll(@PathVariable Long lessonid){ + return Result.ok(commonWebService.listenLessonRoll(lessonid)); + } + + @Operation(summary = "上传学生csv名单文件") + @PostMapping("/uploadcsv") + public Result 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 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> scoreRank(){ + return Result.ok(commonWebService.scoreRank()); + } + + @Operation(summary = "教师打分评价") + @GetMapping("/comment/{lesson_id}/{student_no}/{score}") + public Result 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> getNoList(@PathVariable(value = "lesson_id") Long lessonid){ + return Result.ok(commonWebService.leesonStudentNoList(lessonid)); + } +} diff --git a/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/CommonWebService.java b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/CommonWebService.java new file mode 100644 index 0000000..6406377 --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/CommonWebService.java @@ -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 scoreRank(); + + Boolean teacherComment(Long lesosn_id, String student_no, int score); + + List leesonStudentNoList(Long lesson_id); +} diff --git a/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/StudentWebService.java b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/StudentWebService.java new file mode 100644 index 0000000..4559087 --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/StudentWebService.java @@ -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 getStudentLessons(Long id); + + Boolean uploadCsvData(MultipartFile multipartFile, Long teacher_id, String lesson_name); +} diff --git a/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/impl/CommonWebServiceImpl.java b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/impl/CommonWebServiceImpl.java new file mode 100644 index 0000000..edaff84 --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/impl/CommonWebServiceImpl.java @@ -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 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 result = studentFeignClient.authentication(authenticationForm); + if (result.getData()){ + return true; + }else { + return false; + } + } + + @Override + public User getUserInfo(Long id) { + Result 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 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 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 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 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 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 scoreRank() { + Result> 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 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 leesonStudentNoList(Long lesson_id) { + Result> 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(); + } +} diff --git a/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/impl/StudentWebServiceImpl.java b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/impl/StudentWebServiceImpl.java new file mode 100644 index 0000000..6daa74c --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/java/com/cxy/classroll/student/service/impl/StudentWebServiceImpl.java @@ -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 getStudentLessons(Long id) { + Result> result = studentFeignClient.getStudentLessons(id); + Integer code = result.getCode(); + if (code!=200){ + throw new CxyException(ResultCodeEnum.DATA_ERROR); + } + + List 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 result = studentFeignClient.uploadCsv(multipartFile, teacher_id, lesson_name); + if (result.getCode()!=200){ + throw new CxyException(ResultCodeEnum.DATA_ERROR); + } + return result.getData(); + } +} diff --git a/backend/classroll-parent/web/web-student/src/main/resources/bootstrap.properties b/backend/classroll-parent/web/web-student/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..6099280 --- /dev/null +++ b/backend/classroll-parent/web/web-student/src/main/resources/bootstrap.properties @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/web/web-teacher/pom.xml b/backend/classroll-parent/web/web-teacher/pom.xml new file mode 100644 index 0000000..6e3e886 --- /dev/null +++ b/backend/classroll-parent/web/web-teacher/pom.xml @@ -0,0 +1,26 @@ + + + + com.cxy.classroll + web + 0.0.1-SNAPSHOT + + 4.0.0 + web-teacher + 0.0.1-SNAPSHOT + web-teacher + web-teacher + jar + + + web-teacher + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/WebTeacherApplication.java b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/WebTeacherApplication.java new file mode 100644 index 0000000..24d117c --- /dev/null +++ b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/WebTeacherApplication.java @@ -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); + } + +} diff --git a/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/controller/TeacherWebController.java b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/controller/TeacherWebController.java new file mode 100644 index 0000000..43807ba --- /dev/null +++ b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/controller/TeacherWebController.java @@ -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> getTeacherLessonList(@PathVariable Long id) { + return Result.ok(teacherWebService.getTeacherLessonsList(id)); + } + + @Operation(summary = "开始上课") + @GetMapping("/classstart/{leesonid}") + public Result classStart(@PathVariable Long leesonid){ + return Result.ok(teacherWebService.lessonStart(leesonid)); + } + + @Operation(summary = "结束上课") + @GetMapping("/classend/{lessonid}") + public Result classEnd(@PathVariable Long lessonid){ + return Result.ok(teacherWebService.lessonEnd(lessonid)); + } +} diff --git a/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/service/TeacherWebService.java b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/service/TeacherWebService.java new file mode 100644 index 0000000..d1e88d8 --- /dev/null +++ b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/service/TeacherWebService.java @@ -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 getTeacherLessonsList(Long id); + + Boolean lessonStart(Long lesson_id); + + Boolean lessonEnd(Long lesson_id); +} diff --git a/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/TeacherWebServiceImpl.java b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/TeacherWebServiceImpl.java new file mode 100644 index 0000000..6cc7afb --- /dev/null +++ b/backend/classroll-parent/web/web-teacher/src/main/java/com/cxy/classroll/teacher/service/impl/TeacherWebServiceImpl.java @@ -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 getTeacherLessonsList(Long id) { + Result> result = teacherFeignClient.getTeacherLessonList(id); + Integer code = result.getCode(); + if (code != 200) { + throw new CxyException(ResultCodeEnum.DATA_ERROR); + } + List data = result.getData(); + if (data == null) { + throw new CxyException(ResultCodeEnum.DATA_ERROR); + } + return data; + } + + @Override + public Boolean lessonStart(Long lesson_id) { + Result 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 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; + } +} diff --git a/backend/classroll-parent/web/web-teacher/src/main/resources/bootstrap.properties b/backend/classroll-parent/web/web-teacher/src/main/resources/bootstrap.properties new file mode 100644 index 0000000..b9909ab --- /dev/null +++ b/backend/classroll-parent/web/web-teacher/src/main/resources/bootstrap.properties @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/yaml_config/DEFAULT_GROUP.zip b/backend/classroll-parent/yaml_config/DEFAULT_GROUP.zip new file mode 100644 index 0000000..702e6fd Binary files /dev/null and b/backend/classroll-parent/yaml_config/DEFAULT_GROUP.zip differ diff --git a/backend/classroll-parent/yaml_config/DEFAULT_GROUP/server-gateway-classroll-dev.yaml b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/server-gateway-classroll-dev.yaml new file mode 100644 index 0000000..e42b906 --- /dev/null +++ b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/server-gateway-classroll-dev.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 diff --git a/backend/classroll-parent/yaml_config/DEFAULT_GROUP/service-student-dev.yaml b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/service-student-dev.yaml new file mode 100644 index 0000000..82ca307 --- /dev/null +++ b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/service-student-dev.yaml @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/yaml_config/DEFAULT_GROUP/service-teacher-dev.yaml b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/service-teacher-dev.yaml new file mode 100644 index 0000000..82ca307 --- /dev/null +++ b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/service-teacher-dev.yaml @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/yaml_config/DEFAULT_GROUP/web-student-dev.yaml b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/web-student-dev.yaml new file mode 100644 index 0000000..2dcd023 --- /dev/null +++ b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/web-student-dev.yaml @@ -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 \ No newline at end of file diff --git a/backend/classroll-parent/yaml_config/DEFAULT_GROUP/web-teacher-dev.yaml b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/web-teacher-dev.yaml new file mode 100644 index 0000000..2dcd023 --- /dev/null +++ b/backend/classroll-parent/yaml_config/DEFAULT_GROUP/web-teacher-dev.yaml @@ -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 \ No newline at end of file