Explorar o código

Merge branch 'test-user' into develop-pay

* test-user:
  广电报备接口,还差匹配成功后激活流程
  修改了商学院-晨会列表接口,新增了商学院-晨会列表-增加学习人数接口
  修改了.gitgnore
  封装部署rocketmq

# Conflicts:
#	kxs-common/pom.xml
mac %!s(int64=2) %!d(string=hai) anos
pai
achega
757db88413
Modificáronse 43 ficheiros con 2000 adicións e 36 borrados
  1. 1 1
      .gitignore
  2. 48 17
      docker-compose.yml
  3. 25 8
      kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/constant/enums/ErrorTypeEnum.java
  4. 12 0
      kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/util/AssertUtil.java
  5. 30 0
      kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/valid/Sn.java
  6. 36 0
      kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/valid/impl/SnValidator.java
  7. 26 0
      kxs-common/kxs-common-mq/pom.xml
  8. 1 0
      kxs-common/kxs-common-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  9. 1 0
      kxs-common/pom.xml
  10. 49 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/dto/kxsapp/gd/GdReportDTO.java
  11. 79 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/dto/kxsapp/gd/GdReportPutDTO.java
  12. 157 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/model/KxsGdReport.java
  13. 35 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/req/gd/GdQueryCardOrderReq.java
  14. 18 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/res/gd/GdCommRes.java
  15. 102 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/res/gd/GdQueryOrderRes.java
  16. 50 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/vo/kxsapp/gd/GdDotNumVO.java
  17. 77 0
      kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/vo/kxsapp/gd/GdReportListVO.java
  18. 4 0
      kxs-product/kxs-product-biz/pom.xml
  19. 2 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/KxsProductApplication.java
  20. 52 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/config/RsaProperties.java
  21. 33 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/constant/enums/GdReportEnum.java
  22. 78 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/controller/admin/SysGdController.java
  23. 104 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/controller/kxsapp/GdController.java
  24. 30 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/mapper/KxsGdReportMapper.java
  25. 77 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/KxsGdReportService.java
  26. 33 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/KxsGdService.java
  27. 157 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/impl/KxsGdReportServiceImpl.java
  28. 109 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/impl/KxsGdServiceImpl.java
  29. 0 1
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/impl/KxsMachineServiceImpl.java
  30. 284 0
      kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/util/GdRsaUtils.java
  31. 38 0
      kxs-product/kxs-product-biz/src/main/resources/mapper/KxsGdReportMapper.xml
  32. 12 0
      kxs-system/kxs-system-api/src/main/java/com/kxs/system/api/dto/kxsapp/AddStudyPersonDTO.java
  33. 31 6
      kxs-system/kxs-system-biz/src/main/java/com/kxs/system/biz/controller/kxsapp/MorningController.java
  34. 8 0
      kxs-system/kxs-system-biz/src/main/java/com/kxs/system/biz/service/KxsMorningService.java
  35. 32 1
      kxs-system/kxs-system-biz/src/main/java/com/kxs/system/biz/service/impl/KxsMorningServiceImpl.java
  36. 8 0
      kxs-user/kxs-user-api/src/main/java/com/kxs/user/api/feign/RemoteKxsUserService.java
  37. 6 0
      kxs-user/kxs-user-biz/pom.xml
  38. 13 0
      kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/controller/kxsapp/KxsAppController.java
  39. 42 0
      kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/controller/kxsapp/TestMq.java
  40. 5 2
      kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/service/impl/KxsUserServiceImpl.java
  41. 75 0
      kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/util/SmsUtils.java
  42. 9 0
      kxs-visual/kxs-rocket/broker/broker.conf
  43. 11 0
      pom.xml

+ 1 - 1
.gitignore

@@ -38,7 +38,7 @@ target/
 *.tar
 *.tar.gz
 *.versionsBackup
-
+*.yml
 ### vscode ###
 .vscode
 yarn.lock

+ 48 - 17
docker-compose.yml

@@ -108,23 +108,6 @@ services:
 #    networks:
 #      - kxs_cloud_network
 #
-#  kxs-rabbitmq:
-#    image: rabbitmq:3.12.8
-#    container_name: kxs-rabbitmq
-#    restart: always
-#    volumes:
-#      - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime"        #设置系统时区
-#      - "/usr/share/zoneinfo/Asia/Shanghai:/etc/timezone"  #设置时区
-#      - "./data/rabbit/:/var/lib/rabbitmq/"
-#      - "./logs/rabbit:/var/log/rabbitmq/"
-#    ports:
-#      - 5672:5672
-#      - 15672:15672
-#    environment:
-#      - RABBITMQ_DEFAULT_USER=admin
-#      - RABBITMQ_DEFAULT_PASS=admin
-#    networks:
-#      - kxs_cloud_network
 
 #  kxs-mongo:
 #    image: mongo:6.0.3
@@ -171,6 +154,54 @@ services:
       - kxs_cloud_network
 
 
+  kxs-rocket:
+    image: apache/rocketmq:5.1.4
+    hostname: kxs-rocket
+    container_name: kxs-rocket
+    ports:
+      - 9876:9876
+    volumes:
+      - ./logs/rocket:/home/rocketmq/logs
+    command: sh mqnamesrv
+    restart: on-failure
+    networks:
+      - kxs_cloud_network
+
+  kxs-rocket-broker:
+    image: apache/rocketmq:5.1.4
+    hostname: kxs-rocket-broker
+    container_name: kxs-rocket-broker
+    ports:
+      - 10909:10909
+      - 10911:10911
+      - 10912:10912
+    environment:
+      JAVA_OPT_EXT: "-server -Xms128m -Xmx128m -Xmn128m"
+    volumes:
+      - ./data/broker/store:/home/rocketmq/store
+      - ./kxs-visual/kxs-rocket/broker/broker.conf:/home/rocketmq/conf/broker.conf
+    command: sh mqbroker -n kxs-rocket:9876 -c /home/rocketmq/conf/broker.conf
+    restart: on-failure
+    networks:
+      - kxs_cloud_network
+    depends_on:
+      - kxs-rocket
+
+  kxs-rocket-dashboard:
+    image: apacherocketmq/rocketmq-dashboard:1.0.0
+    container_name: kxs-rocket-dashboard
+    hostname: kxs-rocket-dashboard
+    ports:
+      - 9870:8080
+    environment:
+      - JAVA_OPTS=-Drocketmq.namesrv.addr=kxs-rocket:9876
+    restart: on-failure
+    depends_on:
+      - kxs-rocket-broker
+    networks:
+      - kxs_cloud_network
+
+
 networks:
   kxs_cloud_network:
     name: kxs_cloud_network

+ 25 - 8
kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/constant/enums/ErrorTypeEnum.java

@@ -13,17 +13,34 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public enum ErrorTypeEnum {
 
-	DECRYPT_ERROR(-1, "解密异常"), TOKEN_EXPIRED(-1, "令牌已过期"), TOKEN_EMPTY(-1, "令牌不存在"),
-	CLIENT_NULL(-1, "客户端查询异常,请检查数据库链接"), ACCESS_DENIED(-1, "不允许范访问"), BAD_CREDENTIALS(-1, "用户名或密码错误"),
-	CREDENTIALS_EXPIRED(-1, "用户凭证已过期"), USER_DISABLED(-1, "用户已失效"), ACCOUNT_DISABLED(-1, "用户帐号已过期"),
-	ACCOUNT_LOCKED(-1, "用户帐号已被锁定"), USER_NOT_FOUND(-1, "未找到用户"), PHONE_NOT_FOUND(-1, "手机号不存在"),
-	VERIFICATION_CODE_IS_ILLEGAL(-1, "验证码不合法"), VERIFICATION_CODE_IS_EMPTY(-1, "验证码不能为空"),
+	DECRYPT_ERROR(-1, "解密异常"),
+	TOKEN_EXPIRED(-1, "令牌已过期"),
+	TOKEN_EMPTY(-1, "令牌不存在"),
+	CLIENT_NULL(-1, "客户端查询异常,请检查数据库链接"),
+	ACCESS_DENIED(-1, "不允许范访问"),
+	BAD_CREDENTIALS(-1, "用户名或密码错误"),
+	CREDENTIALS_EXPIRED(-1, "用户凭证已过期"),
+	USER_DISABLED(-1, "用户已失效"),
+	ACCOUNT_DISABLED(-1, "用户帐号已过期"),
+	ACCOUNT_LOCKED(-1, "用户帐号已被锁定"),
+	USER_NOT_FOUND(-1, "未找到用户"),
+	PHONE_NOT_FOUND(-1, "手机号不存在"),
+	VERIFICATION_CODE_IS_ILLEGAL(-1, "验证码不合法"),
+	VERIFICATION_CODE_IS_EMPTY(-1, "验证码不能为空"),
 	UNAUTHORIZED_CLIENT(-1, "客户端不允许登陆"),
 
-	SYS_PARAM_DELETE_SYSTEM(-1, "系统内置参数不能删除"), SYS_DICT_DELETE_SYSTEM(-1, "系统内置字典不允许删除"),
-	SYS_MENU_DELETE_EXISTING(-1, "菜单存在下级节点 删除失败"), SYS_USER_USERNAME_EXISTING(-1, "用户名已存在"),
+	SYS_PARAM_DELETE_SYSTEM(-1, "系统内置参数不能删除"),
+	SYS_DICT_DELETE_SYSTEM(-1, "系统内置字典不允许删除"),
+	SYS_MENU_DELETE_EXISTING(-1, "菜单存在下级节点 删除失败"),
+	SYS_USER_USERNAME_EXISTING(-1, "用户名已存在"),
 	REMOTE_DATA_ERROR(-1, "远程数据调用错误"),
-	SYS_USER_UPDATE_PASSWORD_ERROR(-1, "用户原密码错误"), SYS_DICT_UPDATE_SYSTEM(-1, "系统内置字典不能修改");
+	SYS_USER_UPDATE_PASSWORD_ERROR(-1, "用户原密码错误"),
+	SYS_DICT_UPDATE_SYSTEM(-1, "系统内置字典不能修改"),
+	SYS_MORNING_IS_NULL(-1, "该晨会不存在"),
+	SYS_SCHOOL_IS_NULL(-1, "该学堂不存在"),
+	SYS_TYPE_ERROR(-1, "类型异常"),
+
+	;
 
 	private final int code;
 

+ 12 - 0
kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/util/AssertUtil.java

@@ -21,6 +21,8 @@ public class AssertUtil {
      //手机的正则表达式
      private static final Pattern CHINA_PATTERN_PHONE = Pattern.compile("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$");
 
+    private static final Pattern YYYY_MM = Pattern.compile("^\\d{4}-(0[1-9]|1[0-2])$");
+
     public static final String CHINA_PATTERN_PHONE_STR =  "^((13[0-9])|(14[014-9])|(15[0-35-9])|(16[2567])|(17[0-8])|(18[0-9])|(19[0-35-9]))\\d{8}$";
 
      /**--------------------------------------------------------
@@ -34,7 +36,17 @@ public class AssertUtil {
             throw new GlobalCustomerException("手机号格式错误");
         }
     }
+    /**--------------------------------------------------------
+     时间格式断言
+     --------------------------------------------------------**/
+    public static void isYyyyMM(String month){
 
+        //格式校验
+        Matcher m = YYYY_MM.matcher(month);
+        if(!m.matches()){
+            throw new GlobalCustomerException("时间格式错误yyyy-MM");
+        }
+    }
 
 
 

+ 30 - 0
kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/valid/Sn.java

@@ -0,0 +1,30 @@
+package com.kxs.common.core.valid;
+
+import com.kxs.common.core.valid.impl.PhoneValidator;
+import com.kxs.common.core.valid.impl.SnValidator;
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+
+import java.lang.annotation.*;
+
+/**
+ * 手机号验证正则
+ * @author mac
+ */
+@Target({ElementType.FIELD,ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = {SnValidator.class})// 指定约束处理器
+public @interface Sn {
+
+    String pattern() default "^[a-zA-Z0-9]+$";
+
+    String message() default "SN格式非法";
+
+    Class<?>[] groups() default { }; // groups用来指定分组,可以让校验采取不同的机制,当前默认未指定任何分组机制,默认每次都要进行校验
+
+    Class<? extends Payload>[] payload() default { };
+
+
+}
+

+ 36 - 0
kxs-common/kxs-common-core/src/main/java/com/kxs/common/core/valid/impl/SnValidator.java

@@ -0,0 +1,36 @@
+package com.kxs.common.core.valid.impl;
+
+import com.kxs.common.core.valid.Sn;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * sn格式校验器
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-11
+ */
+public class SnValidator implements ConstraintValidator<Sn, String> {
+
+    // 注解对象
+    private Sn sn;
+
+    // 初始化【Phone】对象
+    @Override
+    public void initialize(Sn constraintAnnotation) {
+        sn = constraintAnnotation;
+    }
+
+    @Override
+    public boolean isValid(String value, ConstraintValidatorContext context) {
+        // 获取【Phone】对象的手机格式验证表达式
+        String pattern = sn.pattern();
+        Pattern compile = Pattern.compile(pattern);
+        Matcher matcher = compile.matcher(value);
+        return matcher.matches();
+    }
+}
+

+ 26 - 0
kxs-common/kxs-common-mq/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.kxs</groupId>
+        <artifactId>kxs-common</artifactId>
+        <version>1.1.0</version>
+    </parent>
+
+    <artifactId>kxs-common-mq</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 1 - 0
kxs-common/kxs-common-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration

+ 1 - 0
kxs-common/pom.xml

@@ -25,6 +25,7 @@
         <module>kxs-common-seata</module>
         <module>kxs-common-oss</module>
         <module>kxs-common-pay</module>
+        <module>kxs-common-mq</module>
     </modules>
     <dependencyManagement>
         <dependencies>

+ 49 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/dto/kxsapp/gd/GdReportDTO.java

@@ -0,0 +1,49 @@
+package com.kxs.product.api.dto.kxsapp.gd;
+
+import com.kxs.common.core.valid.Phone;
+import com.kxs.common.core.valid.Sn;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+
+/**
+ * 广电报备-提交报备-dto
+ *
+ * @author 系统
+ * @date 2024-04-23 10:44:27
+ */
+@Data
+public class GdReportDTO {
+
+    /**
+     * 主键ID
+     */
+    @Schema(description = "主键ID")
+    @NotNull(message = "报备ID不能为空")
+    private Integer id;
+
+
+    /**
+     * sn码
+     */
+    @Schema(description = "sn码")
+    @NotBlank(message = "sn码不能为空")
+    @Sn
+    private String gdSn;
+
+
+    /**
+     * 广电手机号码
+     */
+    @Schema(description = "广电手机号码")
+    @NotBlank(message = "广电手机号码不能为空")
+    @Phone
+    private String gdMobile;
+
+
+
+
+
+}

+ 79 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/dto/kxsapp/gd/GdReportPutDTO.java

@@ -0,0 +1,79 @@
+package com.kxs.product.api.dto.kxsapp.gd;
+
+import com.kxs.common.core.valid.Phone;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+
+/**
+ * 广电报备-提交工单-dto
+ *
+ * @author 系统
+ * @date 2024-04-23 10:44:27
+ */
+@Data
+public class GdReportPutDTO {
+
+    /**
+     * 创客姓名
+     */
+    @Schema(description = "创客姓名")
+    @NotBlank(message = "创客姓名不能为空")
+    private String username;
+
+
+    /**
+     * 创客编号
+     */
+    @Schema(description = "创客编号")
+    @NotBlank(message = "创客编号不能为空")
+    private String userCode;
+
+
+    /**
+     * 报备省份
+     */
+    @Schema(description = "报备省份")
+    @NotBlank(message = "报备省份不能为空")
+    private String province;
+
+
+    /**
+     * 报备城市
+     */
+    @Schema(description = "报备城市")
+    @NotBlank(message = "报备城市不能为空")
+    private String city;
+
+
+    /**
+     * 入网姓名
+     */
+    @Schema(description = "入网姓名")
+    @NotBlank(message = "入网姓名不能为空")
+    private String putName;
+
+
+    /**
+     * 入网手机号
+     */
+    @Schema(description = "入网手机号")
+    @NotBlank(message = "入网手机号不能为空")
+    @Phone
+    private String putMobile;
+
+
+    /**
+     * 验证码
+     */
+    @Schema(description = "验证码")
+    @NotBlank(message = "验证码不能为空")
+    @Length(min = 6,max = 6, message = "验证码错误")
+    private String code;
+
+
+
+
+}

+ 157 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/model/KxsGdReport.java

@@ -0,0 +1,157 @@
+package com.kxs.product.api.model;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 广电报备入网表(KxsGdReport)表实体类
+ *
+ * @author 系统
+ * @since 2024-04-23 10:44:23
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class KxsGdReport extends Model<KxsGdReport> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    
+    
+    /**
+     * 主键ID
+     */
+    @Schema(description = "主键ID")
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+
+    /**
+     * 新增时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "新增时间")
+    private LocalDateTime createTime;
+
+
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.UPDATE)
+    @Schema(description = "更新时间")
+    private LocalDateTime updateTime;
+
+
+    /**
+     * 删除标记,0未删除,1已删除
+     */
+    @Schema(description = "删除标记,0未删除,1已删除")
+    private Integer delFlag;
+
+
+    /**
+     * 版本
+     */
+    @Schema(description = "版本")
+    private Integer version;
+
+
+    /**
+     * 创客ID
+     */
+    @Schema(description = "创客ID")
+    private Integer userId;
+
+
+    /**
+     * 创客姓名
+     */
+    @Schema(description = "创客姓名")
+    private String username;
+
+
+    /**
+     * 创客编号
+     */
+    @Schema(description = "创客编号")
+    private String userCode;
+
+
+    /**
+     * 报备省份
+     */
+    @Schema(description = "报备省份")
+    private String province;
+
+
+    /**
+     * 报备城市
+     */
+    @Schema(description = "报备城市")
+    private String city;
+
+
+    /**
+     * 入网姓名
+     */
+    @Schema(description = "入网姓名")
+    private String putName;
+
+
+    /**
+     * 入网手机号
+     */
+    @Schema(description = "入网手机号")
+    private String putMobile;
+
+
+    /**
+     * 备注
+     */
+    @Schema(description = "备注")
+    private String remark;
+
+
+    /**
+     * 状态 未处理=0 已作废=-1 报备成功=1
+     */
+    @Schema(description = "状态 未处理=0 已作废=-1 报备成功=1")
+    private Integer status;
+
+
+    /**
+     * sn码
+     */
+    @Schema(description = "sn码")
+    private String gdSn;
+
+
+    /**
+     * 广电手机号码
+     */
+    @Schema(description = "广电手机号码")
+    private String gdMobile;
+
+
+    /**
+     * 匹配状态
+     */
+    @Schema(description = "匹配状态")
+    private Integer isCheck;
+
+
+
+
+}
+

+ 35 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/req/gd/GdQueryCardOrderReq.java

@@ -0,0 +1,35 @@
+package com.kxs.product.api.req.gd;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 查询开卡订单数据
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-23
+ */
+@Data
+@Builder
+public class GdQueryCardOrderReq {
+
+    /**
+     * 签名
+     */
+    private String sign;
+    /**
+     * 查询开始时间
+     */
+    private String queryBeginTime;
+    /**
+     * 查询结束时间
+     */
+    private String queryEndTime;
+    private String pageNo;
+    private String pageSize;
+    /**
+     * 机构号
+     */
+    private String brhNo;
+    private String timestamp;
+}

+ 18 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/res/gd/GdCommRes.java

@@ -0,0 +1,18 @@
+package com.kxs.product.api.res.gd;
+
+import lombok.Data;
+
+/**
+ * 广电公共返回参数
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-23
+ */
+@Data
+public class GdCommRes<T> {
+
+    private T data;
+    private int resultCode;
+    private int errorCode;
+    private String errorDesc;
+}

+ 102 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/res/gd/GdQueryOrderRes.java

@@ -0,0 +1,102 @@
+package com.kxs.product.api.res.gd;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 广电开卡订单数据返回
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-23
+ */
+@Data
+public class GdQueryOrderRes {
+
+    private int total;
+    private int size;
+    private int current;
+    private int pages;
+    private List<GdQueryOrder> records;
+
+
+    /**
+     * 订单数据
+     *
+     * @author 没秃顶的码农
+     * @date 2024-04-23
+     */
+    @Data
+    public class GdQueryOrder{
+
+        /**
+         * 订单号
+         */
+        private String orderNo;
+        /**
+         * 订单创建时间
+         */
+        private String orderCreateTime;
+        /**
+         * 用户选择号码
+         */
+        private String phoneNo;
+        /**
+         * 是否首充(中文):是,否
+         */
+        private String firstCharge;
+        /**
+         * 首充金额(元)
+         */
+        private BigDecimal initialChargeAmount;
+        /**
+         * 省
+         */
+        private String province;
+        /**
+         * 城市
+         */
+        private String city;
+        /**
+         * 商品名称
+         */
+        private String productName;
+        /**
+         * 促销活动名称
+         */
+        private String promotionName;
+        /**
+         * 商品类型名称
+         */
+        private String productTypeName;
+        /**
+         * 实付金额(元)
+         */
+        private BigDecimal paidInAmount;
+        /**
+         * 订单状态(中文):待
+         * 激活、已完成、退款
+         * 中、未知
+         */
+        private String orderStatus;
+        /**
+         * 激活状态(中文):待激活、已激活、未知
+         */
+        private String activationStatusName;
+        /**
+         * 激活时间
+         */
+        private String activationTime;
+        /**
+         * 开卡人工号
+         */
+        private String jobId;
+        /**
+         * SIM 卡号
+         */
+        private String iccId;
+    }
+
+
+}

+ 50 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/vo/kxsapp/gd/GdDotNumVO.java

@@ -0,0 +1,50 @@
+package com.kxs.product.api.vo.kxsapp.gd;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 广电报备-数量接口vo
+ *
+ * @author 系统
+ * @date 2024-04-23 10:44:27
+ */
+@Data
+@Schema(description = "广电报备-数量接口返回实体")
+public class GdDotNumVO implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 待处理
+     */
+    @Schema(description = "待处理")
+    private Object pendNum;
+
+
+    /**
+     * 已报备
+     */
+    @Schema(description = "已报备")
+    private Object reportNum;
+
+
+    /**
+     * 已作废
+     */
+    @Schema(description = "已作废")
+    private Object cancelNum;
+
+
+
+
+
+	
+
+}

+ 77 - 0
kxs-product/kxs-product-api/src/main/java/com/kxs/product/api/vo/kxsapp/gd/GdReportListVO.java

@@ -0,0 +1,77 @@
+package com.kxs.product.api.vo.kxsapp.gd;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 广电报备-列表vo
+ *
+ * @author 系统
+ * @date 2024-04-23 10:44:27
+ */
+@Data
+@Schema(description = "广电报备-列表返回实体")
+public class GdReportListVO implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 主键ID
+     */
+    @Schema(description = "主键ID")
+    private Integer id;
+
+
+    /**
+     * 新增时间
+     */
+    @Schema(description = "新增时间")
+    private LocalDateTime createTime;
+
+
+    /**
+     * 入网姓名
+     */
+    @Schema(description = "入网姓名")
+    private String putName;
+
+
+    /**
+     * 入网手机号
+     */
+    @Schema(description = "入网手机号")
+    private String putMobile;
+
+    /**
+     * 广电手机号
+     */
+    @Schema(description = "广电手机号")
+    private String gdMobile;
+
+    /**
+     * 广电sn
+     */
+    @Schema(description = "广电sn")
+    private String gdSn;
+
+
+    /**
+     * 状态 未处理=0 已作废=-1 报备成功=1
+     */
+    @Schema(description = "状态 未处理=0 已作废=-1 报备成功=1")
+    private Integer status;
+
+
+
+
+
+	
+
+}

+ 4 - 0
kxs-product/kxs-product-biz/pom.xml

@@ -75,6 +75,10 @@
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-crypto</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-json</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/KxsProductApplication.java

@@ -4,6 +4,7 @@ import com.kxs.common.security.annotation.EnableAuthResourceServer;
 import com.kxs.common.swagger.annotation.EnableKxsDoc;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
 
 
 /**
@@ -15,6 +16,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 @SpringBootApplication
 @EnableAuthResourceServer
 @EnableKxsDoc(value = "product")
+@EnableAsync
 public class KxsProductApplication {
 
 	public static void main(String[] args) {

+ 52 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/config/RsaProperties.java

@@ -0,0 +1,52 @@
+
+package com.kxs.product.biz.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+/**
+ * 广电 配置信息
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-18
+ */
+@Data
+@Component
+@RefreshScope
+@ConfigurationProperties("rsa")
+public class RsaProperties {
+
+	/**
+	 * 广电配置信息
+	 */
+	private GdProperties gd = new GdProperties();
+
+	@Data
+	public static class GdProperties {
+
+		/**
+		 * 请求地址
+		 */
+		private String url;
+
+		/**
+		 * 机构号
+		 */
+		private String brhNo;
+
+		/**
+		 * 公钥
+		 */
+		private String publicKey;
+
+		/**
+		 * 私钥
+		 */
+		private String privateKey;
+
+	}
+
+
+}

+ 33 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/constant/enums/GdReportEnum.java

@@ -0,0 +1,33 @@
+package com.kxs.product.biz.constant.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 商户模块枚举类
+ *
+ * @author Lxq
+ * @date 2023-10-25
+ */
+@Getter
+@AllArgsConstructor
+public enum GdReportEnum {
+
+    /**
+     * 报备状态
+     */
+    PENDING(0, "待处理"),
+    REPORT(1, "已报备"),
+    CANCEL(-1, "已作废"),
+
+    /**
+     * 匹配状态
+     */
+    CHECK_NO(0, "未匹配"),
+    CHECK_SUC(1, "匹配成功");
+
+    //状态码
+    private final Integer type;
+    //状态码码描述
+    private final String description;
+}

+ 78 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/controller/admin/SysGdController.java

@@ -0,0 +1,78 @@
+package com.kxs.product.biz.controller.admin;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.product.api.model.KxsGdReport;
+import com.kxs.product.biz.service.KxsGdReportService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 产品模块(SysGd)控制层
+ *
+ * @author 系统
+ * @since 2024-04-23 10:44:27
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("sysGd")
+public class SysGdController {
+
+    /**
+     * 服务对象
+     */
+    private final KxsGdReportService kxsGdReportService;
+
+
+
+    /**
+     * 广电报备-列表
+     *
+     * @param page 分页对象
+     * @param param 查询实体
+     * @return 广电报备-列表
+     */
+    @GetMapping("/page")
+    public R page(Page<KxsGdReport> page, KxsGdReport param) {
+        return R.ok(kxsGdReportService.page(page,
+                Wrappers.<KxsGdReport>lambdaQuery().eq(StrUtil.isNotBlank(param.getGdSn()),KxsGdReport::getGdSn, param.getGdSn())
+                        .eq(StrUtil.isNotBlank(param.getGdMobile()),KxsGdReport::getGdMobile, param.getGdMobile())
+                        .eq(StrUtil.isNotBlank(param.getUserCode()),KxsGdReport::getUserCode, param.getUserCode())
+                        .eq(param.getIsCheck() != null, KxsGdReport::getIsCheck, param.getIsCheck())
+                ));
+    }
+
+
+    /**
+     * 广电报备-编辑
+     *
+     * @param param 实体对象
+     * @return 广电报备-编辑
+     */
+    @PutMapping("/update")
+    public R update(@RequestBody KxsGdReport param) {
+
+        return R.ok(kxsGdReportService.updateData(param));
+    }
+
+    /**
+     * 广电报备-匹配数据
+     *
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @return 广电报备-编辑
+     */
+    @GetMapping("/check")
+    public R check(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
+
+        return kxsGdReportService.checkGdData(startTime, endTime);
+    }
+
+
+
+
+
+}
+

+ 104 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/controller/kxsapp/GdController.java

@@ -0,0 +1,104 @@
+package com.kxs.product.biz.controller.kxsapp;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.R;
+import com.kxs.common.security.annotation.Inner;
+import com.kxs.product.api.dto.kxsapp.gd.GdReportDTO;
+import com.kxs.product.api.dto.kxsapp.gd.GdReportPutDTO;
+import com.kxs.product.api.model.KxsGdReport;
+import com.kxs.product.api.vo.kxsapp.gd.GdReportListVO;
+import com.kxs.product.biz.service.KxsGdReportService;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 产品模块(Gd)控制层
+ *
+ * @author 系统
+ * @since 2024-04-23 10:44:27
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("gd")
+public class GdController {
+
+    /**
+     * 服务对象
+     */
+    private final KxsGdReportService kxsGdReportService;
+
+
+
+    /**
+     * 广电报备-提交工单
+     *
+     * @param param 实体对象
+     * @return 广电报备-提交工单
+     */
+    @Inner(value = false)
+    @PostMapping("/add")
+    public R add(@RequestBody @Valid GdReportPutDTO param) {
+
+        return R.ok(kxsGdReportService.addReport(param));
+    }
+
+
+    /**
+     * 广电报备-列表
+     *
+     * @param page 分页对象
+     * @param status 状态
+     * @param keyword 关键字
+     * @return 广电报备-列表
+     */
+    @GetMapping("/page")
+    public R page(Page<GdReportListVO> page, @RequestParam("status") Integer status, @RequestParam(value = "keyword", required = false) String keyword) {
+
+        return R.ok(kxsGdReportService.getByPage(page, status, keyword));
+    }
+
+
+    /**
+     * 广电报备-数量接口
+     *
+     * @return 广电报备-数量接口
+     */
+    @GetMapping("/dot")
+    public R dot() {
+
+        return R.ok(kxsGdReportService.dotNum());
+    }
+
+
+    /**
+     * 广电报备-作废
+     *
+     * @param param 实体对象
+     * @return 广电报备-作废
+     */
+    @PutMapping("/cancel")
+    public R cancel(@RequestBody KxsGdReport param) {
+
+        return R.ok(kxsGdReportService.cancelReport(param));
+    }
+
+
+    /**
+     * 广电报备-报备
+     *
+     * @param param 实体对象
+     * @return 广电报备-报备
+     */
+    @PutMapping("/report")
+    public R report(@RequestBody @Valid GdReportDTO param) {
+
+        return R.ok(kxsGdReportService.report(param));
+    }
+
+
+
+
+
+}
+

+ 30 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/mapper/KxsGdReportMapper.java

@@ -0,0 +1,30 @@
+package com.kxs.product.biz.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.product.api.model.KxsGdReport;
+import com.kxs.product.api.vo.kxsapp.gd.GdReportListVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 广电报备入网表(KxsGdReport)表数据库访问层
+ *
+ * @author 系统
+ * @since 2024-04-23 10:44:23
+ */
+@Mapper
+public interface KxsGdReportMapper extends BaseMapper<KxsGdReport> {
+
+    /**
+     * app分页
+     *
+     * @param page    页
+     * @param userId 用户ID
+     * @param keyword 关键词
+     * @return {@link IPage}<{@link GdReportListVO}>
+     */
+    IPage<GdReportListVO> getByPage(Page<GdReportListVO> page, @Param("userId") Long userId, @Param("status") Integer status, @Param("keyword") String keyword);
+}
+

+ 77 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/KxsGdReportService.java

@@ -0,0 +1,77 @@
+package com.kxs.product.biz.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.kxs.common.core.util.R;
+import com.kxs.product.api.dto.kxsapp.gd.GdReportDTO;
+import com.kxs.product.api.dto.kxsapp.gd.GdReportPutDTO;
+import com.kxs.product.api.model.KxsGdReport;
+import com.kxs.product.api.vo.kxsapp.gd.GdDotNumVO;
+import com.kxs.product.api.vo.kxsapp.gd.GdReportListVO;
+
+/**
+ * 广电报备入网表(KxsGdReport)表服务接口
+ *
+ * @author 系统
+ * @since 2024-04-23 10:44:23
+ */
+public interface KxsGdReportService extends IService<KxsGdReport> {
+
+    /**
+     * 入网报备信息增加
+     *
+     * @param param 参数
+     */
+    Boolean addReport(GdReportPutDTO param);
+
+    /**
+     * app分页
+     *
+     * @param page    页
+     * @param keyword 关键词
+     * @return {@link IPage}<{@link GdReportListVO}>
+     */
+    IPage<GdReportListVO> getByPage(Page<GdReportListVO> page,  Integer status, String keyword);
+
+    /**
+     * 数量接口
+     *
+     * @return {@link GdDotNumVO}
+     */
+    GdDotNumVO dotNum();
+
+    /**
+     * 广电报备-作废
+     *
+     * @param param 参数
+     * @return {@link Object}
+     */
+    Boolean cancelReport(KxsGdReport param);
+
+    /**
+     * 报备
+     *
+     * @param param 参数
+     * @return {@link Boolean}
+     */
+    Boolean report(GdReportDTO param);
+
+    /**
+     * sys更新数据
+     *
+     * @param param 参数
+     * @return {@link Boolean}
+     */
+    Boolean updateData(KxsGdReport param);
+
+    /**
+     * 匹配 GD 数据
+     *
+     * @param startTime 开始时间
+     * @param endTime   结束时间
+     * @return {@link R}
+     */
+    R checkGdData(String startTime, String endTime);
+}
+

+ 33 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/KxsGdService.java

@@ -0,0 +1,33 @@
+package com.kxs.product.biz.service;
+
+import com.kxs.product.api.res.gd.GdQueryOrderRes;
+
+import java.util.List;
+
+/**
+ * KXS 广电 服务
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-23
+ */
+public interface KxsGdService {
+
+
+    /**
+     * 查询开卡订单数据
+     *
+     * @param startTime 开始时间
+     * @param endTime   结束时间
+     * @param pageNo
+     * @param pageSize
+     */
+    List<GdQueryOrderRes.GdQueryOrder> queryCardOrders(String startTime, String endTime, int pageNo, int pageSize);
+
+    /**
+     * 匹配 广电 开卡数据
+     *
+     * @param startTime 开始时间
+     * @param endTime   结束时间
+     */
+    void checkGdAsyncData(String startTime, String endTime);
+}

+ 157 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/impl/KxsGdReportServiceImpl.java

@@ -0,0 +1,157 @@
+package com.kxs.product.biz.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kxs.common.core.constant.CommonConstants;
+import com.kxs.common.core.constant.SecurityConstants;
+import com.kxs.common.core.constant.enums.ErrorTypeEnum;
+import com.kxs.common.core.exception.GlobalCustomerException;
+import com.kxs.common.core.util.R;
+import com.kxs.common.core.util.RetOps;
+import com.kxs.common.security.util.SecurityUtils;
+import com.kxs.product.api.dto.kxsapp.gd.GdReportDTO;
+import com.kxs.product.api.dto.kxsapp.gd.GdReportPutDTO;
+import com.kxs.product.api.model.KxsGdReport;
+import com.kxs.product.api.res.gd.GdQueryOrderRes;
+import com.kxs.product.api.vo.kxsapp.gd.GdDotNumVO;
+import com.kxs.product.api.vo.kxsapp.gd.GdReportListVO;
+import com.kxs.product.biz.constant.enums.GdReportEnum;
+import com.kxs.product.biz.mapper.KxsGdReportMapper;
+import com.kxs.product.biz.service.KxsGdReportService;
+import com.kxs.product.biz.service.KxsGdService;
+import com.kxs.user.api.feign.RemoteKxsUserService;
+import com.kxs.user.api.model.KxsUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 广电报备入网表(KxsGdReport)表服务实现类
+ *
+ * @author 系统
+ * @since 2024-04-23 10:44:23
+ */
+@Service("kxsGdReportService")
+@RequiredArgsConstructor
+public class KxsGdReportServiceImpl extends ServiceImpl<KxsGdReportMapper, KxsGdReport> implements KxsGdReportService {
+
+    private final RemoteKxsUserService remoteKxsUserService;
+
+    private final KxsGdService kxsGdService;
+
+
+    @Override
+    public Boolean addReport(GdReportPutDTO param) {
+
+
+        R<Boolean> booleanR = remoteKxsUserService.checkMobileCode(param.getPutMobile(), param.getCode(), SecurityConstants.FROM_IN);
+        if(booleanR.getStatus() != CommonConstants.SUCCESS || !booleanR.getData()){
+            throw new GlobalCustomerException(booleanR.getMsg());
+        }
+        R<KxsUser> kxsUserR = remoteKxsUserService.loadUserByCode(param.getUserCode(), SecurityConstants.FROM_IN);
+        KxsUser user = RetOps.of(kxsUserR)
+                .getData()
+                .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));
+
+        KxsGdReport kxsGdReport = new KxsGdReport();
+        BeanUtil.copyProperties(param, kxsGdReport);
+        kxsGdReport.setUserId(user.getId());
+        return this.save(kxsGdReport);
+    }
+
+    @Override
+    public IPage<GdReportListVO> getByPage(Page<GdReportListVO> page, Integer status, String keyword) {
+
+        Long userId = SecurityUtils.getUser().getId();
+        return baseMapper.getByPage(page, userId, status, keyword);
+    }
+
+    @Override
+    public GdDotNumVO dotNum() {
+
+        Long userId = SecurityUtils.getUser().getId();
+        GdDotNumVO gdDotNumVO = new GdDotNumVO();
+        gdDotNumVO.setPendNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getUserId, userId).eq(KxsGdReport::getStatus, GdReportEnum.PENDING.getType()))).orElse(0L));
+        gdDotNumVO.setReportNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getUserId, userId).eq(KxsGdReport::getStatus, GdReportEnum.REPORT.getType()))).orElse(0L));
+        gdDotNumVO.setCancelNum(Optional.of(this.count(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getUserId, userId).eq(KxsGdReport::getStatus, GdReportEnum.CANCEL.getType()))).orElse(0L));
+
+        return gdDotNumVO;
+    }
+
+    @Override
+    public Boolean cancelReport(KxsGdReport param) {
+
+        Optional.ofNullable(param.getId()).orElseThrow(() -> new GlobalCustomerException("参数错误"));
+        KxsGdReport kxsGdReport = this.getById(param.getId());
+        Optional.ofNullable(kxsGdReport).orElseThrow(() -> new GlobalCustomerException("参数错误"));
+        if(Objects.equals(kxsGdReport.getStatus(), GdReportEnum.REPORT.getType())){
+            throw new GlobalCustomerException("该工单已报备,无法作废");
+        }
+
+        kxsGdReport.setStatus(GdReportEnum.CANCEL.getType());
+
+        return this.updateById(kxsGdReport);
+    }
+
+    @Override
+    public Boolean report(GdReportDTO param) {
+
+        KxsGdReport kxsGdReport = this.getById(param.getId());
+
+        Optional.ofNullable(kxsGdReport).orElseThrow(() -> new GlobalCustomerException("参数错误"));
+        if(!Objects.equals(kxsGdReport.getStatus(), GdReportEnum.PENDING.getType())){
+            throw new GlobalCustomerException("该工单状态错误");
+        }
+        //判断sn是否重复
+        KxsGdReport report = this.getOne(Wrappers.<KxsGdReport>lambdaQuery().eq(KxsGdReport::getGdSn, param.getGdSn()));
+        if(report != null){
+            throw new GlobalCustomerException("该工单sn已报备");
+        }
+
+
+        kxsGdReport.setStatus(GdReportEnum.REPORT.getType());
+        kxsGdReport.setGdMobile(param.getGdMobile());
+        kxsGdReport.setGdSn(param.getGdSn());
+
+        return this.updateById(kxsGdReport);
+    }
+
+    @Override
+    public Boolean updateData(KxsGdReport param) {
+
+        Optional.ofNullable(param.getId()).orElseThrow(() -> new GlobalCustomerException("参数错误"));
+        KxsGdReport kxsGdReport = this.getById(param.getId());
+        Optional.ofNullable(kxsGdReport).orElseThrow(() -> new GlobalCustomerException("参数错误"));
+
+        if(Objects.equals(kxsGdReport.getIsCheck(), GdReportEnum.CHECK_SUC.getType())){
+            throw new GlobalCustomerException("该工单已匹配,无法更新");
+        }
+
+
+        return this.update(Wrappers.<KxsGdReport>lambdaUpdate()
+                .eq(KxsGdReport::getId, param.getId())
+                .set(KxsGdReport::getPutName, param.getPutName())
+                .set(KxsGdReport::getGdSn, param.getGdSn())
+                .set(KxsGdReport::getGdMobile, param.getGdMobile()));
+    }
+
+    @Override
+    public R checkGdData(String startTime, String endTime) {
+
+        kxsGdService.checkGdAsyncData(startTime, endTime);
+
+        return R.ok();
+    }
+
+
+
+}
+

+ 109 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/impl/KxsGdServiceImpl.java

@@ -0,0 +1,109 @@
+package com.kxs.product.biz.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.http.Header;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.kxs.common.core.exception.GlobalCustomerException;
+import com.kxs.product.api.model.KxsGdReport;
+import com.kxs.product.api.req.gd.GdQueryCardOrderReq;
+import com.kxs.product.api.res.gd.GdCommRes;
+import com.kxs.product.api.res.gd.GdQueryOrderRes;
+import com.kxs.product.biz.config.RsaProperties;
+import com.kxs.product.biz.constant.enums.GdReportEnum;
+import com.kxs.product.biz.mapper.KxsGdReportMapper;
+import com.kxs.product.biz.service.KxsGdService;
+import com.kxs.product.biz.util.GdRsaUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * KXS 广电 服务实现
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-23
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class KxsGdServiceImpl implements KxsGdService {
+
+    private final RsaProperties rsaProperties;
+
+    private final KxsGdReportMapper kxsGdReportMapper;
+
+    @Async("getAsyncExecutor")
+    public void checkGdAsyncData(String startTime, String endTime){
+        int pageNo = 1;
+        int pageSize = 50;
+
+        do {
+            List<GdQueryOrderRes.GdQueryOrder> list = this.queryCardOrders(startTime, endTime, pageNo, pageSize);
+            if (list.isEmpty()) {
+                pageNo = -1;
+            }else{
+                for (GdQueryOrderRes.GdQueryOrder gdQueryOrder : list) {
+                    if("已激活".equals(gdQueryOrder.getActivationStatusName())){
+                        KxsGdReport kxsGdReport = kxsGdReportMapper.selectOne(Wrappers.<KxsGdReport>lambdaQuery()
+                                        .eq(KxsGdReport::getGdSn, gdQueryOrder.getIccId())
+                                .eq(KxsGdReport::getGdMobile, gdQueryOrder.getPhoneNo()));
+                        if(kxsGdReport != null){
+                            kxsGdReportMapper.update(null, Wrappers.<KxsGdReport>lambdaUpdate().eq(KxsGdReport::getId, kxsGdReport.getId())
+                                            .set(KxsGdReport::getIsCheck, GdReportEnum.CHECK_SUC.getType())
+                                            .set(KxsGdReport::getGdMobile, gdQueryOrder.getPhoneNo()));
+                            //TODO 调用激活接口
+
+                        }
+                    }
+                }
+                pageNo++;
+            }
+        }while (pageNo != -1);
+
+    }
+
+    @Override
+    public List<GdQueryOrderRes.GdQueryOrder> queryCardOrders(String startTime, String endTime, int pageNo, int pageSize) {
+
+        try {
+            String url = "https://" + rsaProperties.getGd().getUrl() + "/ycsim-business/openapi/query_card_order_info";
+
+            long timestamp = System.currentTimeMillis() / 1000;
+
+            GdQueryCardOrderReq req = GdQueryCardOrderReq.builder()
+                    .queryBeginTime(startTime)
+                    .queryEndTime(endTime)
+                    .brhNo(rsaProperties.getGd().getBrhNo())
+                    .pageNo(String.valueOf(pageNo))
+                    .pageSize(String.valueOf(pageSize))
+                    .timestamp(String.valueOf(timestamp)).build();
+            String sign = GdRsaUtils.rsa256Sign(BeanUtil.beanToMap(req), rsaProperties.getGd().getPrivateKey());
+            req.setSign(sign);
+            String body = JSONUtil.toJsonStr(req);
+            String response = HttpRequest.post(url)
+                    .header(Header.CONTENT_TYPE, "application/json")
+                    .body(body)
+                    .timeout(50000)//超时,毫秒
+                    .execute().body();
+            Optional.ofNullable(response).orElseThrow(() -> new GlobalCustomerException("调用接口失败"));
+            GdCommRes<GdQueryOrderRes> commRes = JSONUtil.toBean(response, new TypeReference<GdCommRes<GdQueryOrderRes>>() {}, true);
+            if(commRes.getResultCode() == 1){
+                return commRes.getData().getRecords();
+            }else{
+                throw new GlobalCustomerException(commRes.getErrorDesc());
+            }
+
+        } catch (Exception e) {
+            log.error("请求广电接口报错:{}", e.getLocalizedMessage());
+            throw new GlobalCustomerException(e.getLocalizedMessage());
+        }
+    }
+
+}

+ 0 - 1
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/service/impl/KxsMachineServiceImpl.java

@@ -52,7 +52,6 @@ import java.util.stream.Collectors;
 @Service("kxsMachineService")
 @RequiredArgsConstructor
 @Slf4j
-@EnableAsync
 public class KxsMachineServiceImpl extends ServiceImpl<KxsMachineMapper, KxsMachine> implements KxsMachineService {
 
     private final KxsBrandMapper kxsBrandMapper;

+ 284 - 0
kxs-product/kxs-product-biz/src/main/java/com/kxs/product/biz/util/GdRsaUtils.java

@@ -0,0 +1,284 @@
+package com.kxs.product.biz.util;
+
+import cn.hutool.core.util.StrUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * rsa验签工具。
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-23
+ */
+public class GdRsaUtils {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(GdRsaUtils.class);
+
+    public static final String KEY_ALGORITHM = "RSA";
+    public static final String DEFAULT_CHARSET = "UTF-8";
+    // TODO: 配置私钥 (用于加密)
+    public static final String DEFAULT_PRIVATE_KEY = "";
+    // TODO: 配置公钥 (用于解密)
+    public static final String DEFAULT_PUBLIC_KEY = "";
+
+    /**
+     * 获取公钥
+     *
+     * @param publicKeyStr
+     * @return
+     * @throws Exception
+     */
+    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
+        try {
+            byte[] buffer = Base64.getDecoder().decode(publicKeyStr);
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
+            RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
+            return restorePublicKey(publicKey.getEncoded());
+
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此算法");
+        } catch (InvalidKeySpecException e) {
+            throw new Exception("公钥非法");
+        } catch (IOException e) {
+            throw new Exception("公钥数据内容读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("公钥数据为空");
+        }
+    }
+
+    /**
+     * 还原公钥
+     *
+     * @param keyBytes
+     * @return
+     * @throws Exception
+     */
+    private static PublicKey restorePublicKey(byte[] keyBytes) throws Exception {
+        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
+        try {
+            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
+            return factory.generatePublic(x509EncodedKeySpec);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new Exception(e);
+        }
+    }
+
+    /**
+     * 通过私钥KEY获取解密私钥
+     *
+     * @param privateKeyStr
+     * @return
+     * @throws Exception
+     */
+    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
+        try {
+            byte[] buffer = Base64.getDecoder().decode(privateKeyStr);
+            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
+            return restorePrivateKey(privateKey.getEncoded());
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此算法");
+        } catch (InvalidKeySpecException e) {
+            throw new Exception("公钥非法");
+        } catch (IOException e) {
+            throw new Exception("公钥数据内容读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("公钥数据为空");
+        }
+    }
+
+
+    /**
+     * 还原私钥
+     *
+     * @param keyBytes
+     * @return
+     * @throws Exception
+     */
+    private static PrivateKey restorePrivateKey(byte[] keyBytes) throws Exception {
+        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
+        try {
+            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
+            return factory.generatePrivate(pkcs8EncodedKeySpec);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new Exception(e);
+        }
+    }
+
+    /**
+     * 根据请求参数生成待签名的字符串
+     *
+     * @param params
+     * @return
+     */
+    public static String getSignContent(Map<String, String> params) {
+        params.remove("sign");
+        Map<String, String> sortedParams = new TreeMap<>(params);
+
+        StringBuilder content = new StringBuilder();
+        List<String> keys = new ArrayList<>(sortedParams.keySet());
+        Collections.sort(keys);
+        int index = 0;
+        for (String key : keys) {
+            String value = sortedParams.get(key);
+            if (!StrUtil.isAllBlank(key, value)) {
+                content.append(index == 0 ? "" : "&").append(key).append("=").append(value);
+                index++;
+            }
+        }
+        return content.toString();
+    }
+
+    /**
+     * sha256WithRsa 验签
+     *
+     * @param content
+     * @param sign
+     * @param publicKey
+     * @param charset
+     * @return
+     */
+    public static boolean rsa256CheckContent(String content, String sign, String publicKey, String charset) throws Exception {
+        try {
+            PublicKey pubKey = loadPublicKey(publicKey);
+            Signature signature = Signature.getInstance("SHA256WithRSA");
+            signature.initVerify(pubKey);
+            if (StrUtil.isEmpty(charset)) {
+                signature.update(content.getBytes());
+            } else {
+                signature.update(content.getBytes(charset));
+            }
+            return signature.verify(Base64.getDecoder().decode(sign.getBytes()));
+        } catch (Exception e) {
+            throw new Exception("签名失败,RSAcontent=" + content + ";charset=" + charset + ";sign=" + sign, e);
+        }
+    }
+
+    /**
+     * sha256WithRsa 签名
+     *
+     * @param content
+     * @param privateKey
+     * @param charset
+     * @return
+     */
+    public static String rsa256Sign(String content, String privateKey, String charset) throws Exception {
+        try {
+            PrivateKey priKey = loadPrivateKey(privateKey);
+            Signature signature = Signature.getInstance("SHA256WithRSA");
+            signature.initSign(priKey);
+            if (StrUtil.isEmpty(charset)) {
+                signature.update(content.getBytes());
+            } else {
+                signature.update(content.getBytes(charset));
+            }
+            byte[] signed = signature.sign();
+            return new String(Base64.getEncoder().encode(signed));
+        } catch (Exception e) {
+            throw new Exception("签名失败,RSAcontent=" + content + ";charset=" + charset, e);
+        }
+    }
+
+    /**
+     * 生成接口签名
+     *
+     * @param reqParams
+     * @return
+     * @throws Exception
+     */
+    public static String rsa256Sign(Map<String, Object> reqParams, String privateKey) throws Exception {
+        Map<String, String> params = reqParams.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> String.valueOf(v.getValue())));
+        String checkContent = GdRsaUtils.getSignContent(params);
+        String sign = null;
+        try {
+            sign = GdRsaUtils.rsa256Sign(checkContent, privateKey, DEFAULT_CHARSET);
+        } catch (Exception e) {
+            throw new Exception(e);
+        }
+        return sign;
+    }
+
+    /**
+     * 校验接口请求签名
+     *
+     * @param reqParams
+     * @return
+     * @throws Exception
+     */
+    public static boolean checkSign(Map<String, Object> reqParams, String publicKey) throws Exception {
+        Map<String, String> params = reqParams.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> String.valueOf(v.getValue())));
+        String checkContent = GdRsaUtils.getSignContent(params);
+        String sign = (String) reqParams.get("sign");
+        boolean isSuccess;
+        try {
+            isSuccess = GdRsaUtils.rsa256CheckContent(checkContent, sign, publicKey, DEFAULT_CHARSET);
+        } catch (Exception e) {
+            throw new Exception(e);
+        }
+        return isSuccess;
+    }
+
+    /**
+     * 生成RSA密钥对
+     */
+    public static void generateKeyPair() {
+        try {
+            // 指定生成密钥的算法和密钥长度(密钥长度,常用值:1024、2048、4096)
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+            kpg.initialize(1024);
+
+            // 获取密钥对
+            KeyPair keyPair = kpg.genKeyPair();
+            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
+            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+
+            // 获取公钥字符串
+            String publicKeyString = new String(Base64.getDecoder().decode(publicKey.getEncoded()));
+            // 得到私钥字符串
+            String privateKeyString = new String(Base64.getDecoder().decode((privateKey.getEncoded())));
+
+            System.out.println("公钥:" + publicKeyString);
+            System.out.println("私钥:" + privateKeyString);
+        } catch (Exception e) {
+            LOGGER.info("生成公钥私钥异常:" + e.getMessage());
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        // 生成签名
+        Map<String, Object> reqParams = new HashMap<>(8);
+        reqParams.put("pageNo", 1);
+        reqParams.put("pageSize", 10);
+        reqParams.put("brhNo", "test");
+        reqParams.put("queryBeginTime", "2024-01-16");
+        reqParams.put("queryEndTime", "2024-01-16");
+        reqParams.put("timestamp", System.currentTimeMillis() / 1000);
+        String sign = GdRsaUtils.rsa256Sign(reqParams, DEFAULT_PRIVATE_KEY);
+        System.out.println("生成签名:" + sign);
+
+        // 验签
+        reqParams.put("sign", sign);
+        final boolean result = GdRsaUtils.checkSign(reqParams, DEFAULT_PUBLIC_KEY);
+        assert result;
+    }
+
+}

+ 38 - 0
kxs-product/kxs-product-biz/src/main/resources/mapper/KxsGdReportMapper.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kxs.product.biz.mapper.KxsGdReportMapper">
+
+    <resultMap type="com.kxs.product.api.model.KxsGdReport" id="KxsGdReportMap">
+        <result column="id" property="id" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+        <result column="del_flag" property="delFlag" />
+        <result column="version" property="version" />
+        <result column="user_id" property="userId" />
+        <result column="username" property="username" />
+        <result column="user_code" property="userCode" />
+        <result column="province" property="province" />
+        <result column="city" property="city" />
+        <result column="put_name" property="putName" />
+        <result column="put_mobile" property="putMobile" />
+        <result column="remark" property="remark" />
+        <result column="status" property="status" />
+        <result column="gd_sn" property="gdSn" />
+        <result column="gd_mobile" property="gdMobile" />
+        <result column="is_check" property="isCheck" />
+
+    </resultMap>
+    <select id="getByPage" resultType="com.kxs.product.api.vo.kxsapp.gd.GdReportListVO">
+        select id, create_time, put_name, put_mobile, gd_sn, gd_mobile, status
+        from kxs_gd_report
+        <where>
+            and del_flag = 0
+            and user_id = #{userId}
+            and status = #{status}
+            <if test="keyword != null and keyword != ''">
+                and (put_name = #{keyword} or put_mobile = #{keyword})
+            </if>
+        </where>
+    </select>
+
+</mapper>

+ 12 - 0
kxs-system/kxs-system-api/src/main/java/com/kxs/system/api/dto/kxsapp/AddStudyPersonDTO.java

@@ -0,0 +1,12 @@
+package com.kxs.system.api.dto.kxsapp;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class AddStudyPersonDTO {
+    @NotNull(message = "id不能为空")
+    private long id;
+    @NotNull(message = "类型不能为空")
+    private int type;
+}

+ 31 - 6
kxs-system/kxs-system-biz/src/main/java/com/kxs/system/biz/controller/kxsapp/MorningController.java

@@ -1,15 +1,18 @@
 package com.kxs.system.biz.controller.kxsapp;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kxs.common.core.util.AssertUtil;
 import com.kxs.common.core.util.R;
+import com.kxs.system.api.dto.kxsapp.AddStudyPersonDTO;
 import com.kxs.system.api.model.KxsMorning;
 import com.kxs.system.biz.service.KxsMorningService;
+import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.springdoc.core.annotations.ParameterObject;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * 首页(Morning)控制层
@@ -34,12 +37,34 @@ public class MorningController {
      * @return 商学院-晨会列表
      */
     @GetMapping("/page")
-    public R page(@ParameterObject Page<KxsMorning> page) {
-
+    public R page(@ParameterObject Page<KxsMorning> page,@RequestParam("month") String month) {
+        AssertUtil.isYyyyMM(month);
+        String skbYear = month.substring(0, 4);
+        String subMonth = month.substring(5, 7);
+        //拼接
         return R.ok(kxsMorningService.page(page,
-                Wrappers.<KxsMorning>lambdaQuery().orderByDesc(KxsMorning::getCreateTime)));
+                new QueryWrapper<KxsMorning>()
+                        .apply("YEAR(create_time) = {0} AND MONTH(create_time) = {1}", skbYear, subMonth)
+                        .orderByDesc("create_time")));
+    }
+
+
+
+    /**
+     * 商学院-晨会列表-增加学习人数
+     *
+     * @param addStudyPersonDTO 参数对象
+     * @return 商学院-晨会列表
+     */
+    @GetMapping("/addStudyPerson")
+    public R addStudyPerson(@Valid @RequestBody AddStudyPersonDTO addStudyPersonDTO) {
+
+        //拼接
+        return kxsMorningService.addStudyPerson(addStudyPersonDTO.getId(),addStudyPersonDTO.getType());
     }
 
 
+
+
 }
 

+ 8 - 0
kxs-system/kxs-system-biz/src/main/java/com/kxs/system/biz/service/KxsMorningService.java

@@ -1,6 +1,7 @@
 package com.kxs.system.biz.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.kxs.common.core.util.R;
 import com.kxs.system.api.model.KxsMorning;
 
 /**
@@ -10,6 +11,13 @@ import com.kxs.system.api.model.KxsMorning;
  * @since 2023-12-15 12:16:31
  */
 public interface KxsMorningService extends IService<KxsMorning> {
+    /**
+     * 商学院-晨会列表-增加学习人数
+     *
+     * @param type 1为晨会  2为学堂
+     * @return 商学院-晨会列表
+     */
+    R addStudyPerson(long id, int type);
 
 }
 

+ 32 - 1
kxs-system/kxs-system-biz/src/main/java/com/kxs/system/biz/service/impl/KxsMorningServiceImpl.java

@@ -1,9 +1,14 @@
 package com.kxs.system.biz.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kxs.common.core.constant.enums.ErrorTypeEnum;
+import com.kxs.common.core.util.R;
+import com.kxs.system.api.model.KxsSchoolStudy;
 import com.kxs.system.biz.mapper.KxsMorningMapper;
 import com.kxs.system.api.model.KxsMorning;
+import com.kxs.system.biz.mapper.KxsSchoolStudyMapper;
 import com.kxs.system.biz.service.KxsMorningService;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
 /**
@@ -13,7 +18,33 @@ import org.springframework.stereotype.Service;
  * @since 2023-12-15 12:16:31
  */
 @Service("kxsMorningService")
+@RequiredArgsConstructor
 public class KxsMorningServiceImpl extends ServiceImpl<KxsMorningMapper, KxsMorning> implements KxsMorningService {
-
+    private final KxsSchoolStudyMapper kxsSchoolStudyMapper;
+    @Override
+    public R addStudyPerson(long id, int type) {
+        if (type == 1){
+            //1为每日晨会
+            KxsMorning byId = getById(id);
+            if (byId == null){
+                return R.failed(ErrorTypeEnum.SYS_MORNING_IS_NULL.getDescription());
+            }
+            Integer studyPerson = byId.getStudyPerson();
+            byId.setStudyPerson(++studyPerson);
+            updateById(byId);
+        } else if (type == 2) {
+            //2为创客学堂
+            KxsSchoolStudy kxsSchoolStudy = kxsSchoolStudyMapper.selectById(id);
+            if (kxsSchoolStudy == null){
+                return R.failed(ErrorTypeEnum.SYS_MORNING_IS_NULL.getDescription());
+            }
+            Integer studyPerson = kxsSchoolStudy.getStudyPerson();
+            kxsSchoolStudy.setStudyPerson(++studyPerson);
+            kxsSchoolStudyMapper.updateById(kxsSchoolStudy);
+        }else {
+            return R.failed(ErrorTypeEnum.SYS_TYPE_ERROR);
+        }
+        return R.ok();
+    }
 }
 

+ 8 - 0
kxs-user/kxs-user-api/src/main/java/com/kxs/user/api/feign/RemoteKxsUserService.java

@@ -25,6 +25,14 @@ import java.util.List;
 public interface RemoteKxsUserService {
 
 
+	/**
+	 * 通过手机号码校验验证码
+	 * @param phone 电话信息
+	 * @param code 验证码
+	 * @param from 调用标志
+	 */
+	@GetExchange("/app/checkMobileCode")
+	R<Boolean> checkMobileCode(@RequestParam("phone") String phone, @RequestParam("code") String code, @RequestHeader(SecurityConstants.FROM) String from);
 
 	/**
 	 * 通过手机号码查询用户信息

+ 6 - 0
kxs-user/kxs-user-biz/pom.xml

@@ -79,6 +79,12 @@
             <groupId>com.kxs</groupId>
             <artifactId>kxs-product-api</artifactId>
         </dependency>
+        <!-- 实现对 RocketMQ 的自动化配置 -->
+        <dependency>
+            <groupId>com.kxs</groupId>
+            <artifactId>kxs-common-mq</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 13 - 0
kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/controller/kxsapp/KxsAppController.java

@@ -57,6 +57,19 @@ public class KxsAppController {
         return R.ok(kxsUserService.sendCode(phone));
     }
 
+    /**
+     * 验证验证码
+     *
+     * @param phone 手机号
+     */
+    @Inner
+    @GetMapping("/checkMobileCode")
+    public R checkMobileCode(@RequestParam("phone") String phone, @RequestParam("code") String code) {
+
+        kxsUserService.checkValidateCode(phone, code);
+        return R.ok(Boolean.TRUE);
+    }
+
 
     /**
      * 是否设置支付密码

+ 42 - 0
kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/controller/kxsapp/TestMq.java

@@ -0,0 +1,42 @@
+package com.kxs.user.biz.controller.kxsapp;
+
+import com.kxs.common.core.util.R;
+import com.kxs.common.security.annotation.Inner;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "test-group")
+public class TestMq implements RocketMQListener<String> {
+
+    private final RocketMQTemplate rocketMQTemplate;
+
+    public void onMessage(String message) {
+        log.info("received message: {}", message);
+    }
+
+
+    @Inner(value = false)
+    @GetMapping("/send/msg")
+    public R sendMsg1 (){
+        try {
+            Message<String> msg = MessageBuilder.withPayload("Hello,RocketMQ").build();
+            //发送信息
+            rocketMQTemplate.send("test-topic-1", msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return R.ok();
+    }
+}

+ 5 - 2
kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/service/impl/KxsUserServiceImpl.java

@@ -3,6 +3,7 @@ package com.kxs.user.biz.service.impl;
 import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.IdcardUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.crypto.SecureUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -38,6 +39,7 @@ import com.kxs.user.biz.constant.enums.UserErrorTypeEnum;
 import com.kxs.user.biz.constant.enums.UserRealStatusEnum;
 import com.kxs.user.biz.mapper.*;
 import com.kxs.user.biz.service.KxsUserService;
+import com.kxs.user.biz.util.SmsUtils;
 import io.seata.spring.annotation.GlobalTransactional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
@@ -186,9 +188,10 @@ public class KxsUserServiceImpl extends ServiceImpl<KxsUserMapper, KxsUser> impl
             throw new ValidateCodeException(UserErrorTypeEnum.CODE_NOT_EX.getDescription());
         }
 
-        String code = "111111"; //RandomUtil.randomNumbers(Integer.parseInt(UserConstants.CODE_SIZE));
+        String code = RandomUtil.randomNumbers(Integer.parseInt(UserConstants.CODE_SIZE));
         redisTemplate.opsForValue().set(key, code, UserConstants.CODE_TIME, TimeUnit.SECONDS);
-
+        //发送短信
+        SmsUtils.sendCode(mobile, code);
         return Boolean.TRUE;
     }
 

+ 75 - 0
kxs-user/kxs-user-biz/src/main/java/com/kxs/user/biz/util/SmsUtils.java

@@ -0,0 +1,75 @@
+package com.kxs.user.biz.util;
+
+import cn.hutool.http.Header;
+import cn.hutool.http.HttpRequest;
+import io.micrometer.common.util.StringUtils;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 短信程序
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-24
+ */
+public class SmsUtils {
+
+    public static void sendCode(String mobile, String code){
+
+        Map<String, String> queries = new HashMap<>();
+        queries.put("mobile", mobile);
+        queries.put("param", "**code**:" +code+",**minute**:5");
+
+        //smsSignId(短信前缀)和templateId(短信模板),可登录国阳云控制台自助申请。参考文档:http://help.guoyangyun.com/Problem/Qm.html
+
+        queries.put("smsSignId", "0f6eccbf0ff343029a7bffc144591fd8");
+        queries.put("templateId", "908e94ccf08b4476ba6c876d13f084ad");
+
+
+
+        String path = "https://gyytz.market.alicloudapi.com/sms/smsSend";
+        String url = SmsUtils.buildUrl(path, queries);
+
+        HttpRequest.post(url)
+                .header(Header.AUTHORIZATION, "APPCODE 8e5704921ca3422f80f0deb935a7ddc6")
+                .execute().body();
+
+    }
+    /**
+     * 构建url
+     *
+     * @param url    url
+     * @param queries 查询
+     * @return {@link String}
+     */
+    public static String buildUrl(String url, Map<String, String> queries) {
+        StringBuilder sbUrl = new StringBuilder();
+        sbUrl.append(url);
+        if (null != queries) {
+            StringBuilder sbQuery = new StringBuilder();
+            for (Map.Entry<String, String> query : queries.entrySet()) {
+                if (!sbQuery.isEmpty()) {
+                    sbQuery.append("&");
+                }
+                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
+                    sbQuery.append(query.getValue());
+                }
+                if (!StringUtils.isBlank(query.getKey())) {
+                    sbQuery.append(query.getKey());
+                    if (!StringUtils.isBlank(query.getValue())) {
+                        sbQuery.append("=");
+                        sbQuery.append(URLEncoder.encode(query.getValue(), StandardCharsets.UTF_8));
+                    }
+                }
+            }
+            if (!sbQuery.isEmpty()) {
+                sbUrl.append("?").append(sbQuery);
+            }
+        }
+
+        return sbUrl.toString();
+    }
+}

+ 9 - 0
kxs-visual/kxs-rocket/broker/broker.conf

@@ -0,0 +1,9 @@
+brokerClusterName = DefaultCluster
+brokerName = broker-a
+brokerId = 0
+deleteWhen = 04
+fileReservedTime = 48
+brokerRole = ASYNC_MASTER
+flushDiskType = ASYNC_FLUSH
+# 注意,宿主IP是你计算机网卡的IP
+brokerIP1 = 192.168.101.250

+ 11 - 0
pom.xml

@@ -38,6 +38,7 @@
         <knife4j.version>4.3.0</knife4j.version>
         <fastjson.version>1.2.83</fastjson.version>
         <oss.version>3.15.1</oss.version>
+        <rocketmq.version>2.2.3</rocketmq.version>
     </properties>
 
     <!-- 以下依赖 全局所有的模块都会引入  -->
@@ -212,6 +213,11 @@
                 <artifactId>aliyun-sdk-oss</artifactId>
                 <version>${oss.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.rocketmq</groupId>
+                <artifactId>rocketmq-spring-boot-starter</artifactId>
+                <version>${rocketmq.version}</version>
+            </dependency>
             <!-- 鉴权 -->
             <dependency>
                 <groupId>com.kxs</groupId>
@@ -239,6 +245,11 @@
                 <artifactId>kxs-common-oss</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.kxs</groupId>
+                <artifactId>kxs-common-mq</artifactId>
+                <version>${project.version}</version>
+            </dependency>