zhentao 2 months ago
commit
7e8ce15255

+ 33 - 0
.gitignore

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

+ 153 - 0
pom.xml

@@ -0,0 +1,153 @@
+<?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>
+    <groupId>com.zhentao</groupId>
+    <artifactId>Xiaoe-Tech</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>Xiaoe-Tech</name>
+    <description>Xiaoe-Tech</description>
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <spring-boot.version>2.6.13</spring-boot.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.14</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.11</version> <!-- 确保版本号是正确的 -->
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate.validator</groupId>
+            <artifactId>hibernate-validator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <version>3.12.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.13.3</version> <!-- 可以根据需要选择合适的版本 -->
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.4</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Spring Security -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <!-- FastJSON -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>2.0.29</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+    </dependencies>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <configuration>
+                    <mainClass>com.zhentao.XiaoeTechApplication</mainClass>
+                    <skip>true</skip>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 15 - 0
src/main/java/com/zhentao/XiaoeTechApplication.java

@@ -0,0 +1,15 @@
+package com.zhentao;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.zhentao.mapper")
+public class XiaoeTechApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(XiaoeTechApplication.class, args);
+    }
+
+}

+ 43 - 0
src/main/java/com/zhentao/config/RedissonConfig.java

@@ -0,0 +1,43 @@
+package com.zhentao.config;
+
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+// 定义这是一个Spring配置类,用于配置Redisson相关的Bean
+@Configuration
+public class RedissonConfig {
+//     从配置文件(如application.properties或application.yml)中获取Redis服务器的主机地址
+    @Value("${spring.redis.host}")
+    private String host;
+    // 从配置文件中获取Redis服务器的端口号
+    @Value("${spring.redis.port}")
+    private int port;
+    // 从配置文件中获取要使用的Redis数据库索引
+    @Value("${spring.redis.database}")
+    private int database;
+    // 定义一个Bean,名称为getRedisson,返回一个RedissonClient实例,Spring会在需要RedissonClient的地方注入这个实例
+    @Bean
+    public RedissonClient getRedisson(){
+
+        // 创建一个Redisson的配置对象
+        Config config = new Config();
+
+        // 配置Redisson使用单机模式,并设置Redis服务器的地址
+        config.useSingleServer().setAddress("redis://"+host+":"+port)
+
+                // 设置要使用的Redis数据库索引
+                .setDatabase(database)
+                ;
+
+
+        // 设置锁的看门狗超时时间为2000毫秒。看门狗用于自动延长锁的持有时间,防止业务执行时间过长导致锁提前释放
+        config.setLockWatchdogTimeout(2000);
+
+        // 根据配置创建并返回RedissonClient实例
+        return Redisson.create(config);
+    }
+}

+ 26 - 0
src/main/java/com/zhentao/controller/UserController.java

@@ -0,0 +1,26 @@
+package com.zhentao.controller;
+
+import com.zhentao.dto.NoteDto;
+import com.zhentao.dto.Result;
+import com.zhentao.dto.UserDto;
+import com.zhentao.service.UserLoginService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+public class UserController {
+    @Autowired
+    public UserLoginService service;
+    @PostMapping("/login")
+    public Result Login(@RequestBody @Valid UserDto userDto){
+        return service.login(userDto);
+    }
+    @PostMapping("/code")
+    public Result Login(@RequestBody @Valid NoteDto noteDto){
+        return service.note(noteDto);
+    }
+}

+ 157 - 0
src/main/java/com/zhentao/domain/UserLogin.java

@@ -0,0 +1,157 @@
+package com.zhentao.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 用户
+ * @TableName user_login
+ */
+@TableName(value ="user_login")
+@Data
+public class UserLogin implements Serializable {
+    /**
+     * 用户ID
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 
+     */
+    private String openId;
+
+    /**
+     * 
+     */
+    private String unionId;
+
+    /**
+     * 
+     */
+    private String sessionPwd;
+
+    /**
+     * 用户昵称
+     */
+    private String nickName;
+
+    /**
+     * 头像图片
+     */
+    private String avatar;
+
+    /**
+     * 用户名称
+     */
+    private String userName;
+
+    /**
+     * 性别1男2女3未知
+     */
+    private Integer gender;
+
+    /**
+     * 个性签名
+     */
+    private String userIntro;
+
+    /**
+     * 手机号
+     */
+    private String userMobile;
+
+    /**
+     * 身份证号
+     */
+    private String idenNo;
+
+    /**
+     * 用户等级
+     */
+    private Long gradeId;
+
+    /**
+     * 等级描述
+     */
+    private String gradeDesc;
+
+    /**
+     * 是否付费会员0否1是
+     */
+    private Integer isMember;
+
+    /**
+     * 过期时间
+     */
+    private Date loseDate;
+
+    /**
+     * 1临时会员2副卡3正式会员
+     */
+    private Integer memberType;
+
+    /**
+     * 生日
+     */
+    private Date birthDay;
+
+    /**
+     * 月
+     */
+    private Integer birthMonth;
+
+    /**
+     * 日
+     */
+    private Integer days;
+
+    /**
+     * 总订单数
+     */
+    private Integer totalOrder;
+
+    /**
+     * 总消费金额
+     */
+    private BigDecimal totalConsume;
+
+    /**
+     * 标签列表
+     */
+    private String labelList;
+
+    /**
+     * 状态1正常0锁定
+     */
+    private Integer status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    private Date createdTime;
+
+    /**
+     * 更新人
+     */
+    private String updatedBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 13 - 0
src/main/java/com/zhentao/dto/NoteDto.java

@@ -0,0 +1,13 @@
+package com.zhentao.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+
+@Data
+public class NoteDto {
+    @NotBlank(message = "手机号不能为空")
+    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
+    private String phone;
+}

+ 30 - 0
src/main/java/com/zhentao/dto/Result.java

@@ -0,0 +1,30 @@
+package com.zhentao.dto;
+
+import lombok.Data;
+
+@Data
+public class Result {
+    public String msg;
+    public Integer code;
+    public Object object;
+    public static Result OK(String msg,Object object){
+        Result result = new Result();
+        result.setCode(200);
+        result.setMsg(msg);
+        result.setObject(object);
+        return result;
+    }
+    public static Result ERR(String msg,Object object){
+        Result result = new Result();
+        result.setCode(200);
+        result.setMsg(msg);
+        result.setObject(object);
+        return result;
+    }
+    public static Result error(Integer code,Object object){
+        Result result = new Result();
+        result.setCode(code);
+        result.setObject(object);
+        return result;
+    }
+}

+ 16 - 0
src/main/java/com/zhentao/dto/UserDto.java

@@ -0,0 +1,16 @@
+package com.zhentao.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+@Data
+public class UserDto {
+//    手机号
+    @NotBlank(message = "手机号不能为空")
+    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
+    private String phone;
+//    验证码
+    @NotBlank(message = "验证码不能为空")
+    private String code;
+}

+ 28 - 0
src/main/java/com/zhentao/enums/ApiServerException.java

@@ -0,0 +1,28 @@
+package com.zhentao.enums;
+
+public enum ApiServerException implements BaseExceptionEnum{
+    SUCCESS(1, "成功"),
+    NULL_USERNAME(1,"用户名错误"),
+    SUCCESS_login(1,"登录成功"),
+    TOKEN_ERR(101,"token错误,请重新登录"),
+    INTERRUPT(1,"操作中断"),
+    REGISTERED(1,"已注册"),
+    NOTE_ERROR(1,"验证码错误"),
+    NULL_PASSWORD(1,"密码错误");
+
+    ApiServerException(Integer code,String msg){
+        this.code=code;
+        this.msg=msg;
+    }
+    @Override
+    public Integer getCode() {
+        return code;
+    }
+
+    @Override
+    public String getMsg() {
+        return msg;
+    }
+    private Integer code;
+    private String msg;
+}

+ 6 - 0
src/main/java/com/zhentao/enums/BaseExceptionEnum.java

@@ -0,0 +1,6 @@
+package com.zhentao.enums;
+
+public interface BaseExceptionEnum {
+    Integer getCode();
+    String getMsg();
+}

+ 15 - 0
src/main/java/com/zhentao/exception/AsynException.java

@@ -0,0 +1,15 @@
+package com.zhentao.exception;
+
+import com.zhentao.enums.BaseExceptionEnum;
+import lombok.Data;
+
+@Data
+public class AsynException extends RuntimeException{
+    private Integer code;
+    private String msg;
+    public AsynException(BaseExceptionEnum baseExceptionEnum){
+        super(baseExceptionEnum.getMsg());
+        this.code = baseExceptionEnum.getCode();
+        this.msg = baseExceptionEnum.getMsg();
+    }
+}

+ 54 - 0
src/main/java/com/zhentao/exception/GlobalExceptionHandler.java

@@ -0,0 +1,54 @@
+package com.zhentao.exception;
+
+import com.zhentao.dto.Result;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.multipart.MultipartException;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Slf4j
+@RestControllerAdvice
+@ControllerAdvice
+public class GlobalExceptionHandler {
+    // 捕获所有异常的处理器,指定捕获的异常类型为Exception
+    @ExceptionHandler(value = Exception.class)
+// 将处理结果以JSON格式返回
+    @ResponseBody
+    public Result defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
+        // 记录异常信息到日志,这里只记录异常信息,不记录堆栈信息
+        log.error(e.getMessage());
+
+        // 判断异常类型并进行处理
+        if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {
+            // 如果是404异常,即没有找到处理器
+            return Result.error(404,"不存在页面请求");
+        }
+
+        if (e instanceof AsynException) {
+            // 如果是自定义的AsynException
+            AsynException customException = (AsynException) e;
+
+            // 返回自定义异常的错误码和错误信息
+            return Result.error(customException.getCode(), customException.getMessage());
+        } else if (e instanceof MultipartException) {
+            // 如果是文件上传异常 
+            log.error("系统异常{}", e); // 记录异常堆栈信息
+            return Result.error(1000, "上传文件异常");
+        } else if (e instanceof MethodArgumentNotValidException) {
+            // 如果是校验异常,例如使用@Valid注解校验参数失败
+            MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) e;
+
+            // 获取校验失败的第一个字段的错误信息
+            return Result.error(1002, methodArgumentNotValidException.getBindingResult().getFieldError().getDefaultMessage());
+        } else {
+            // 其他未处理的异常
+            log.error("系统异常{}", e); // 记录异常堆栈信息
+            return Result.error(1001, "系统参数异常");
+        }
+    }
+}

+ 34 - 0
src/main/java/com/zhentao/filter/TokenFilter.java

@@ -0,0 +1,34 @@
+package com.zhentao.filter;
+
+import com.alibaba.fastjson.JSON;
+import com.zhentao.dto.Result;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+@Component
+public class TokenFilter implements Filter {
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        String requestURI = request.getRequestURI();
+        System.err.println("发送的请求路径是"+requestURI);
+        if (requestURI.equals("/user/denglu")){
+            filterChain.doFilter(servletRequest,servletResponse);
+            return;
+        }
+        String token = request.getHeader("Authorization");
+        if (token.equals("123")){
+            Result result = Result.OK("你没有当前权限,请联系管理员", null);
+            String string = JSON.toJSONString(result);
+            response.setContentType("application/json;charset=utf-8");
+            PrintWriter writer = response.getWriter();
+            writer.write(string);
+        }
+    }
+}

+ 18 - 0
src/main/java/com/zhentao/mapper/UserLoginMapper.java

@@ -0,0 +1,18 @@
+package com.zhentao.mapper;
+
+import com.zhentao.domain.UserLogin;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author 86183
+* @description 针对表【user_login(用户)】的数据库操作Mapper
+* @createDate 2025-05-04 21:01:51
+* @Entity com.zhentao.domain.UserLogin
+*/
+public interface UserLoginMapper extends BaseMapper<UserLogin> {
+
+}
+
+
+
+

+ 18 - 0
src/main/java/com/zhentao/service/UserLoginService.java

@@ -0,0 +1,18 @@
+package com.zhentao.service;
+
+import com.zhentao.domain.UserLogin;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhentao.dto.NoteDto;
+import com.zhentao.dto.Result;
+import com.zhentao.dto.UserDto;
+
+/**
+* @author 86183
+* @description 针对表【user_login(用户)】的数据库操作Service
+* @createDate 2025-05-04 21:01:51
+*/
+public interface UserLoginService extends IService<UserLogin> {
+    Result login(UserDto userDto);
+    //    短信
+    Result note(NoteDto noteDto);
+}

+ 127 - 0
src/main/java/com/zhentao/service/impl/UserLoginServiceImpl.java

@@ -0,0 +1,127 @@
+package com.zhentao.service.impl;
+
+import cn.hutool.core.util.IdUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sun.deploy.net.HttpResponse;
+import com.zhentao.domain.UserLogin;
+import com.zhentao.dto.NoteDto;
+import com.zhentao.dto.Result;
+import com.zhentao.dto.UserDto;
+import com.zhentao.enums.ApiServerException;
+import com.zhentao.exception.AsynException;
+import com.zhentao.service.UserLoginService;
+import com.zhentao.mapper.UserLoginMapper;
+import com.zhentao.tool.HttpUtils;
+import com.zhentao.tool.TokenUtils;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+* @author 86183
+* @description 针对表【user_login(用户)】的数据库操作Service实现
+* @createDate 2025-05-04 21:01:51
+*/
+@Service
+public class UserLoginServiceImpl extends ServiceImpl<UserLoginMapper, UserLogin>
+    implements UserLoginService{
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+    @Autowired
+    private RedissonClient redissonClient;
+    @Override
+    public Result login(UserDto userDto) {
+        RLock lock = redissonClient.getLock(userDto.getPhone());
+        try {
+            boolean b = lock.tryLock(10, 20, TimeUnit.SECONDS);
+            if (b){
+                String s = stringRedisTemplate.opsForValue().get(userDto.getPhone());
+//                验证码比较
+                if (s.equals(userDto.getCode())){
+                    throw new AsynException(ApiServerException.NOTE_ERROR);
+                }
+                try{
+                    QueryWrapper<UserLogin> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("user_mobile",userDto.getPhone());
+                    UserLogin one = this.getOne(queryWrapper);
+                    String jwtToken = TokenUtils.createJwtToken(one.getId() + "");
+                    return Result.OK("登录成功",jwtToken);
+                }catch (NullPointerException e){
+                    long l = IdUtil.getSnowflake(1, 1).nextId();
+                    UserLogin userLogin = new UserLogin();
+                    userLogin.setId(l);
+                    userLogin.setUserMobile(userDto.getPhone());
+                    userLogin.setCreatedTime(new Date());
+
+                    this.save(userLogin);
+                    String jwtToken = TokenUtils.createJwtToken(l + "");
+                    return Result.OK("登录成功",jwtToken);
+                }
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new AsynException(ApiServerException.INTERRUPT);
+        }finally {
+            lock.unlock();
+        }
+        return null;
+    }
+
+
+    @Override
+    public Result note(NoteDto noteDto) {
+        int randomSixDigit = 100000 + (int) (Math.random() * 900000); // 生成六位随机数
+        System.out.println("验证码:"+randomSixDigit);
+        System.err.println("手机号:"+noteDto.getPhone());
+        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
+        stringStringValueOperations.set(noteDto.getPhone(),randomSixDigit+"");
+
+        String host = "https://gyytz.market.alicloudapi.com";
+        String path = "/sms/smsSend";
+        String method = "POST";
+        String appcode = "03a7c868bfcb4de291d6d609a6b625d3";
+        Map<String, String> headers = new HashMap<String, String>();
+        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
+        headers.put("Authorization", "APPCODE " + appcode);
+        Map<String, String> querys = new HashMap<String, String>();
+        querys.put("mobile", noteDto.getPhone());
+        querys.put("param", "**code**:"+randomSixDigit+",**minute**:5");
+
+//smsSignId(短信前缀)和templateId(短信模板),可登录国阳云控制台自助申请。参考文档:http://help.guoyangyun.com/Problem/Qm.html
+
+        querys.put("smsSignId", "2e65b1bb3d054466b82f0c9d125465e2");
+        querys.put("templateId", "908e94ccf08b4476ba6c876d13f084ad");
+        Map<String, String> bodys = new HashMap<String, String>();
+
+
+        try {
+            /**
+             * 重要提示如下:
+             * HttpUtils请从\r\n\t    \t* https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java\r\n\t    \t* 下载
+             *
+             * 相应的依赖请参照
+             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
+             */
+            HttpResponse response = (HttpResponse) HttpUtils.doPost(host, path, method, headers, querys, bodys);
+            System.out.println(response.toString());
+            //获取response的body
+            //System.out.println(EntityUtils.toString(response.getEntity()));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Result.OK("发送成功",null);
+    }
+}
+
+
+
+

+ 311 - 0
src/main/java/com/zhentao/tool/HttpUtils.java

@@ -0,0 +1,311 @@
+package com.zhentao.tool;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class HttpUtils {
+
+	/**
+	 * get
+	 *
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doGet(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpGet request = new HttpGet(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        return httpClient.execute(request);
+    }
+
+	/**
+	 * post form
+	 *
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @param bodys
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doPost(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys,
+			Map<String, String> bodys)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpPost request = new HttpPost(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (bodys != null) {
+            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
+
+            for (String key : bodys.keySet()) {
+                nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
+            }
+            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
+            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
+            request.setEntity(formEntity);
+        }
+
+        return httpClient.execute(request);
+    }
+
+	/**
+	 * Post String
+	 *
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @param body
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doPost(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys,
+			String body)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpPost request = new HttpPost(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (StringUtils.isNotBlank(body)) {
+        	request.setEntity(new StringEntity(body, "utf-8"));
+        }
+
+        return httpClient.execute(request);
+    }
+
+	/**
+	 * Post stream
+	 *
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @param body
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doPost(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys,
+			byte[] body)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpPost request = new HttpPost(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (body != null) {
+        	request.setEntity(new ByteArrayEntity(body));
+        }
+
+        return httpClient.execute(request);
+    }
+
+	/**
+	 * Put String
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @param body
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doPut(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys,
+			String body)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpPut request = new HttpPut(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (StringUtils.isNotBlank(body)) {
+        	request.setEntity(new StringEntity(body, "utf-8"));
+        }
+
+        return httpClient.execute(request);
+    }
+
+	/**
+	 * Put stream
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @param body
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doPut(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys,
+			byte[] body)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpPut request = new HttpPut(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (body != null) {
+        	request.setEntity(new ByteArrayEntity(body));
+        }
+
+        return httpClient.execute(request);
+    }
+
+	/**
+	 * Delete
+	 *
+	 * @param host
+	 * @param path
+	 * @param method
+	 * @param headers
+	 * @param querys
+	 * @return
+	 * @throws Exception
+	 */
+	public static HttpResponse doDelete(String host, String path, String method,
+			Map<String, String> headers,
+			Map<String, String> querys)
+            throws Exception {
+    	HttpClient httpClient = wrapClient(host);
+
+    	HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+        	request.addHeader(e.getKey(), e.getValue());
+        }
+
+        return httpClient.execute(request);
+    }
+
+	private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
+    	StringBuilder sbUrl = new StringBuilder();
+    	sbUrl.append(host);
+    	if (!StringUtils.isBlank(path)) {
+    		sbUrl.append(path);
+        }
+    	if (null != querys) {
+    		StringBuilder sbQuery = new StringBuilder();
+        	for (Map.Entry<String, String> query : querys.entrySet()) {
+        		if (0 < sbQuery.length()) {
+        			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(), "utf-8"));
+        			}
+                }
+        	}
+        	if (0 < sbQuery.length()) {
+        		sbUrl.append("?").append(sbQuery);
+        	}
+        }
+
+    	return sbUrl.toString();
+    }
+
+	private static HttpClient wrapClient(String host) {
+		HttpClient httpClient = new DefaultHttpClient();
+		if (host.startsWith("https://")) {
+			sslClient(httpClient);
+		}
+
+		return httpClient;
+	}
+
+	private static void sslClient(HttpClient httpClient) {
+        try {
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            X509TrustManager tm = new X509TrustManager() {
+                public X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+                public void checkClientTrusted(X509Certificate[] xcs, String str) {
+
+                }
+                public void checkServerTrusted(X509Certificate[] xcs, String str) {
+
+                }
+            };
+            ctx.init(null, new TrustManager[] { tm }, null);
+            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
+            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+            ClientConnectionManager ccm = httpClient.getConnectionManager();
+            SchemeRegistry registry = ccm.getSchemeRegistry();
+            registry.register(new Scheme("https", 443, ssf));
+        } catch (KeyManagementException ex) {
+            throw new RuntimeException(ex);
+        } catch (NoSuchAlgorithmException ex) {
+        	throw new RuntimeException(ex);
+        }
+    }
+}

+ 113 - 0
src/main/java/com/zhentao/tool/TokenUtils.java

@@ -0,0 +1,113 @@
+package com.zhentao.tool;
+
+import com.zhentao.enums.ApiServerException;
+import com.zhentao.exception.AsynException;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.bind.DatatypeConverter;
+import java.security.Key;
+import java.util.Date;
+
+/**
+ * 生成Token工具类
+ */
+public class TokenUtils {
+
+    /**
+     * 签名秘钥
+     */
+    public static final String SECRET = "cjyfutu1688";
+
+    /**
+     * 生成token
+     * @param id 一般传入userName
+     * @return
+     */
+    public static String createJwtToken(String id){
+        String issuer = "www.futureading.com";
+        String subject = "65532781@qq.com";
+        long ttlMillis = System.currentTimeMillis();
+        return createJwtToken(id, issuer, subject, ttlMillis);
+    }
+
+    /**
+     * 生成Token
+     *
+     * @param id
+     *            编号
+     * @param issuer
+     *            该JWT的签发者,是否使用是可选的
+     * @param subject
+     *            该JWT所面向的用户,是否使用是可选的;
+     * @param ttlMillis
+     *            签发时间
+     * @return token String
+     */
+    public static String createJwtToken(String id, String issuer, String subject, long ttlMillis) {
+
+        // 签名算法 ,将对token进行签名
+        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+
+        // 生成签发时间
+        long nowMillis = System.currentTimeMillis();
+        Date now = new Date(nowMillis);
+
+        // 通过秘钥签名JWT
+        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
+        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
+
+        // Let's set the JWT Claims
+        JwtBuilder builder = Jwts.builder().setId(id)
+                .setIssuedAt(now)
+                .setSubject(subject)
+                .setIssuer(issuer)
+                .signWith(signatureAlgorithm, signingKey);
+
+        // if it has been specified, let's add the expiration
+        if (ttlMillis >= 0) {
+            long expMillis = nowMillis + ttlMillis;
+            Date exp = new Date(expMillis);
+            builder.setExpiration(exp);
+        }
+
+        // Builds the JWT and serializes it to a compact, URL-safe string
+        return builder.compact();
+
+    }
+
+    // Sample method to validate and read the JWT
+    public static Claims parseJWT(String jwt) {
+        // This line will throw an exception if it is not a signed JWS (as expected)
+        Claims claims = Jwts.parser()
+                .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
+                .parseClaimsJws(jwt).getBody();
+        return claims;
+    }
+
+    public static Long getUserId(String token){
+        Claims claims = null;
+        try {
+            claims = TokenUtils.parseJWT(token);
+        } catch (Exception e) {
+            throw new AsynException(ApiServerException.TOKEN_ERR);
+        }
+
+        if(null==claims) {
+            throw new AsynException(ApiServerException.TOKEN_ERR);
+        }
+        String id = claims.getId();
+        Long userId=Long.valueOf(id);
+
+        return userId;
+
+
+    }
+
+    public static void main(String[] args) {
+        System.out.println(TokenUtils.createJwtToken("admin"));
+    }
+}

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

@@ -0,0 +1,13 @@
+server:
+  port: 9500
+spring:
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://47.110.46.22:3306/xiaoetong?useSSL=false&serverTimezone=UTC
+    username: root
+    password: Fengjaijia0610
+  redis:
+    host: 47.110.46.22
+    port: 6379
+    database: 0
+    password: Fengjiajia0610

+ 48 - 0
src/main/resources/mapper/UserLoginMapper.xml

@@ -0,0 +1,48 @@
+<?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.zhentao.mapper.UserLoginMapper">
+
+    <resultMap id="BaseResultMap" type="com.zhentao.domain.UserLogin">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="openId" column="open_id" jdbcType="VARCHAR"/>
+            <result property="unionId" column="union_id" jdbcType="VARCHAR"/>
+            <result property="sessionPwd" column="session_pwd" jdbcType="VARCHAR"/>
+            <result property="nickName" column="nick_name" jdbcType="VARCHAR"/>
+            <result property="avatar" column="avatar" jdbcType="VARCHAR"/>
+            <result property="userName" column="user_name" jdbcType="VARCHAR"/>
+            <result property="gender" column="gender" jdbcType="INTEGER"/>
+            <result property="userIntro" column="user_intro" jdbcType="VARCHAR"/>
+            <result property="userMobile" column="user_mobile" jdbcType="VARCHAR"/>
+            <result property="idenNo" column="iden_no" jdbcType="VARCHAR"/>
+            <result property="gradeId" column="grade_id" jdbcType="BIGINT"/>
+            <result property="gradeDesc" column="grade_desc" jdbcType="VARCHAR"/>
+            <result property="isMember" column="is_member" jdbcType="INTEGER"/>
+            <result property="loseDate" column="lose_date" jdbcType="TIMESTAMP"/>
+            <result property="memberType" column="member_type" jdbcType="INTEGER"/>
+            <result property="birthDay" column="birth_day" jdbcType="DATE"/>
+            <result property="birthMonth" column="birth_month" jdbcType="INTEGER"/>
+            <result property="days" column="days" jdbcType="INTEGER"/>
+            <result property="totalOrder" column="total_order" jdbcType="INTEGER"/>
+            <result property="totalConsume" column="total_consume" jdbcType="DECIMAL"/>
+            <result property="labelList" column="label_list" jdbcType="VARCHAR"/>
+            <result property="status" column="status" jdbcType="INTEGER"/>
+            <result property="remark" column="remark" jdbcType="VARCHAR"/>
+            <result property="createdTime" column="created_time" jdbcType="TIMESTAMP"/>
+            <result property="updatedBy" column="updated_by" jdbcType="VARCHAR"/>
+            <result property="updatedTime" column="updated_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,open_id,union_id,
+        session_pwd,nick_name,avatar,
+        user_name,gender,user_intro,
+        user_mobile,iden_no,grade_id,
+        grade_desc,is_member,lose_date,
+        member_type,birth_day,birth_month,
+        days,total_order,total_consume,
+        label_list,status,remark,
+        created_time,updated_by,updated_time
+    </sql>
+</mapper>

+ 13 - 0
src/test/java/com/example/XiaoeTechApplicationTests.java

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