Преглед изворни кода

1、初始化微校推送服务

Bingo пре 3 година
родитељ
комит
0b01e8feb4
29 измењених фајлова са 1870 додато и 0 уклоњено
  1. 121 0
      pom.xml
  2. 15 0
      src/main/java/com/chuanghai/WxpushApplication.java
  3. 21 0
      src/main/java/com/chuanghai/config/WeixiaoConfig.java
  4. 83 0
      src/main/java/com/chuanghai/controller/PushProjectController.java
  5. 110 0
      src/main/java/com/chuanghai/controller/WxController.java
  6. 35 0
      src/main/java/com/chuanghai/dto/WeixiaoPushDTO.java
  7. 63 0
      src/main/java/com/chuanghai/entity/Organization.java
  8. 51 0
      src/main/java/com/chuanghai/entity/PushProject.java
  9. 185 0
      src/main/java/com/chuanghai/entity/User.java
  10. 53 0
      src/main/java/com/chuanghai/exception/BizCodeEnume.java
  11. 65 0
      src/main/java/com/chuanghai/exception/RRException.java
  12. 12 0
      src/main/java/com/chuanghai/mapper/PushProjectMapper.java
  13. 17 0
      src/main/java/com/chuanghai/service/PushProjectService.java
  14. 95 0
      src/main/java/com/chuanghai/service/impl/PushProjectServiceImpl.java
  15. 110 0
      src/main/java/com/chuanghai/utils/AesUtil.java
  16. 35 0
      src/main/java/com/chuanghai/utils/BaseResult.java
  17. 52 0
      src/main/java/com/chuanghai/utils/CommonResult.java
  18. 59 0
      src/main/java/com/chuanghai/utils/ReturnValueUtil.java
  19. 40 0
      src/main/java/com/chuanghai/vo/PushProjectVO.java
  20. 38 0
      src/main/resources/application.yml
  21. 18 0
      src/main/resources/mapper.wx/OrganizationMapper.xml
  22. 14 0
      src/main/resources/mapper.wx/PushProjectMapper.xml
  23. 44 0
      src/main/resources/mapper.wx/UserMapper.xml
  24. 28 0
      src/main/resources/smart-doc.json
  25. 7 0
      src/main/resources/static/doc/AllInOne.css
  26. 282 0
      src/main/resources/static/doc/index.adoc
  27. 66 0
      src/main/resources/static/doc/index.html
  28. 138 0
      src/main/resources/static/doc/search.js
  29. 13 0
      src/test/java/com/chuanghai/WxpushApplicationTests.java

+ 121 - 0
pom.xml

@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.7</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.chuanghai</groupId>
+    <artifactId>wxpush</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>wxpush</name>
+    <description>微校推送服务</description>
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>6.1.5.Final</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.68</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+
+
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <!-- 排除 doc 路径下的api文件 -->
+                        <exclude>**/doc/**</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+
+            <!-- smart doc -->
+            <plugin>
+                <groupId>com.github.shalousun</groupId>
+                <artifactId>smart-doc-maven-plugin</artifactId>
+                <version>2.2.2</version>
+                <configuration>
+                    <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
+                    <configFile>./src/main/resources/smart-doc.json</configFile>
+                    <!--指定项目名称-->
+                    <projectName>微校推送服务</projectName>
+                </configuration>
+                <executions>
+                    <execution>
+                        <!--如果不需要在执行编译时启动smart-doc,则将phase注释掉-->
+                        <phase>compile</phase>
+                        <goals>
+                            <!--smart-doc提供了html、openapi、markdown等goal,可按需配置-->
+                            <goal>html</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 15 - 0
src/main/java/com/chuanghai/WxpushApplication.java

@@ -0,0 +1,15 @@
+package com.chuanghai;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling //设置定时任务
+public class WxpushApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(WxpushApplication.class, args);
+    }
+
+}

+ 21 - 0
src/main/java/com/chuanghai/config/WeixiaoConfig.java

@@ -0,0 +1,21 @@
+package com.chuanghai.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @Author: binguo
+ * @Description: 微校相关配置
+ * @Date: 2022/12/28 星期三 10:48
+ * @Version: V1.0
+ **/
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "weixiao")
+public class WeixiaoConfig {
+
+    private String appKey;
+    private String appSecret;
+    private String ocode;
+}

+ 83 - 0
src/main/java/com/chuanghai/controller/PushProjectController.java

@@ -0,0 +1,83 @@
+package com.chuanghai.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.chuanghai.entity.PushProject;
+import com.chuanghai.service.PushProjectService;
+import com.chuanghai.utils.CommonResult;
+import com.chuanghai.vo.PushProjectVO;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import sun.awt.image.VolatileSurfaceManager;
+
+import java.util.List;
+
+/**
+ * 推送项目设置
+ *
+ * @Author: binguo
+ * @Date: 2022/12/28 星期三 10:48
+ * @Description: 推送项目设置
+ * @Version: 1.0
+ */
+@RestController
+@RequestMapping("/push")
+public class PushProjectController {
+
+    @Autowired
+    private PushProjectService pushProjectService;
+
+    /**
+     * 查询推送项目
+     * @return
+     */
+    @GetMapping("queryPushProject")
+    public CommonResult queryPushProject() {
+        QueryWrapper<PushProject> wrapper = new QueryWrapper<>();
+        wrapper.eq("statu", "0");
+        List<PushProject> pushProjectList = pushProjectService.list(wrapper);
+        return CommonResult.ok().setResult(pushProjectList);
+
+    }
+
+    /**
+     *  添加推送项目
+     * @param url  推送服务接口:post请求 json参数
+     * @param project  服务名称
+     * @return
+     */
+    @PostMapping("addPushProject")
+    public CommonResult addPushProject(@Param("url") String url, @Param("project") String project) {
+        pushProjectService.addPushProject(url, project);
+        return CommonResult.ok();
+    }
+
+
+    /**
+     *  修改推送项目
+     * @param pushProjectVo
+     * @return
+     */
+    @PutMapping("updatePushProject")
+    public CommonResult updatePushProject(@RequestBody PushProjectVO pushProjectVo){
+        PushProject pushProject = new PushProject();
+        BeanUtils.copyProperties(pushProjectVo, pushProject);
+        pushProjectService.updateById(pushProject);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除推送项目
+     * @param id
+     * @return
+     */
+    @DeleteMapping("deletePushProject")
+    public CommonResult deletePushProject(Long id){
+        pushProjectService.deletePushProject(id);
+        return CommonResult.ok();
+    }
+
+}
+

+ 110 - 0
src/main/java/com/chuanghai/controller/WxController.java

@@ -0,0 +1,110 @@
+package com.chuanghai.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.chuanghai.config.WeixiaoConfig;
+import com.chuanghai.dto.WeixiaoPushDTO;
+import com.chuanghai.service.PushProjectService;
+import com.chuanghai.utils.AesUtil;
+import com.chuanghai.utils.CommonResult;
+import com.chuanghai.utils.ReturnValueUtil;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 微校推送服务
+ *
+ * @Author: binguo
+ * @Date: 2022/12/28 星期三 15:27
+ * @Description: com.chuanghai.controller
+ * @Version: 1.0
+ */
+@Slf4j
+@Controller
+@RequestMapping("/wxc")
+public class WxController {
+
+    @Autowired
+    private WeixiaoConfig weixiaoConfig;
+
+    @Autowired
+    private PushProjectService pushProjectService;
+    /**
+     * 应用有效凭证
+     */
+    private String access_token = "";
+
+
+    /**
+     * 获取微校 应用有效凭证
+     */
+    @Async
+   // @Scheduled(fixedDelay = 7190000)
+    public void getWXToken() {
+        String tokenUrl = "https://open.wecard.qq.com/cgi-bin/oauth2/token";
+        Map<String, String> tokenParams = new HashMap<>();
+
+        tokenParams.put("app_key", weixiaoConfig.getAppKey());
+        tokenParams.put("app_secret", weixiaoConfig.getAppSecret());
+        tokenParams.put("ocode", weixiaoConfig.getOcode());
+        tokenParams.put("grant_type", "client_credentials");
+        tokenParams.put("scope", "base");
+
+        try {
+            RestTemplate client = new RestTemplate();
+            ResponseEntity<String> tokenResponse = client.postForEntity(tokenUrl, tokenParams, String.class);
+            String body = tokenResponse.getBody();
+            log.info("微校code换token返回结果【{}】", body);
+
+            ObjectMapper mapper = new ObjectMapper();
+            Map<String, Object> jsonMap = mapper.readValue(body, new TypeReference<Map<String, Object>>() {
+            });
+            access_token = (String) jsonMap.get("access_token");
+        }catch (Exception e){
+            log.error("获取微校Token令牌失效======》》【{}】", e.getMessage());
+        }
+    }
+
+
+    /**
+     *  微校数据变更推送接口
+     * @param weixiaoPushDTO
+     * @return code  接收响应状态码,0为成功,非0时则认为接收方接受数据失败,将会进行重试
+     */
+    @PostMapping("/receive")
+    @ResponseBody
+    public ReturnValueUtil receive(@RequestBody WeixiaoPushDTO weixiaoPushDTO){
+        log.info("微校数据变更推送=======》》》》【{}】",weixiaoPushDTO.toString());
+
+        try {
+            String appKey = weixiaoPushDTO.getApp_key();
+            String schoolCode = weixiaoPushDTO.getSchool_code();
+            String event = weixiaoPushDTO.getEvent();
+            String rawData = weixiaoPushDTO.getRaw_data();
+
+            String cKey = appKey;
+            String cIv = weixiaoConfig.getAppSecret().substring(0, 16);
+            AesUtil aes = new AesUtil();
+            String userString = aes.Decrypt(rawData, cKey, cIv);
+
+            System.out.println(userString);
+            pushProjectService.pushProject(weixiaoPushDTO);
+            return ReturnValueUtil.ok();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return ReturnValueUtil.fail();
+    }
+
+
+}

+ 35 - 0
src/main/java/com/chuanghai/dto/WeixiaoPushDTO.java

@@ -0,0 +1,35 @@
+package com.chuanghai.dto;
+
+import lombok.Data;
+
+/**
+ * @Author: binguo
+ * @Date: 2022/12/29 星期四 16:03
+ * @Description: 用于接收微校推送的数据
+ * @Version: 1.0
+ */
+@Data
+public class WeixiaoPushDTO {
+    /**
+     * 应用appKey
+     */
+    private String app_key;
+    /**
+     * 学校主体代码
+     */
+    private String school_code;
+    /**
+     * 推送事件类型
+     *  addUser 新增用户信息事件
+     *  updateUser  修改用户信息事件
+     *  deleteUser  删除用户信息事件
+     *  addOrg  新增组织架构事件
+     *  updateOrg  修改组织架构事件
+     *  deleteOrg  删除组织架构事件
+     */
+    private String event;
+    /**
+     * 推送加密后数据
+     */
+    private String raw_data;
+}

+ 63 - 0
src/main/java/com/chuanghai/entity/Organization.java

@@ -0,0 +1,63 @@
+package com.chuanghai.entity;
+
+import java.util.Date;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class Organization implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 组织名称
+     */
+    private String name;
+
+    /**
+     * 父组织编号
+     */
+    private Integer parentId;
+
+    /**
+     * 组织类别
+     */
+    private String orgType;
+
+    /**
+     * 类别
+     */
+    private Integer type;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+
+    /**
+     * 省份
+     */
+    private String province;
+
+    /**
+     * 城市
+     */
+    private String city;
+
+    /**
+     * 地区
+     */
+    private String area;
+
+
+}

+ 51 - 0
src/main/java/com/chuanghai/entity/PushProject.java

@@ -0,0 +1,51 @@
+package com.chuanghai.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * @Author: binguo
+ * @Date: 2022/12/29 星期四 10:41
+ * @Description: com.chuanghai.entity
+ * @Version: 1.0
+ */
+@Data
+public class PushProject implements Serializable {
+
+    private static final long serialVersionUID = 3851799424004024204L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 推送地址
+     */
+    private String url;
+
+    /**
+     * 推送项目
+     */
+    private String project;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 状态 0(有效) 1(无效)
+     */
+    @Pattern(regexp = "[0-1]", message = "是否可用只能为0或者为1")
+    private Integer statu;
+
+
+
+}

+ 185 - 0
src/main/java/com/chuanghai/entity/User.java

@@ -0,0 +1,185 @@
+package com.chuanghai.entity;
+
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用户信息
+ *
+ * @Author: binguo
+ * @Date: 2022/12/28 星期三 10:48
+ * @Description: 用户实体信息
+ * @Version: 1.0
+ */
+@Data
+public class User implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键
+     */
+    private Integer id;
+
+    private String weixiaoStuId;
+
+    /**
+     * 电子卡号
+     */
+    private String cardNumber;
+
+    /**
+     * 姓名
+     */
+    private String name;
+
+    /**
+     * 性别
+     */
+    private Integer gender;
+
+    /**
+     * 头像
+     */
+    private String headImage;
+
+    /**
+     * 身份类型,1为其他,2为学生,3为教职工,4为校友
+     */
+    private Integer identityType;
+
+    /**
+     * 年级
+     */
+    private String grade;
+
+    /**
+     * 校区
+     */
+    private String campus;
+
+    /**
+     * 宿舍号
+     */
+    private String dormNumber;
+
+    /**
+     * 物理芯片号
+     */
+    private String physicalChipNumber;
+
+    /**
+     * 物理卡号
+     */
+    private String physicalCardNumber;
+
+    /**
+     * 民族
+     */
+    private String nation;
+
+    /**
+     * 生日
+     */
+    private String birthday;
+
+    /**
+     * 生源地
+     */
+    private String originPlace;
+
+    /**
+     * 毕业学校
+     */
+    private String graduatedSchool;
+
+    /**
+     * 家庭住址
+     */
+    private String address;
+
+    /**
+     * QQ
+     */
+    private String qq;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    private Integer cardType;
+
+    /**
+     * 身份职称
+     */
+    private String identityTitle;
+
+    /**
+     * 学院
+     */
+    private String college;
+
+    /**
+     * 专业
+     */
+    private String profession;
+
+    /**
+     * 班级
+     */
+    private String clazz;
+
+    /**
+     * 身份证号
+     */
+    private String idCard;
+
+    private Integer country;
+
+    /**
+     * 电话号码
+     */
+    private String telephone;
+
+    private Integer dataSource;
+
+    /**
+     * 有效期开始时间
+     */
+    private String startAt;
+
+    /**
+     * 有效期结束时间
+     */
+    private String expireAt;
+
+    /**
+     * 职务
+     */
+    private String jobTitle;
+
+    /**
+     * 编号
+     */
+    private String serialNumber;
+
+    /**
+     * 学段
+     */
+    private String schoolPeriod;
+
+    /**
+     * 入学年份
+     */
+    private String registerYear;
+
+    /**
+     * 组织结构
+     */
+    private String organization;
+
+
+}

+ 53 - 0
src/main/java/com/chuanghai/exception/BizCodeEnume.java

@@ -0,0 +1,53 @@
+package com.chuanghai.exception;
+
+/***
+ * 错误码和错误信息定义类
+ * 1. 错误码定义规则为5为数字
+ * 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常
+ * 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式
+ * 错误码列表:
+ *  10: 通用
+ *  11: 参数
+ *  12: 角色
+ *  13: 用户
+ *  14: 权限
+ *  15: 文件
+ *  16: 业务
+ *
+ */
+public enum BizCodeEnume {
+    UNKNOW_EXCEPTION(10000,"系统未知异常"),
+    METHOD_NOT_SUPPORT(10001, "请求方法不支持"),
+    REQUEST_HEADER_MISSING(10002, "缺少必要的请求头"),
+    TOKEN_INVALID(10003, "无效的token"),
+    TOKEN_IS_EMPTY(10004, "token为空"),
+    ADMIN_LOGIN_FAIL(10005, "管理员登录失败"),
+    PERMISSION_DENIED(10006, "权限不足"),
+    INVALID_PARAM(11001,"参数格式校验失败"),
+    BODY_IS_EMPTY(11002, "body为空"),
+    PARAMETER_ERROR(11003, "参数异常"),
+    REPEAT_SUBMIT(11004, "重复提交表单"),
+    ORDER_SUBMIT_ERROR(11005, "订单提交失败"),
+    MQ_CONSUME_EXCEPTION(11006,"消费者消费异常"),
+    DATA_IS_EXIST(16000, "数据已存在"),
+    DATA_NOT_EXIST(16000, "数据不存在"),
+    FILE_IS_NOT_EXIT(16006, "临时文件不存在"),
+    FILE_UPLOAD_ERROR(16007, "文件上传失败"),
+    FILE_IS_TOO_BIG(16008, "文件太大"),
+    FILE_IS_PUSH(16009, "微校信息推送异常");
+
+    private int code;
+    private String msg;
+    BizCodeEnume(int code, String msg){
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}

+ 65 - 0
src/main/java/com/chuanghai/exception/RRException.java

@@ -0,0 +1,65 @@
+package com.chuanghai.exception;
+
+/**
+ * 自定义异常
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class RRException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    private String msg;
+    private int code = 500;
+
+    public RRException(String msg) {
+        super(msg);
+        this.msg = msg;
+    }
+
+    public RRException(String msg, Throwable e) {
+        super(msg, e);
+        this.msg = msg;
+    }
+
+    public RRException(String msg, int code) {
+        super(msg);
+        this.msg = msg;
+        this.code = code;
+    }
+
+    public RRException(BizCodeEnume bizCodeEnume) {
+        super(bizCodeEnume.getMsg());
+        this.msg = bizCodeEnume.getMsg();
+        this.code = bizCodeEnume.getCode();
+    }
+
+    public RRException(BizCodeEnume bizCodeEnume, String msg) {
+        super(bizCodeEnume.getMsg());
+        this.msg = msg;
+        this.code = bizCodeEnume.getCode();
+    }
+
+    public RRException(String msg, int code, Throwable e) {
+        super(msg, e);
+        this.msg = msg;
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+
+}

+ 12 - 0
src/main/java/com/chuanghai/mapper/PushProjectMapper.java

@@ -0,0 +1,12 @@
+package com.chuanghai.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.chuanghai.entity.PushProject;
+import com.chuanghai.entity.User;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PushProjectMapper extends BaseMapper<PushProject> {
+
+}

+ 17 - 0
src/main/java/com/chuanghai/service/PushProjectService.java

@@ -0,0 +1,17 @@
+package com.chuanghai.service;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.chuanghai.dto.WeixiaoPushDTO;
+import com.chuanghai.entity.PushProject;
+import com.chuanghai.entity.User;
+
+public interface PushProjectService extends IService<PushProject> {
+
+    void pushProject(WeixiaoPushDTO weixiaoPushDTO);
+
+    void addPushProject(String url, String project);
+
+    void deletePushProject(Long id);
+}

+ 95 - 0
src/main/java/com/chuanghai/service/impl/PushProjectServiceImpl.java

@@ -0,0 +1,95 @@
+package com.chuanghai.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.chuanghai.dto.WeixiaoPushDTO;
+import com.chuanghai.entity.PushProject;
+import com.chuanghai.exception.BizCodeEnume;
+import com.chuanghai.exception.RRException;
+import com.chuanghai.mapper.PushProjectMapper;
+import com.chuanghai.service.PushProjectService;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class PushProjectServiceImpl extends ServiceImpl<PushProjectMapper, PushProject> implements PushProjectService {
+
+   @Override
+    public void pushProject(WeixiaoPushDTO weixiaoPushDTO) {
+
+        String app_key = weixiaoPushDTO.getApp_key();
+        String school_code = weixiaoPushDTO.getSchool_code();
+        String event = weixiaoPushDTO.getEvent();
+        String raw_data = weixiaoPushDTO.getRaw_data();
+
+        Map<String, String> tokenParams = new HashMap<>();
+        tokenParams.put("app_key", app_key);
+        tokenParams.put("school_code", school_code);
+        tokenParams.put("event", event);
+        tokenParams.put("raw_data", raw_data);
+
+        List<PushProject> pushProjectList = this.queryPushProject();
+        pushProjectList.forEach(pushProject -> {
+            try {
+                String tokenUrl = pushProject.getUrl();
+                RestTemplate client = new RestTemplate();
+                ResponseEntity<String> tokenResponse = client.postForEntity(tokenUrl, tokenParams, String.class);
+                String body = tokenResponse.getBody();
+                log.info("微校推送服务接口状态=======》》推送项目:【{}】》》结果集:【{}】",pushProject.getProject(),body);
+
+                ObjectMapper mapper = new ObjectMapper();
+                Map<String, Object> jsonMap = mapper.readValue(body, new TypeReference<Map<String, Object>>() {
+                });
+                String code = (String) jsonMap.get("code");
+
+            }catch (Exception e){
+                throw new RRException(BizCodeEnume.FILE_IS_PUSH);
+            }
+        });
+
+    }
+
+    /**
+     *  添加推送项目
+     * @param url
+     * @param project
+     */
+    @Override
+    public void addPushProject(String url, String project) {
+        LocalDateTime localDateTime = LocalDateTime.now();
+        PushProject pushProject = new PushProject();
+        pushProject.setCreateTime(localDateTime.now());
+        pushProject.setProject(project);
+        pushProject.setStatu(0);
+        pushProject.setUrl(url);
+        this.save(pushProject);
+    }
+
+    @Override
+    public void deletePushProject(Long id) {
+        PushProject pushProject = this.getById(id);
+        pushProject.setStatu(1);
+        this.updateById(pushProject);
+    }
+
+    /**
+     * 查询有效的项目
+     * @return
+     */
+    public List<PushProject> queryPushProject(){
+        QueryWrapper<PushProject> wrapper = new QueryWrapper<>();
+        wrapper.eq("statu","0");
+        return this.list(wrapper);
+    }
+}

+ 110 - 0
src/main/java/com/chuanghai/utils/AesUtil.java

@@ -0,0 +1,110 @@
+package com.chuanghai.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * @Author: binguo
+ * @Date: 2022/12/28 星期三 15:51
+ * @Description: com.chuanghai.utils
+ * @Version: 1.0
+ */
+public class AesUtil {
+
+    public static String Encrypt(String sSrc, String sKey, String sIv) throws Exception {
+
+        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+        int blockSize = cipher.getBlockSize();
+
+        byte[] dataBytes = sSrc.getBytes();
+        int plaintextLength = dataBytes.length;
+        if (plaintextLength % blockSize != 0) {
+            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
+        }
+
+        byte[] plaintext = new byte[plaintextLength];
+        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
+
+        SecretKeySpec keyspec = new SecretKeySpec(sKey.getBytes(), "AES");
+        IvParameterSpec ivspec = new IvParameterSpec(sIv.getBytes());
+
+        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
+        byte[] encrypted = cipher.doFinal(plaintext);
+
+        return byte2hex(encrypted).toLowerCase();
+    }
+
+    public static String Decrypt(String sSrc, String sKey, String sIv) throws Exception {
+
+        byte[] encrypted1      = hex2byte(sSrc);
+
+        Cipher cipher          = Cipher.getInstance("AES/CBC/NoPadding");
+        SecretKeySpec keyspec  = new SecretKeySpec(sKey.getBytes(), "AES");
+        IvParameterSpec ivspec = new IvParameterSpec(sIv.getBytes());
+
+        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
+
+        byte[] original = cipher.doFinal(encrypted1);
+        String originalString = new String(original);
+
+        return originalString;
+    }
+
+    public static byte[] hex2byte(String strhex) {
+        if (strhex == null) {
+            return null;
+        }
+        int l = strhex.length();
+        if (l % 2 == 1) {
+            return null;
+        }
+        byte[] b = new byte[l / 2];
+        for (int i = 0; i != l / 2; i++) {
+            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
+                    16);
+        }
+
+        return b;
+    }
+
+    public static String byte2hex(byte[] b) {
+        String hs = "";
+        String stmp = "";
+        for (int n = 0; n < b.length; n++) {
+            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
+            if (stmp.length() == 1) {
+                hs = hs + "0" + stmp;
+            } else {
+                hs = hs + stmp;
+            }
+        }
+
+        return hs.toUpperCase();
+    }
+
+
+    public static void main(String args[]) throws Exception {
+        // app_key
+        String cKey = "DB60250B489345ED";
+        // 需要加密的字串
+        String cSrc = "{\"code\":\"0\",\"error_msg\":\"密码错误\",\"weixiao_openid\":\"12345678\",\"student_num\":\"888888888888\",\"name\":\"洪丹丹测试\",\"sign\":\"5C6E844C23C8F0C15AF382081D0663DC\"}";
+        // app_secret 取前16位;
+        String cIv = "68ED5D4B98DD8817";
+        System.out.println(cSrc);
+        // 加密
+        long lStart = System.currentTimeMillis();
+        String enString = AesUtil.Encrypt(cSrc, cKey, cIv);
+        System.out.println("加密后的字串是:" + enString);
+
+        long lUseTime = System.currentTimeMillis() - lStart;
+        System.out.println("加密耗时:" + lUseTime + "毫秒");
+        // 解密
+        lStart = System.currentTimeMillis();
+        String DeString = AesUtil.Decrypt(enString, cKey, cIv);
+        System.out.println("解密后的字串是:" + DeString);
+        lUseTime = System.currentTimeMillis() - lStart;
+        System.out.println("解密耗时:" + lUseTime + "毫秒");
+
+    }
+}

+ 35 - 0
src/main/java/com/chuanghai/utils/BaseResult.java

@@ -0,0 +1,35 @@
+package com.chuanghai.utils;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: binguo
+ * @Description: 接口统一返回基类
+ * @Date: 2022/12/28 星期三 10:48
+ * @Version: V1.0
+ **/
+@Data
+public abstract class BaseResult<T> implements Serializable {
+
+    /**
+     * 接口调用结果标识
+     */
+    private boolean success = false;
+
+    /**
+     * 接口调用结果信息
+     */
+    private String message;
+
+    /**
+     * 接口调用业务码
+     */
+    private String code;
+
+    /**
+     * 接口调用返回数据
+     */
+    private T data;
+}

+ 52 - 0
src/main/java/com/chuanghai/utils/CommonResult.java

@@ -0,0 +1,52 @@
+package com.chuanghai.utils;
+
+import java.io.Serializable;
+
+/**
+ * @Author: binguo
+ * @Description: 接口统一返回
+ * @Date: 2022/12/28 星期三 10:48
+ * @Version: V1.0
+ **/
+public class CommonResult<T> extends BaseResult implements Serializable {
+
+    private static final long serialVersionUID = 3616484754899974346L;
+
+    public static CommonResult ok() {
+        return ok("1", "执行成功");
+    }
+
+
+    public static <T> CommonResult<T> success(String code, String msg) {
+        return baseCreate(code, msg, true);
+    }
+
+    public static <T> CommonResult<T> ok(String code, String msg) {
+        return baseCreate(code, msg, true);
+    }
+
+    public static CommonResult fail() {
+        return fail("-1", "执行失败");
+    }
+
+    public static CommonResult fail(String code, String msg) {
+        return baseCreate(code, msg, false);
+    }
+
+    private static <T> CommonResult<T> baseCreate(String code, String msg, boolean success) {
+        CommonResult result = new CommonResult();
+        result.setCode(code);
+        result.setSuccess(success);
+        result.setMessage(msg);
+        return result;
+    }
+
+    public CommonResult<T> setResult(T data) {
+        this.setData(data);
+        return this;
+    }
+
+    public T getData() {
+        return (T) super.getData();
+    }
+}

+ 59 - 0
src/main/java/com/chuanghai/utils/ReturnValueUtil.java

@@ -0,0 +1,59 @@
+package com.chuanghai.utils;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * @Author: bingo
+ * @Date: 2022/3/3 星期四 14:22
+ * @Description: 定义通用得方法返回值及状态码
+ * @version: 1.0
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+public class ReturnValueUtil {
+
+    /**
+     * 响应代码
+     */
+    private Integer code;
+    /**
+     * 响应消息
+     */
+    private String message;
+
+
+
+
+    /**
+     * 成功:用于微校接口反馈
+     *
+     * @param
+     * @return
+     */
+    public static ReturnValueUtil ok() {
+        ReturnValueUtil rb = new ReturnValueUtil();
+        rb.setCode(0);
+        rb.setMessage("OK");
+        return rb;
+    }
+
+    /**
+     * 成功:用于微校接口反馈
+     *
+     * @param
+     * @return
+     */
+    public static ReturnValueUtil fail() {
+        ReturnValueUtil rb = new ReturnValueUtil();
+        rb.setCode(1);
+        rb.setMessage("fail");
+        return rb;
+    }
+}
+

+ 40 - 0
src/main/java/com/chuanghai/vo/PushProjectVO.java

@@ -0,0 +1,40 @@
+package com.chuanghai.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import javax.validation.constraints.Pattern;
+import java.time.LocalDateTime;
+
+/**
+ * @Author: binguo
+ * @Date: 2022/12/29 星期四 17:11
+ * @Description: com.chuanghai.vo
+ * @Version: 1.0
+ */
+@Data
+public class PushProjectVO {
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 推送地址
+     */
+    private String url;
+
+    /**
+     * 推送项目
+     */
+    private String project;
+
+    /**
+     * 状态 0(有效) 1(无效)
+     */
+    @Pattern(regexp = "[0-1]", message = "是否可用只能为0或者为1")
+    private Integer statu;
+
+
+
+}

+ 38 - 0
src/main/resources/application.yml

@@ -0,0 +1,38 @@
+server:
+  port: 8099
+  servlet:
+    context-path: /wx
+
+spring:
+  application:
+    name: wx
+  main:
+    allow-circular-references: true
+  datasource:
+    username: root
+#    password: Chuanghai_2021.
+    password: root
+    url: jdbc:mysql://localhost:3306/wxpush?characterEncoding=UTF-8&useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+    driver-class-name: com.mysql.cj.jdbc.Driver
+
+
+
+mybatis-plus:
+  mapper-locations: classpath:/mapper/ihotel/*.xml
+  global-config:
+    db-config:
+      id-type: assign_id
+#  configuration:
+#  关闭sql打印
+#    log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+logging:
+  level:
+    com.chuanghai: debug
+
+
+
+# 微校配置-学生肖像
+weixiao:
+  app-key: DB60250B489345ED
+  app-secret: 68ED5D4B98DD8817C1558A8FCAF9D1BF
+  ocode: 1015730314

+ 18 - 0
src/main/resources/mapper.wx/OrganizationMapper.xml

@@ -0,0 +1,18 @@
+<?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.chuanghai.mapper.UserMapper">
+
+    <!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.chuanghai.entity.Organization" id="organizationMap">
+        <result property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="orgType" column="org_type"/>
+        <result property="type" column="type"/>
+        <result property="updatedAt" column="updated_at"/>
+        <result property="province" column="province"/>
+        <result property="city" column="city"/>
+        <result property="area" column="area"/>
+    </resultMap>
+
+</mapper>

+ 14 - 0
src/main/resources/mapper.wx/PushProjectMapper.xml

@@ -0,0 +1,14 @@
+<?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.chuanghai.mapper.PushProjectMapper">
+
+    <!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.chuanghai.entity.PushProject" id="PushProjectMap">
+        <result property="id" column="id"/>
+        <result property="url" column="url"/>
+        <result property="project" column="project"/>
+        <result property="createTime" column="create_time"/>
+        <result property="statu" column="statu"/>
+    </resultMap>
+
+</mapper>

+ 44 - 0
src/main/resources/mapper.wx/UserMapper.xml

@@ -0,0 +1,44 @@
+<?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.chuanghai.mapper.UserMapper">
+
+    <!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.chuanghai.entity.Organization" id="organizationMap">
+        <result property="id" column="id"/>
+        <result property="weixiaoStuId" column="weixiao_stu_id"/>
+        <result property="cardNumber" column="card_number"/>
+        <result property="name" column="name"/>
+        <result property="gender" column="gender"/>
+        <result property="headImage" column="head_image"/>
+        <result property="identityType" column="identity_type"/>
+        <result property="grade" column="grade"/>
+        <result property="campus" column="campus"/>
+        <result property="dormNumber" column="dorm_number"/>
+        <result property="physicalChipNumber" column="physical_chip_number"/>
+        <result property="physicalCardNumber" column="physical_card_number"/>
+        <result property="nation" column="nation"/>
+        <result property="birthday" column="birthday"/>
+        <result property="originPlace" column="origin_place"/>
+        <result property="graduatedSchool" column="graduated_school"/>
+        <result property="address" column="address"/>
+        <result property="qq" column="qq"/>
+        <result property="email" column="email"/>
+        <result property="cardType" column="cardType"/>
+        <result property="identityTitle" column="identity_title"/>
+        <result property="college" column="college"/>
+        <result property="profession" column="profession"/>
+        <result property="clazz" column="clazz"/>
+        <result property="idCard" column="id_card"/>
+        <result property="country" column="country"/>
+        <result property="telephone" column="telephone"/>
+        <result property="dataSource" column="data_source"/>
+        <result property="startAt" column="start_at"/>
+        <result property="expireAt" column="expire_at"/>
+        <result property="jobTitle" column="job_title"/>
+        <result property="serialNumber" column="serial_number"/>
+        <result property="schoolPeriod" column="schoolperiod"/>
+        <result property="registerYear" column="register_year"/>
+        <result property="organization" column="organization"/>
+    </resultMap>
+
+</mapper>

+ 28 - 0
src/main/resources/smart-doc.json

@@ -0,0 +1,28 @@
+{
+  "serverUrl": "http://192.168.161.34:8099/wx",
+  "isStrict": false,
+  "allInOne": true,
+  "outPath": "./src/main/resources/static/doc",
+  "coverOld": true,
+  "style": "zenburn",
+  "createDebugPage": false,
+  "projectName": "微校信息推送服务",
+  "inlineEnum": true,
+  "revisionLogs": [
+    {
+      "version": "0.0.1",
+      "revisionTime":"2022-07-27 09:50:00",
+      "status": "创建文档",
+      "author": "binguo",
+      "remarks": "初始化接口文档"
+    }
+  ],
+  "errorCodeDictionaries": [
+    {
+      "title": "业务异常代码",
+      "enumClassName": "com.chuanghai.exception.BizCodeEnume",
+      "codeField": "code",
+      "descField": "msg"
+    }
+  ]
+}

Разлика између датотеке није приказан због своје велике величине
+ 7 - 0
src/main/resources/static/doc/AllInOne.css


+ 282 - 0
src/main/resources/static/doc/index.adoc

@@ -0,0 +1,282 @@
+= 微校信息推送服务
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Version |  Update Time  | Status | Author |  Description
+|0.0.1|2022-07-27 09:50:00|创建文档|binguo|初始化接口文档
+|====================
+
+
+== 推送项目设置
+=== 查询推送项目
+*URL:* http://192.168.161.34:8099/wx/push/queryPushProject
+
+*Type:* GET
+
+
+*Content-Type:* application/x-www-form-urlencoded;charset=utf-8
+
+
+
+
+
+*Request-example:*
+----
+curl -X GET -i http://192.168.161.34:8099/wx/push/queryPushProject
+----
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|success|boolean|接口调用结果标识|-
+|message|string|接口调用结果信息|-
+|code|string|接口调用业务码|-
+|data|object|接口调用返回数据|-
+|====================
+
+*Response-example:*
+----
+{
+  "success": true,
+  "message": "success",
+  "code": "79076",
+  "data": {
+    "waring": "You may have used non-display generics."
+  }
+}
+----
+
+=== 添加推送项目
+*URL:* http://192.168.161.34:8099/wx/push/addPushProject
+
+*Type:* POST
+
+
+*Content-Type:* application/x-www-form-urlencoded;charset=utf-8
+
+
+
+*Query-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|url|string| 推送服务接口:post请求 json参数|false|-
+|project|string| 服务名称|false|-
+|====================
+
+
+*Request-example:*
+----
+curl -X POST -i http://192.168.161.34:8099/wx/push/addPushProject --data 'project=mv0yt3&url=www.xn---xn--9nz-d33pw339a.biz'
+----
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|success|boolean|接口调用结果标识|-
+|message|string|接口调用结果信息|-
+|code|string|接口调用业务码|-
+|data|object|接口调用返回数据|-
+|====================
+
+*Response-example:*
+----
+{
+  "success": true,
+  "message": "success",
+  "code": "79076",
+  "data": {
+    "waring": "You may have used non-display generics."
+  }
+}
+----
+
+=== 修改推送项目
+*URL:* http://192.168.161.34:8099/wx/push/updatePushProject
+
+*Type:* PUT
+
+
+*Content-Type:* application/json; charset=utf-8
+
+
+
+
+*Body-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|id|int64|主键|false|-
+|url|string|推送地址|false|-
+|project|string|推送项目|false|-
+|statu|int32|状态 0(有效) 1(无效)|false|-
+|====================
+
+*Request-example:*
+----
+curl -X PUT -H 'Content-Type: application/json; charset=utf-8' -i http://192.168.161.34:8099/wx/push/updatePushProject --data '{
+  "id": 657,
+  "url": "www.xn---xn--9nz-d33pw339a.biz",
+  "project": "eui823",
+  "statu": 965
+}'
+----
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|success|boolean|接口调用结果标识|-
+|message|string|接口调用结果信息|-
+|code|string|接口调用业务码|-
+|data|object|接口调用返回数据|-
+|====================
+
+*Response-example:*
+----
+{
+  "success": true,
+  "message": "success",
+  "code": "79076",
+  "data": {
+    "waring": "You may have used non-display generics."
+  }
+}
+----
+
+=== 删除推送项目
+*URL:* http://192.168.161.34:8099/wx/push/deletePushProject
+
+*Type:* DELETE
+
+
+*Content-Type:* application/x-www-form-urlencoded;charset=utf-8
+
+
+
+*Query-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|id|int64|No comments found.|false|-
+|====================
+
+
+*Request-example:*
+----
+curl -X DELETE -i http://192.168.161.34:8099/wx/push/deletePushProject?id=828
+----
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|success|boolean|接口调用结果标识|-
+|message|string|接口调用结果信息|-
+|code|string|接口调用业务码|-
+|data|object|接口调用返回数据|-
+|====================
+
+*Response-example:*
+----
+{
+  "success": true,
+  "message": "success",
+  "code": "79076",
+  "data": {
+    "waring": "You may have used non-display generics."
+  }
+}
+----
+
+== 微校推送服务
+=== 微校数据变更推送接口
+*URL:* http://192.168.161.34:8099/wx/wxc/receive
+
+*Type:* POST
+
+
+*Content-Type:* application/json; charset=utf-8
+
+
+
+
+*Body-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|app_key|string|应用appKey|false|-
+|school_code|string|学校主体代码|false|-
+|event|string|推送事件类型<br> addUser 新增用户信息事件<br> updateUser  修改用户信息事件<br> deleteUser  删除用户信息事件<br> addOrg  新增组织架构事件<br> updateOrg  修改组织架构事件<br> deleteOrg  删除组织架构事件|false|-
+|raw_data|string|推送加密后数据|false|-
+|====================
+
+*Request-example:*
+----
+curl -X POST -H 'Content-Type: application/json; charset=utf-8' -i http://192.168.161.34:8099/wx/wxc/receive --data '{
+  "app_key": "tdatrw",
+  "school_code": "79076",
+  "event": "l2li4v",
+  "raw_data": "2wg8sh"
+}'
+----
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|code|int32|响应代码|-
+|message|string|响应消息|-
+|====================
+
+*Response-example:*
+----
+{
+  "code": 473,
+  "message": "success"
+}
+----
+
+== 错误码列表
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Error code |Description
+|10000|系统未知异常
+|10001|请求方法不支持
+|10002|缺少必要的请求头
+|10003|无效的token
+|10004|token为空
+|10005|管理员登录失败
+|10006|权限不足
+|11001|参数格式校验失败
+|11002|body为空
+|11003|参数异常
+|11004|重复提交表单
+|11005|订单提交失败
+|11006|消费者消费异常
+|16000|数据已存在
+|16000|数据不存在
+|16006|临时文件不存在
+|16007|文件上传失败
+|16008|文件太大
+|16009|微校信息推送异常
+|====================
+

Разлика између датотеке није приказан због своје велике величине
+ 66 - 0
src/main/resources/static/doc/index.html


+ 138 - 0
src/main/resources/static/doc/search.js

@@ -0,0 +1,138 @@
+let api = [];
+api.push({
+    alias: 'PushProjectController',
+    order: '1',
+    link: '推送项目设置',
+    desc: '推送项目设置',
+    list: []
+})
+api[0].list.push({
+    order: '1',
+    desc: '查询推送项目',
+});
+api[0].list.push({
+    order: '2',
+    desc: '添加推送项目',
+});
+api[0].list.push({
+    order: '3',
+    desc: '修改推送项目',
+});
+api[0].list.push({
+    order: '4',
+    desc: '删除推送项目',
+});
+api.push({
+    alias: 'WxController',
+    order: '2',
+    link: '微校推送服务',
+    desc: '微校推送服务',
+    list: []
+})
+api[1].list.push({
+    order: '1',
+    desc: '微校数据变更推送接口',
+});
+api.push({
+    alias: 'error',
+    order: '3',
+    link: 'error_code_list',
+    desc: '错误码列表',
+    list: []
+})
+api.push({
+    alias: 'dict',
+    order: '4',
+    link: 'dict_list',
+    desc: '数据字典',
+    list: []
+})
+document.onkeydown = keyDownSearch;
+function keyDownSearch(e) {
+    const theEvent = e;
+    const code = theEvent.keyCode || theEvent.which || theEvent.charCode;
+    if (code == 13) {
+        const search = document.getElementById('search');
+        const searchValue = search.value;
+        let searchArr = [];
+        for (let i = 0; i < api.length; i++) {
+            let apiData = api[i];
+            const desc = apiData.desc;
+            if (desc.indexOf(searchValue) > -1) {
+                searchArr.push({
+                    order: apiData.order,
+                    desc: apiData.desc,
+                    link: apiData.link,
+                    list: apiData.list
+                });
+            } else {
+                let methodList = apiData.list || [];
+                let methodListTemp = [];
+                for (let j = 0; j < methodList.length; j++) {
+                    const methodData = methodList[j];
+                    const methodDesc = methodData.desc;
+                    if (methodDesc.indexOf(searchValue) > -1) {
+                        methodListTemp.push(methodData);
+                        break;
+                    }
+                }
+                if (methodListTemp.length > 0) {
+                    const data = {
+                        order: apiData.order,
+                        desc: apiData.desc,
+                        link: apiData.link,
+                        list: methodListTemp
+                    };
+                    searchArr.push(data);
+                }
+            }
+        }
+        let html;
+        if (searchValue == '') {
+            const liClass = "";
+            const display = "display: none";
+            html = buildAccordion(api,liClass,display);
+            document.getElementById('accordion').innerHTML = html;
+        } else {
+            const liClass = "open";
+            const display = "display: block";
+            html = buildAccordion(searchArr,liClass,display);
+            document.getElementById('accordion').innerHTML = html;
+        }
+        const Accordion = function (el, multiple) {
+            this.el = el || {};
+            this.multiple = multiple || false;
+            const links = this.el.find('.dd');
+            links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown);
+        };
+        Accordion.prototype.dropdown = function (e) {
+            const $el = e.data.el;
+            $this = $(this), $next = $this.next();
+            $next.slideToggle();
+            $this.parent().toggleClass('open');
+            if (!e.data.multiple) {
+                $el.find('.submenu').not($next).slideUp("20").parent().removeClass('open');
+            }
+        };
+        new Accordion($('#accordion'), false);
+    }
+}
+
+function buildAccordion(apiData, liClass, display) {
+    let html = "";
+    let doc;
+    if (apiData.length > 0) {
+        for (let j = 0; j < apiData.length; j++) {
+            html += '<li class="'+liClass+'">';
+            html += '<a class="dd" href="#_' + apiData[j].link + '">' + apiData[j].order + '.&nbsp;' + apiData[j].desc + '</a>';
+            html += '<ul class="sectlevel2" style="'+display+'">';
+            doc = apiData[j].list;
+            for (let m = 0; m < doc.length; m++) {
+                html += '<li><a href="#_' + apiData[j].order + '_' + doc[m].order + '_' + doc[m].desc + '">' + apiData[j].order + '.' + doc[m].order + '.&nbsp;' + doc[m].desc + '</a> </li>';
+            }
+            html += '</ul>';
+            html += '</li>';
+        }
+    }
+    return html;
+}

+ 13 - 0
src/test/java/com/chuanghai/WxpushApplicationTests.java

@@ -0,0 +1,13 @@
+package com.chuanghai;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class WxpushApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}