系统体验环境数据抽取创建

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
    • 介绍

本文主要介绍系统体验环境的数据抽取和复制。

需求有一个项目需要有用户体验或者是演示功能这些操作又不能在正式环境操作测试环境也不稳定用户体验不好。所以需要有新的一套系统供用户使用

但是这些数据不会长期保存。

这些用户也不需要登录

2. 逻辑设计

  • 新搭建一套系统

  • 修改登录设置

  • 访问系统还是需要token

  • 需要造一份数据供用户进来后观看

  • 限制入口必须是从官网进来的

  • 体验名额有限

  • 一个浏览器进来之后只能占用一个用户名额。

3. 数据操作

3.1 数据抽取

在创建好数据后将数据库备份所有数据需要有一个companyId作为这个这个用户创建的数据

新建一个库用于备数据比如创建数据的库是demo, 创建一个新的库是test-demo

备数据语句, 其他所有表的语句也是这样

CREATE TABLE test-demo.address_info  select * FROM   demo.address_info    where team_id = 368614817831877 and company_id = 368614817831878;

上边SQL运行完之后在test-demo中就会出现一个表里面只有这个用户创建的数据

3.2 将test-demo中所有的表数据转存结构和数据将SQL语句导出来。

结果就是这样的

/*
 Navicat Premium Data Transfer

 Source Server         : 演示环境
 Source Server Type    : MySQL
 Source Server Version : 80027
 Source Host           : 172.21.6.120:30306
 Source Schema         : test1

 Target Server Type    : MySQL
 Target Server Version : 80027
 File Encoding         : 65001

 Date: 14/01/2023 14:19:26
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for address_info
-- ----------------------------
DROP TABLE IF EXISTS `address_info`;
CREATE TABLE `address_info`  (
  `id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '收货地址主键',
  `dept_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '部门主键',
  `company_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '公司主键',
  `team_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '团队主键',
  `user_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户主键',
  `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '手机号',
  `postal_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '邮政编码',
  `is_default` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否默认地址 0否 1是',
  `province_id` int NOT NULL DEFAULT 0 COMMENT '省',
  `province_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '省名称',
  `city_id` int NOT NULL DEFAULT 0 COMMENT '市',
  `city_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '市名称',
  `area_id` int NOT NULL DEFAULT 0 COMMENT '区',
  `area_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '区名称',
  `area_address` varchar(160) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所在地区(省市区县乡镇拼接)',
  `address` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '详细地址(不含省市区县乡镇)',
  `create_by` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建人',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_by` bigint UNSIGNED NULL DEFAULT 0 COMMENT '修改人',
  `update_time` datetime NULL DEFAULT NULL COMMENT '修改时间',
  `is_deleted` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除(0:否 1:是)'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of address_info
-- ----------------------------
INSERT INTO `address_info` VALUES (368877194447429, 368614817831878, 368614817831878, 368614817831877, 368614454736709, '试用', '13811762869', '100000', 1, 110000, '北京市', 110100, '北京市', 110106, '丰台区', '北京市北京市丰台区', '丰台科技园', 368614454736709, '2022-12-28 10:25:11', 368614454736709, '2022-12-28 10:25:14', 0);

上边的SQL我们只需要插入语句所以要去除其他没有用的行这就需要写java代码去处理这个文件需要输出的文件自己提取创建好。因为最后剩下的语句没有库名称插入的时候方便我加上了库名称。


    /**
     * 读取SQL文件只保留inert into
     * @param fileName
     * @param fileName2
     * @throws IOException
     */
    public static void readTestSqlFileContent(String fileName, String fileName2, String database) throws IOException {
        // 1、获取到文件对象
        File file = new File(fileName);
        File outFile = new File(fileName2);

        // 2、判断文件是否存在
        if(!file.exists()) {
            return;
        } else if (!outFile.exists()) {
            // 输出文件不存在文件且创建失败
            if(!outFile.createNewFile()) {
                return;
            }
        }

        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));
        ) {
            String readStr;
            // 读一行写一行
            while ((readStr = reader.readLine()) != null) {

//
                if (!readStr.startsWith("INSERT INTO")){
                    continue;
                }

                // 加上数据库
                readStr = readStr.replaceAll("INSERT INTO ", "INSERT INTO "+ database);

                writer.write(readStr);
//                writer.write("\r\n");
                writer.newLine();
                // 输出流在close之前会自动执行flush也可以根据情况手动执行
//                writer.flush();
            }
        }


    }

处理完结果

INSERT INTO `demo`.`address_info` VALUES (368877194447429, 368614817831878, 368614817831878, 368614817831877, 368614454736709, '试用', '13811762869', '100000', 1, 110000, '北京市', 110100, '北京市', 110106, '丰台区', '北京市北京市丰台区', '丰台科技园', 368614454736709, '2022-12-28 10:25:11', 368614454736709, '2022-12-28 10:25:14', 0);

插入语句前边的库名一定要对否则就插入到别的库里面了注意这个 `demo`.`address_info`

以上就把数据抽取出来了

3.2 修改id及关联id

这里就是吧id变了只要不重复就行我这id是15位的我自己生成id的时候定义由3部分组成。前5位是用户10001, 第2部分是表个数11111第3部分是行数据10001这样第一个用户的第一条数据的id就是100011111110001然后把以前的id和这个新生成做替换。

  • 先循环文件找出没一行id的值就是“VALUES (” 后边的第一个数368877194447429。和新生成的100011111110001做对应这里是用map存储的key是368877194447429value是100011111110001。

  • map存储完之后再循环文件的没一行去替换里面的id值没一行都循环map去处理替换id值也可以替换其他的值。

  • 替换完之后再存储起来。

替换id代码

package com.example.demoes.test;

import org.springframework.util.StringUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileTest3 {

    public static void main(String[] args) throws IOException {

        /**
         1. 转SQL只有insert into
         2. 把2个库的SQL都存一起
         3. 清除user_info表uuid
         4. company_info_normal修改id

           暂时不用 replaceTestSqlFileContent("D:\\test\\test1.sql","D:\\test\\test12.sql");
            readFileContent("D:\\test\\22.txt","D:\\test\\11.txt");
            getNumFileContent("D:\\test\\11.txt","D:\\test\\33.txt");
        */
/*

        // 将原来导出的test.sql取出插入语句
        readTestSqlFileContent("D:\\test\\testdata.sql","D:\\test\\test3.sql", "`test`.");// `cnpc`.

        // 将原来导出的test-base.sql取出插入语句
        readTestSqlFileContent("D:\\test\\test1-base.sql","D:\\test\\test3-base.sql", "`test-base`.");// `cnpc-base`.

        // 合并成一个文件
        appendFileContent("D:\\test\\test3.sql","D:\\test\\testhe3.sql");
        appendFileContent("D:\\test\\test3-base.sql","D:\\test\\testhe3.sql");
*/

        // 处理数据
        int userIdprefix = 10005;
        Map<String, String> map = getIdMapTestSqlFileContent("D:\\test\\testhe3.sql", "D:\\test\\testId.sql", userIdprefix, 11111);
        for (int i = 0; i < 100; i++) {
//            replaceIdSqlFileContent("D:\\test\\testhe3.sql","D:\\test\\cnpche31.sql", map, i+7);
            replaceIdSqlFileContent("D:\\test\\testhe3.sql","D:\\test\\cnpche31-100.sql", map, i+5);

            userIdprefix++;
// 
            Set<String> keys = map.keySet();
            for (String key : keys) {
                String v = map.get(key);
                String substring = v.substring(5);
                v = userIdprefix+ substring;
                map.put(key, v);
            }
        }


    }

    /**
     * @Title: readFileContent
     * @Description: 按行读取文本文件的内容
     * @author: 读取文件并输出到另一个文件
     * @date: 2022/1/13 11:25
     */
    public static void replaceIdSqlFileContent(String fileName, String fileName2, Map<String,String> map, int i) throws IOException {
        // 1、获取到文件对象
        File file = new File(fileName);
        File outFile = new File(fileName2);

        // 2、判断文件是否存在
        if(!file.exists()) {
            return;
        } else if (!outFile.exists()) {
            // 输出文件不存在文件且创建失败
            if(!outFile.createNewFile()) {
                return;
            }
        }

        long phone= 13800000000L;

        String reCompanyName = "智采云测试公司" + i;
        String rePhone = ""+(phone+i);
        String reUserName = "'trial_" + i + "'";

        int a = 0;
        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             // 这里需要追加以file为模板创建100份输出到outfile
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile, true));
        ) {
            String readStr;
            StringBuilder read100Str = new StringBuilder();



            // 读一行写一行
            while ((readStr = reader.readLine()) != null) {

                if (readStr.equals("") || readStr.equals("######")){
                    continue;
                }

                a++;
                read100Str.append(readStr);
                read100Str.append("\r\n");
                if (a==100){
                    String s100str = read100Str.toString();
                    Iterator<String> iterator = map.keySet().iterator();

                    while (iterator.hasNext()){
                        String key = iterator.next();
                        s100str = s100str.replaceAll(key, map.get(key))
//                                .replaceAll("'trial_1'", reUserName)
//                                .replaceAll("集团有限公司", "测试公司" + i)
//                                .replaceAll("测试公司", reCompanyName)
//                                .replaceAll("13811761111", rePhone)
                        ;
                    }
                    read100Str = new StringBuilder();
                    s100str = s100str.replaceAll("'trial_1'", reUserName)
                            .replaceAll("智采云测试公司", reCompanyName)
                            .replaceAll("13811761111", rePhone);


                    writer.write(s100str);
//                    writer.newLine();
                    a=0;
                }
            }
            // 循环完不到100行的
            String slt100str = read100Str.toString();
            Iterator<String> iterator = map.keySet().iterator();

            while (iterator.hasNext()){
                String key = iterator.next();
                slt100str = slt100str.replaceAll(key, map.get(key))
                        .replaceAll(key, map.get(key))
//                        .replaceAll("'trial_1'", reUserName)
                        .replaceAll("集团有限公司", "测试公司" + i)
//                        .replaceAll("测试公司", reCompanyName)
//                        .replaceAll("13811761111", rePhone)
                ;
            }
            read100Str = new StringBuilder();
            slt100str = slt100str.replaceAll("'trial_1'", reUserName)
                    .replaceAll("测试公司", reCompanyName)
                    .replaceAll("13811761111", rePhone);

            writer.write(slt100str);
        }


    }

    /**
     * 读取SQL文件替换id 隔开
     * @param inFileName
     * @param outFileName
     * @throws IOException
     */
    public static Map<String,String> getIdMapTestSqlFileContent(String inFileName, String outFileName, int userIdPrefix, int mid ) throws IOException {
        // 1、获取到文件对象
        File file = new File(inFileName);
        File outFile = new File(outFileName);

        // 2、判断文件是否存在
        if(!file.exists()) {
            return null;
        } else if (!outFile.exists()) {
            // 输出文件不存在文件且创建失败
            if(!outFile.createNewFile()) {
                return null;
            }
        }

        String tableName = "";

        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));  // true,追加
        ) {
            Map<String,String> idMap = new HashMap<>();
            String readStr;

            int suffix = 10001;
            int row =0;
            // 读一行写一行
            while ((readStr = reader.readLine()) != null) {

//                if (readStr.equals("") || readStr.equals("######")){
//                    continue;
//                }

                row++;
                int start = readStr.indexOf("INSERT INTO `");
                int end = readStr.indexOf("` VALUES (");

                if (StringUtils.isEmpty(tableName)){
                    tableName = readStr.substring(13, end);
                }

                String tableName2 = readStr.substring(13, end);

                if (!tableName2.equals(tableName)){
//                    System.out.println(tableName + "===" + (row-1));
                    row=1;
                    tableName = tableName2;
                    mid++;
                }else {

                }


                String regEx  = "\\d{15}";
                Pattern compile = Pattern.compile(regEx);
                Matcher matcher = compile.matcher(readStr);

                String id = "";
                if (matcher.find()) {
                    id = matcher.group();
                }

                String selfId = ""+userIdPrefix + mid + suffix;
                writer.write(id + "=" + selfId);
                writer.write("\r\n");
//                writer.newLine();
                // 输出流在close之前会自动执行flush也可以根据情况手动执行
//                writer.flush();
                idMap.put(id, selfId);
                suffix++;
            }

            return idMap;
        }


    }

    /**
     * 读取SQL文件替换###### 隔开
     * @param inFileName
     * @param outFileName
     * @throws IOException
     */
    public static void replaceTestSqlFileContent(String inFileName, String outFileName) throws IOException {
        // 1、获取到文件对象
        File file = new File(inFileName);
        File outFile = new File(outFileName);

        // 2、判断文件是否存在
        if(!file.exists()) {
            return;
        } else if (!outFile.exists()) {
            // 输出文件不存在文件且创建失败
            if(!outFile.createNewFile()) {
                return;
            }
        }

        String tableName = "";

        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));
        ) {
            String readStr;
            // 读一行写一行
            while ((readStr = reader.readLine()) != null) {

                int start = readStr.indexOf("INSERT INTO `");
                int end = readStr.indexOf("` VALUES (");

                if (StringUtils.isEmpty(tableName)){
                    tableName = readStr.substring(start, end);
                }

                String tableName2 = readStr.substring(start, end);

                if (!tableName2.equals(tableName)){
                    tableName = tableName2;
                    writer.write("\r\n");
                    writer.write("######");
                    writer.write("\r\n");
                }

                writer.write(readStr);
                writer.newLine();
                // 输出流在close之前会自动执行flush也可以根据情况手动执行
//                writer.flush();
            }
        }


    }

    /**
     * 读取SQL文件只保留inert into
     * @param fileName
     * @param fileName2
     * @throws IOException
     */
    public static void readTestSqlFileContent(String fileName, String fileName2, String database) throws IOException {
        // 1、获取到文件对象
        File file = new File(fileName);
        File outFile = new File(fileName2);

        // 2、判断文件是否存在
        if(!file.exists()) {
            return;
        } else if (!outFile.exists()) {
            // 输出文件不存在文件且创建失败
            if(!outFile.createNewFile()) {
                return;
            }
        }

        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));
        ) {
            String readStr;
            // 读一行写一行
            while ((readStr = reader.readLine()) != null) {

//
                if (!readStr.startsWith("INSERT INTO")){
                    continue;
                }

                // 加上数据库
                readStr = readStr.replaceAll("INSERT INTO ", "INSERT INTO "+ database);

                writer.write(readStr);
//                writer.write("\r\n");
                writer.newLine();
                // 输出流在close之前会自动执行flush也可以根据情况手动执行
//                writer.flush();
            }
        }


    }

    /**
     * 2个文件内容合并
     * @param fileName 读取文件
     * @param fileName2 输出追加
     * @throws IOException
     */
    public static void appendFileContent(String fileName, String fileName2) throws IOException {
        // 1、获取到文件对象
        File file = new File(fileName);
        File outFile = new File(fileName2);

        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile, true));
        ) {
            String readStr;
            // 读一行写一行
            while ((readStr = reader.readLine()) != null) {

                writer.write(readStr);
//                writer.write("\r\n");
                writer.newLine();
                // 输出流在close之前会自动执行flush也可以根据情况手动执行
//                writer.flush();
            }
        }


    }

    public static void getNumFileContent(String fileName, String fileName2) throws IOException {
        // 1、获取到文件对象
        File file = new File(fileName);
        File outFile = new File(fileName2);

        // 2、判断文件是否存在
        if(!file.exists()) {
            return;
        } else if (!outFile.exists()) {
            // 输出文件不存在文件且创建失败
            if(!outFile.createNewFile()) {
                return;
            }
        }

        int a =1;
        // 因为读取的是文本所以使用字符流。如果是其他二进制文件可以使用字节流。在try中创建可以自动关闭
        try (BufferedReader reader = new BufferedReader(new FileReader(file));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));
        ) {
            String readStr;
            // 读一行写一行
            while ((readStr = reader.readLine()) != null && a<20) {
                a++;
//                int i = readStr.indexOf("VALUES (");

                String regEx  = "\\d{15}";
                Pattern compile = Pattern.compile(regEx);
                Matcher matcher = compile.matcher(readStr);


                if (matcher.find()) {
                    String group = matcher.group();
                    System.out.println(group);
                    System.out.println(group);
                }

                String s = matcher.replaceAll("");


                writer.write(s);
                writer.write("\r\n");
                writer.newLine();
                // 输出流在close之前会自动执行flush也可以根据情况手动执行
//                writer.flush();
            }
        }


    }



}

3.3 替换完成就可以导入SQL文件了。

4. 如果数据创建错了需要删除

清除表数据

-- show TABLES;

TRUNCATE address_info;

删除自己导入的数据这里id都是100开头的所以好删除

delete from address_info where id like '100%';

统计数据的条数

SELECT (select count(1) from address_info) +

(select count(1) from apply_address));

5. 登录限制代码

 public PasswordLoginSuccessVO demoLogin(HttpServletRequest request, TrialLoginDTO params, Integer businessType) {

        // 获取请求是从哪里来的
        String referer = params.getReferer();
        log.info("跳转路径--{}", referer);
        log.info("跳转路径判断--{}", referer.startsWith("https://cnpc-test-web.site/"));
        // 如果是直接输入的地址或者不是从智彩云访问的重定向到本网站的首页都抛出异常
        if (referer == null || !referer.startsWith("https://www.test.net")) {
            throw E.of(SsoExceptionEnum.PLATFORM_ERROR);

            // 系统升级使用
//            throw new E(SsoExceptionEnum.SYSTEM_UPDATE);
        }

        // 获取token
        // header中的token
        String tokenHeader = request.getHeader(SystemConstant.TOKEN);

        // header中的平台标识
        String platform = request.getHeader(SystemConstant.PLATFORM);

        // 平台参数是空或者不是WEB过来都抛异常
        if (StringUtils.isBlank(platform) || !PlatformEnum.WEB.name().equals(platform)) {
            throw E.of(SsoExceptionEnum.PLATFORM_ERROR);
        }

        // 1. token=null第一次访问生成新的token返回选择用户并更新使用uuid
        if (StringUtils.isBlank(tokenHeader)) {

            log.info("token为空选择一个新用户并返回");
            // 选择一个新用户并返回
            return selectNewUser();
        }

        // token检查
        String tokenCacheKey = MessageFormat.format(CommonConstant.TOKEN_CACHE_PREFIX, JWTUtils.parseCacheKey(tokenHeader));

        // 字符串格式的用户ID
        String userIdStr = stringRedisTemplate.opsForValue().get(tokenCacheKey);
        if (Strings.isBlank(userIdStr)) {

            log.info("token失效选择新用户");
            // 选择一个新用户并返回
            return selectNewUser();
        }


        // 2. token有值解析token用uuid去查用户
        String uuid = JWTUtils.parseUUID(tokenHeader);

        UserInfoPO userInfoByUuid = userService.getUserInfoByUuid(uuid);

        // 2.1 查到用户返回这个token和用户
        if (Objects.nonNull(userInfoByUuid)){

            log.info("token有值还是返回这个用户id={}", userInfoByUuid.getId());
            return PasswordLoginSuccessVO.of(userInfoByUuid.getId(), tokenHeader);
        }

        // 2.2 查不到用户就选择一个没有被使用的用户生成新的token返回并更新用户的uuid信息
        return selectNewUser();
    }
 /**
     * 选择一个新用户并返回
     */
    // 这里可能需要加锁
    private PasswordLoginSuccessVO selectNewUser() {
        // 选择用户
        UserInfoPO userInfoPO = selectUser();
        // 创建并保存TOKEN至缓存
        String token = getLoginToken(userInfoPO, PlatformEnum.WEB);
        String uuid = JWTUtils.parseUUID(token);

        updateUserUuid(userInfoPO.getId(), uuid);

        return PasswordLoginSuccessVO.of(userInfoPO.getId(), token);
    }

    /**
     * 选择用户
     * @return
     */
    private UserInfoPO selectUser() {

        // 2.3 用户全被使用完抛出异常--明天再来体验
        UserInfoPO userInfoPO = userService.queryUserRadom();

        // 查不到可用 用户 明天再来体验
        if (Objects.isNull(userInfoPO)){
            throw E.of(SsoExceptionEnum.TOMORROW_TRIAL);
        }

//        if (StringUtils.isNotEmpty(userInfoPO.getUuid())){
//            throw E.of(SsoExceptionEnum.TOMORROW_TRIAL);
//        }
        return userInfoPO;
    }

    // 更新用户被这个uuid使用
    private void updateUserUuid(Long id, String uuid) {
        UserInfoPO userInfoPO = new UserInfoPO();
        userInfoPO.setId(id);
        userInfoPO.setUuid(uuid);
        userService.updateUserUuid(userInfoPO);
    }

解析token代码

/**
     * 生成TOKEN (其实用不用JWT生成意义不大)
     */
    public static JWTTokenDTO createToken(Long userId, PlatformEnum platform) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            String jwtToken = JWT.create()
                    .withIssuer(ISSUER)
                    .withClaim(SystemConstant.USER_ID, userId)
                    .withClaim("since", new Date())
                    .sign(algorithm);
            String cacheKeyPrefix = UUID.randomUUID().toString().replace("-", "").toUpperCase();
            String cacheKey = cacheKeyPrefix + DigestUtils.sha1Hex(String.join(".", platform.toString(), jwtToken)).toUpperCase();
            return JWTTokenDTO.of(String.join(".", platform.toString(), cacheKeyPrefix, jwtToken), cacheKey);
        } catch (JWTCreationException e) {
            log.error("生成TOKEN失败 -> {}", e.getMessage(), e);
            throw new E("生成TOKEN失败");
        }
    }

    /**
     * 根据token解析缓存key 错误的token会抛出异常
     */
    public static String parseCacheKey(String token) {
        if (Strings.isBlank(token)) {
            throw new E("TOKEN不能为空");
        }
        String[] splits = token.split("\\.");
        if (splits.length != PART_COUNT) {
            throw new E("TOKEN格式错误");
        }
        return splits[1] + DigestUtils.sha1Hex(String.join(".", splits[0], splits[2], splits[3], splits[4])).toUpperCase();
    }

    public static String parseUUID(String token) {

        if (Strings.isBlank(token)) {
            throw new E("TOKEN不能为空");
        }
        String[] splits = token.split("\\.");
        if (splits.length != PART_COUNT) {
            throw new E("TOKEN格式错误");
        }
        return splits[1];
    }

    public static Long parseToken(String token) {
        if (Strings.isBlank(token)) {
            throw new E("TOKEN不能为空");
        }
        String[] splits = token.split("\\.");

        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = verifier.verify(token);
        Map<String, Claim> claims = jwt.getClaims();
        Long string = claims.get("since").asLong();
        System.out.println("djajd--" + string);
        return string;
    }

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6