Pārlūkot izejas kodu

新增app-api模块以及tg用户登录逻辑

xudm 2 mēneši atpakaļ
vecāks
revīzija
0a91c88089
45 mainītis faili ar 4117 papildinājumiem un 3 dzēšanām
  1. 152 0
      continew-appapi/pom.xml
  2. 23 0
      continew-appapi/src/main/java/top/continew/admin/ContinewAppApiApplication.java
  3. 38 0
      continew-appapi/src/main/java/top/continew/admin/config/satoken/LoginPasswordProperties.java
  4. 62 0
      continew-appapi/src/main/java/top/continew/admin/config/satoken/SaExtensionInterceptor.java
  5. 89 0
      continew-appapi/src/main/java/top/continew/admin/config/satoken/SaTokenConfiguration.java
  6. 45 0
      continew-appapi/src/main/java/top/continew/admin/config/satoken/SaTokenPermissionImpl.java
  7. 43 0
      continew-appapi/src/main/java/top/continew/admin/controller/LoginController.java
  8. 318 0
      continew-appapi/src/main/resources/config/application-dev.yml
  9. 290 0
      continew-appapi/src/main/resources/config/application.yml
  10. 26 0
      continew-appapi/src/main/resources/db/changelog/db.changelog-master.yaml
  11. 2 0
      continew-appapi/src/main/resources/db/changelog/mysql/main_column.sql
  12. 190 0
      continew-appapi/src/main/resources/db/changelog/mysql/main_data.sql
  13. 296 0
      continew-appapi/src/main/resources/db/changelog/mysql/main_table.sql
  14. 50 0
      continew-appapi/src/main/resources/db/changelog/mysql/plugin/plugin_generator.sql
  15. 37 0
      continew-appapi/src/main/resources/db/changelog/mysql/plugin/plugin_open.sql
  16. 21 0
      continew-appapi/src/main/resources/db/changelog/mysql/plugin/plugin_schedule.sql
  17. 2 0
      continew-appapi/src/main/resources/db/changelog/postgresql/main_column.sql
  18. 189 0
      continew-appapi/src/main/resources/db/changelog/postgresql/main_data.sql
  19. 492 0
      continew-appapi/src/main/resources/db/changelog/postgresql/main_table.sql
  20. 78 0
      continew-appapi/src/main/resources/db/changelog/postgresql/plugin/plugin_generator.sql
  21. 49 0
      continew-appapi/src/main/resources/db/changelog/postgresql/plugin/plugin_open.sql
  22. 21 0
      continew-appapi/src/main/resources/db/changelog/postgresql/plugin/plugin_schedule.sql
  23. 88 0
      continew-appapi/src/main/resources/logback-spring.xml
  24. 13 0
      continew-appapi/src/test/java/top/continew/admin/ContinewAppapiApplicationTests.java
  25. 33 0
      continew-module-coin-core/pom.xml
  26. 16 0
      continew-module-coin-core/src/main/java/top/continew/admin/user/mapper/TgUserMapper.java
  27. 258 0
      continew-module-coin-core/src/main/java/top/continew/admin/user/model/entity/TgUser.java
  28. 39 0
      continew-module-coin-core/src/main/java/top/continew/admin/user/model/req/AppLoginReq.java
  29. 12 0
      continew-module-coin-core/src/main/java/top/continew/admin/user/model/resp/AppLoginResp.java
  30. 27 0
      continew-module-coin-core/src/main/java/top/continew/admin/user/service/ITgUserService.java
  31. 102 0
      continew-module-coin-core/src/main/java/top/continew/admin/user/service/Impl/TgUserServiceImpl.java
  32. 27 0
      continew-module-coin-core/src/main/java/top/continew/admin/utils/InviteCodeGenerator.java
  33. 185 0
      continew-module-coin-core/src/main/java/top/continew/admin/utils/MyGenerator.java
  34. 51 0
      continew-module-coin-core/src/main/resources/mapper/TgUserMapper.xml
  35. 16 0
      continew-module-system/src/main/java/top/continew/admin/business/mapper/TgUserMapper.java
  36. 264 0
      continew-module-system/src/main/java/top/continew/admin/business/model/entity/TgUser.java
  37. 29 0
      continew-module-system/src/main/java/top/continew/admin/business/model/req/TgUserReq.java
  38. 234 0
      continew-module-system/src/main/java/top/continew/admin/business/model/resp/TgUserResp.java
  39. 27 0
      continew-module-system/src/main/java/top/continew/admin/business/service/ITgUserService.java
  40. 86 0
      continew-module-system/src/main/java/top/continew/admin/business/service/Impl/TgUserServiceImpl.java
  41. 50 0
      continew-module-system/src/main/resources/mapper/TgUserMapper.xml
  42. 25 0
      continew-webapi/src/main/java/top/continew/admin/controller/business/TgUserController.java
  43. 1 1
      continew-webapi/src/main/resources/config/application-dev.yml
  44. 1 1
      continew-webapi/src/main/resources/config/application.yml
  45. 20 1
      pom.xml

+ 152 - 0
continew-appapi/pom.xml

@@ -0,0 +1,152 @@
+<?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>top.continew</groupId>
+        <artifactId>continew-admin</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <artifactId>continew-appapi</artifactId>
+    <version>3.4.0</version>
+    <name>continew-appapi</name>
+    <description>gold-coin的app接口</description>
+    <properties>
+        <!-- ### 打包配置相关 ### -->
+        <!-- 启动类 -->
+        <main-class>top.continew.admin.ContinewAppApiApplication</main-class>
+        <!-- 程序 jar 输出目录 -->
+        <bin-path>bin/</bin-path>
+        <!-- 配置文件输出目录 -->
+        <config-path>config/</config-path>
+        <!-- 依赖 jar 输出目录 -->
+        <lib-path>lib/</lib-path>
+    </properties>
+    <dependencies>
+        <!-- ContiNew Starter 日志模块 - 拦截器版(Spring Boot Actuator HttpTrace 增强版) -->
+        <dependency>
+            <groupId>top.continew</groupId>
+            <artifactId>continew-starter-log-interceptor</artifactId>
+        </dependency>
+
+        <!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
+        <dependency>
+            <groupId>top.continew</groupId>
+            <artifactId>continew-module-coin-core</artifactId>
+        </dependency>
+
+        <!-- 任务调度插件(后续会改造为独立插件) -->
+        <dependency>
+            <groupId>top.continew</groupId>
+            <artifactId>continew-plugin-schedule</artifactId>
+        </dependency>
+
+        <!-- 能力开放插件(后续会改造为独立插件) -->
+        <dependency>
+            <groupId>top.continew</groupId>
+            <artifactId>continew-plugin-open</artifactId>
+        </dependency>
+
+        <!-- 代码生成器插件(后续会改造为独立插件) -->
+        <dependency>
+            <groupId>top.continew</groupId>
+            <artifactId>continew-plugin-generator</artifactId>
+        </dependency>
+
+        <!-- Liquibase(用于管理数据库版本,跟踪、管理和应用数据库变化) -->
+        <dependency>
+            <groupId>org.liquibase</groupId>
+            <artifactId>liquibase-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <!-- 设置构建的 jar 包名 -->
+        <finalName>${project.parent.name}</finalName>
+        <plugins>
+            <!-- Maven 打包插件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <!-- 排除配置文件 -->
+                    <excludes>
+                        <exclude>${config-path}</exclude>
+                        <exclude>db/</exclude>
+                        <exclude>templates/</exclude>
+                        <exclude>logback-spring.xml</exclude>
+                    </excludes>
+                    <archive>
+                        <manifest>
+                            <mainClass>${main-class}</mainClass>
+                            <!-- 为 MANIFEST.MF 中的 Class-Path 加入依赖 jar 目录前缀 -->
+                            <classpathPrefix>../${lib-path}</classpathPrefix>
+                            <addClasspath>true</addClasspath>
+                            <!-- jar 包不包含唯一版本标识 -->
+                            <useUniqueVersions>false</useUniqueVersions>
+                        </manifest>
+                        <manifestEntries>
+                            <!--为 MANIFEST.MF 中的 Class-Path 加入配置文件目录前缀 -->
+                            <Class-Path>../${config-path}</Class-Path>
+                        </manifestEntries>
+                    </archive>
+                    <outputDirectory>${project.build.directory}/app/${bin-path}</outputDirectory>
+                </configuration>
+            </plugin>
+            <!-- 拷贝依赖 jar -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/app/${lib-path}</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- 拷贝配置文件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <resources>
+                                <resource>
+                                    <directory>src/main/resources/${config-path}</directory>
+                                </resource>
+                                <resource>
+                                    <directory>src/main/resources</directory>
+                                    <includes>
+                                        <include>db/</include>
+                                        <include>templates/</include>
+                                        <include>logback-spring.xml</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                            <outputDirectory>${project.build.directory}/app/${config-path}</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 23 - 0
continew-appapi/src/main/java/top/continew/admin/ContinewAppApiApplication.java

@@ -0,0 +1,23 @@
+package top.continew.admin;
+
+import com.alicp.jetcache.anno.config.EnableMethodCache;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.x.file.storage.spring.EnableFileStorage;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import top.continew.starter.extension.crud.annotation.EnableCrudRestController;
+import top.continew.starter.web.annotation.EnableGlobalResponse;
+
+@Slf4j
+@EnableFileStorage
+@EnableMethodCache(basePackages = "top.continew.admin")
+@EnableGlobalResponse
+@EnableCrudRestController
+@SpringBootApplication
+public class ContinewAppApiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ContinewAppApiApplication.class, args);
+    }
+
+}

+ 38 - 0
continew-appapi/src/main/java/top/continew/admin/config/satoken/LoginPasswordProperties.java

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.admin.config.satoken;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 密码配置属性
+ *
+ * @author Charles7c
+ * @since 2024/6/15 22:15
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "auth.password")
+public class LoginPasswordProperties {
+
+    /**
+     * 排除(放行)路径配置
+     */
+    private String[] excludes = new String[0];
+}

+ 62 - 0
continew-appapi/src/main/java/top/continew/admin/config/satoken/SaExtensionInterceptor.java

@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.admin.config.satoken;
+
+import cn.dev33.satoken.fun.SaParamFunction;
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.stp.StpUtil;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.lang.Nullable;
+import top.continew.admin.common.context.UserContextHolder;
+
+/**
+ * Sa-Token 扩展拦截器
+ *
+ * @author Charles7c
+ * @since 2024/10/10 20:25
+ */
+public class SaExtensionInterceptor extends SaInterceptor {
+
+    public SaExtensionInterceptor(SaParamFunction<Object> auth) {
+        super(auth);
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest request,
+                             HttpServletResponse response,
+                             Object handler) throws Exception {
+        boolean flag = super.preHandle(request, response, handler);
+        if (flag && StpUtil.isLogin()) {
+            UserContextHolder.getContext();
+            UserContextHolder.getExtraContext();
+        }
+        return flag;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request,
+                                HttpServletResponse response,
+                                Object handler,
+                                @Nullable Exception e) throws Exception {
+        try {
+            super.afterCompletion(request, response, handler, e);
+        } finally {
+            UserContextHolder.clearContext();
+        }
+    }
+}

+ 89 - 0
continew-appapi/src/main/java/top/continew/admin/config/satoken/SaTokenConfiguration.java

@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.admin.config.satoken;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaRequest;
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.sign.SaSignTemplate;
+import cn.dev33.satoken.sign.SaSignUtil;
+import cn.dev33.satoken.stp.StpInterface;
+import cn.dev33.satoken.stp.StpUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import top.continew.admin.common.context.UserContext;
+import top.continew.admin.common.context.UserContextHolder;
+import top.continew.starter.auth.satoken.autoconfigure.SaTokenExtensionProperties;
+import top.continew.starter.core.constant.StringConstants;
+import top.continew.starter.core.exception.BusinessException;
+import top.continew.starter.core.validation.CheckUtils;
+
+import java.util.List;
+
+/**
+ * Sa-Token 配置
+ *
+ * @author Charles7c
+ * @author chengzi
+ * @since 2022/12/19 22:13
+ */
+@Configuration
+@RequiredArgsConstructor
+public class SaTokenConfiguration {
+
+    private final SaTokenExtensionProperties properties;
+    private final LoginPasswordProperties loginPasswordProperties;
+
+    /**
+     * Sa-Token 权限认证配置
+     */
+    @Bean
+    public StpInterface stpInterface() {
+        return new SaTokenPermissionImpl();
+    }
+
+    /**
+     * SaToken 拦截器配置
+     */
+    @Bean
+    public SaInterceptor saInterceptor() {
+        return new SaExtensionInterceptor(handle -> SaRouter.match(StringConstants.PATH_PATTERN)
+                .notMatch(properties.getSecurity().getExcludes())
+                .check(r -> {
+                    // 如果包含 sign,进行 API 接口参数签名验证
+                    SaRequest saRequest = SaHolder.getRequest();
+                    List<String> paramNames = saRequest.getParamNames();
+                    if (paramNames.stream().anyMatch(SaSignTemplate.sign::equals)) {
+                        try {
+                            SaSignUtil.checkRequest(saRequest);
+                        } catch (Exception e) {
+                            throw new BusinessException(e.getMessage());
+                        }
+                        return;
+                    }
+                    // 不包含 sign 参数,进行普通登录验证
+                    StpUtil.checkLogin();
+                    if (SaRouter.isMatchCurrURI(loginPasswordProperties.getExcludes())) {
+                        return;
+                    }
+                    UserContext userContext = UserContextHolder.getContext();
+                    CheckUtils.throwIf(userContext.isPasswordExpired(), "密码已过期,请修改密码");
+                }));
+    }
+}

+ 45 - 0
continew-appapi/src/main/java/top/continew/admin/config/satoken/SaTokenPermissionImpl.java

@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.admin.config.satoken;
+
+import cn.dev33.satoken.stp.StpInterface;
+import top.continew.admin.common.context.UserContext;
+import top.continew.admin.common.context.UserContextHolder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Sa-Token 权限认证实现
+ *
+ * @author Charles7c
+ * @since 2023/3/1 22:28
+ */
+public class SaTokenPermissionImpl implements StpInterface {
+
+    @Override
+    public List<String> getPermissionList(Object loginId, String loginType) {
+        UserContext userContext = UserContextHolder.getContext();
+        return new ArrayList<>(userContext.getPermissions());
+    }
+
+    @Override
+    public List<String> getRoleList(Object loginId, String loginType) {
+        UserContext userContext = UserContextHolder.getContext();
+        return new ArrayList<>(userContext.getRoleCodes());
+    }
+}

+ 43 - 0
continew-appapi/src/main/java/top/continew/admin/controller/LoginController.java

@@ -0,0 +1,43 @@
+package top.continew.admin.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import cn.dev33.satoken.stp.SaTokenInfo;
+import cn.dev33.satoken.stp.StpUtil;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import top.continew.admin.common.context.UserExtraContext;
+import top.continew.admin.user.model.req.AppLoginReq;
+import top.continew.admin.user.service.ITgUserService;
+
+@RestController()
+@AllArgsConstructor
+@Tag(name = "tg登录api")
+@RequestMapping("/login")
+@Slf4j
+public class LoginController {
+    private final ITgUserService userService;
+
+    @SaIgnore
+    @GetMapping("/coinLogin")
+    @Operation(summary = "tg账号登录", description = "根据tg用户id进行登录")
+    public SaTokenInfo coinLogin(@Validated AppLoginReq req) {
+        return userService.tgLogin(req);
+    }
+
+    @RequestMapping("/getUserExtraContext")
+    public UserExtraContext getUserExtraContext() {
+        log.info("loginid {}", StpUtil.getLoginId());
+        log.info(StpUtil.getLoginDevice());
+        log.info("logintime {}", StpUtil.getExtra("loginTime"));
+        UserExtraContext userExtraContext = new UserExtraContext();
+        userExtraContext.setIp(StpUtil.getExtra("ip") + "");
+        userExtraContext.setOs(StpUtil.getExtra("os") + "");
+        return userExtraContext;
+    }
+
+
+}

+ 318 - 0
continew-appapi/src/main/resources/config/application-dev.yml

@@ -0,0 +1,318 @@
+--- ### 项目配置
+project:
+  # URL(跨域配置默认放行此 URL,第三方登录回调默认使用此 URL 为前缀,请注意更改为你实际的前端 URL)
+  url: http://localhost:5173
+
+--- ### 服务器配置
+server:
+  # HTTP 端口(默认 8080)
+  port: 8100
+
+--- ### 数据源配置
+spring.datasource:
+  type: com.zaxxer.hikari.HikariDataSource
+  url: jdbc:p6spy:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
+  username: ${DB_USER:root}
+  password: ${DB_PWD:123456}
+  driver-class-name: com.p6spy.engine.spy.P6SpyDriver
+  #  # PostgreSQL 配置
+  #  url: jdbc:p6spy:postgresql://${DB_HOST:127.0.0.1}:${DB_PORT:5432}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
+  #  username: ${DB_USER:root}
+  #  password: ${DB_PWD:123456}
+  #  driver-class-name: com.p6spy.engine.spy.P6SpyDriver
+  # Hikari 连接池配置(完整配置请参阅:https://github.com/brettwooldridge/HikariCP)
+  hikari:
+    # 最大连接数量(默认 10,根据实际环境调整)
+    # 注意:当连接达到上限,并且没有空闲连接可用时,获取连接将在超时前阻塞最多 connectionTimeout 毫秒
+    maximum-pool-size: 20
+    # 获取连接超时时间(默认 30000 毫秒,30 秒)
+    connection-timeout: 30000
+    # 空闲连接最大存活时间(默认 600000 毫秒,10 分钟)
+    idle-timeout: 600000
+    # 保持连接活动的频率,以防止它被数据库或网络基础设施超时。该值必须小于 maxLifetime(默认 0,禁用)
+    keepaliveTime: 30000
+    # 连接最大生存时间(默认 1800000 毫秒,30 分钟)
+    max-lifetime: 1800000
+## Liquibase 配置
+spring.liquibase:
+  # 是否启用
+  enabled: true
+  # 配置文件路径
+  change-log: classpath:/db/changelog/db.changelog-master.yaml
+
+--- ### 缓存配置
+spring.data:
+  ## Redis 配置(单机模式)
+  redis:
+    # 地址
+    host: ${REDIS_HOST:127.0.0.1}
+    # 端口(默认 6379)
+    port: ${REDIS_PORT:6379}
+    # 密码(未设置密码时请注释掉)
+    password: ${REDIS_PWD:123456}
+    # 数据库索引
+    database: ${REDIS_DB:0}
+    # 连接超时时间
+    timeout: 10s
+    # 是否开启 SSL
+    ssl:
+      enabled: false
+  ## Redisson 配置
+  redisson:
+    enabled: true
+    mode: SINGLE
+## JetCache 配置
+jetcache:
+  # 统计间隔(默认 0,表示不统计)
+  statIntervalMinutes: 15
+  ## 本地/进程级/一级缓存配置
+  local:
+    default:
+      # 缓存类型
+      type: caffeine
+      # key 转换器的全局配置
+      keyConvertor: jackson
+      # 以毫秒为单位指定超时时间的全局配置
+      expireAfterWriteInMillis: 7200000
+      # 每个缓存实例的最大元素的全局配置,仅 local 类型的缓存需要指定
+      limit: 1000
+  ## 远程/分布式/二级缓存配置
+  remote:
+    default:
+      # 缓存类型
+      type: redisson
+      # key 转换器的全局配置(用于将复杂的 KEY 类型转换为缓存实现可以接受的类型)
+      keyConvertor: jackson
+      # 以毫秒为单位指定超时时间的全局配置
+      expireAfterWriteInMillis: 7200000
+      # 2.7+ 支持两级缓存更新以后失效其他 JVM 中的 local cache,但多个服务共用 Redis 同一个 channel 可能会造成广播风暴,需要在这里指定channel。
+      # 你可以决定多个不同的服务是否共用同一个 channel,如果没有指定则不开启。
+      broadcastChannel: ${spring.application.name}
+      # 序列化器的全局配置,仅 remote 类型的缓存需要指定
+      valueEncoder: java
+      valueDecoder: java
+
+--- ### 验证码配置
+continew-starter.captcha:
+  ## 行为验证码
+  behavior:
+    enabled: true
+    cache-type: REDIS
+    water-mark:
+    # 一分钟内接口请求次数限制开关(默认:0,关闭,开启后下方失败锁定配置才会生效)
+    req-frequency-limit-enable: 0
+    # 一分钟内验证码最多失败次数限制(默认:5次)
+    req-get-lock-limit: 5
+    # 一分钟内验证码最多失败次数限制达标后锁定时间(默认:300秒)
+    req-get-lock-seconds: 300
+  ## 图形验证码
+  graphic:
+    # 类型
+    type: SPEC
+    # 内容长度
+    length: 4
+    # 过期时间
+    expirationInMinutes: 2
+## 其他验证码配置
+captcha:
+  ## 邮箱验证码配置
+  mail:
+    # 内容长度
+    length: 6
+    # 过期时间
+    expirationInMinutes: 5
+    # 模板路径
+    templatePath: mail/captcha.ftl
+  ## 短信验证码配置
+  sms:
+    # 内容长度
+    length: 4
+    # 过期时间
+    expirationInMinutes: 5
+    # 模板 ID
+    templateId: 1
+
+--- ### 日志配置
+continew-starter.log:
+  # 是否打印日志,开启后可打印访问日志(类似于 Nginx access log)
+  is-print: true
+## 项目日志配置(配置重叠部分,优先级高于 logback-spring.xml 中的配置)
+logging:
+  level:
+    top.continew.admin: DEBUG
+    top.continew.starter: DEBUG
+  file:
+    path: ./logs
+
+--- ### 跨域配置
+continew-starter.web.cors:
+  enabled: true
+  # 配置允许跨域的域名
+  allowed-origins: '*'
+  # 配置允许跨域的请求方式
+  allowed-methods: '*'
+  # 配置允许跨域的请求头
+  allowed-headers: '*'
+  # 配置允许跨域的响应头
+  exposed-headers: '*'
+
+--- ### 接口文档配置
+springdoc:
+  swagger-ui:
+    enabled: true
+
+--- ### WebSocket 配置
+continew-starter.messaging.websocket:
+  enabled: true
+  path: /websocket
+  # 配置允许跨域的域名
+  allowed-origins: '*'
+
+--- ### 短信配置
+sms:
+  # 从 YAML 读取配置
+  config-type: YAML
+  http-log: true
+  is-print: false
+  blends:
+    cloopen:
+      # 短信厂商
+      supplier: cloopen
+      base-url: https://app.cloopen.com:8883/2013-12-26
+      access-key-id: 你的Access Key
+      access-key-secret: 你的Access Key Secret
+      sdk-app-id: 你的应用ID
+
+--- ### 邮件配置
+spring.mail:
+  # 根据需要更换
+  host: smtp.126.com
+  port: 465
+  username: 你的邮箱
+  password: 你的邮箱授权码
+  properties:
+    mail:
+      smtp:
+        auth: true
+        socketFactory:
+          class: javax.net.ssl.SSLSocketFactory
+          port: 465
+
+--- ### Just Auth 配置
+justauth:
+  enabled: true
+  type:
+    GITEE:
+      client-id: 5d271b7f638941812aaf8bfc2e2f08f06d6235ef934e0e39537e2364eb8452c4
+      client-secret: 1f7d08**********5b7**********29e
+      redirect-uri: ${project.url}/social/callback?source=gitee
+    GITHUB:
+      client-id: 38080dad08cfbdfacca9
+      client-secret: 1f7d08**********5b7**********29e
+      redirect-uri: ${project.url}/social/callback?source=github
+  cache:
+    type: REDIS
+
+--- ### Sa-Token 扩展配置
+sa-token.extension:
+  # 安全配置:排除(放行)路径配置
+  security.excludes:
+    - /error
+    # 静态资源
+    - /*.html
+    - /*/*.html
+    - /*/*.css
+    - /*/*.js
+    - /websocket/**
+    # 接口文档相关资源
+    - /favicon.ico
+    - /doc.html
+    - /webjars/**
+    - /swagger-ui/**
+    - /swagger-resources/**
+    - /*/api-docs/**
+    # 本地存储资源
+    - /file/**
+
+--- ### 安全配置
+continew-starter.security:
+  ## 字段加/解密配置
+  crypto:
+    enabled: true
+    # 对称加密算法密钥
+    password: abcdefghijklmnop
+    # 非对称加密算法密钥(在线生成 RSA 密钥对:http://web.chacuo.net/netrsakeypair)
+    public-key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAM51dgYtMyF+tTQt80sfFOpSV27a7t9uaUVeFrdGiVxscuizE7H8SMntYqfn9lp8a5GH5P1/GGehVjUD2gF/4kcCAwEAAQ==
+    private-key: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAznV2Bi0zIX61NC3zSx8U6lJXbtru325pRV4Wt0aJXGxy6LMTsfxIye1ip+f2WnxrkYfk/X8YZ6FWNQPaAX/iRwIDAQABAkEAk/VcAusrpIqA5Ac2P5Tj0VX3cOuXmyouaVcXonr7f+6y2YTjLQuAnkcfKKocQI/juIRQBFQIqqW/m1nmz1wGeQIhAO8XaA/KxzOIgU0l/4lm0A2Wne6RokJ9HLs1YpOzIUmVAiEA3Q9DQrpAlIuiT1yWAGSxA9RxcjUM/1kdVLTkv0avXWsCIE0X8woEjK7lOSwzMG6RpEx9YHdopjViOj1zPVH61KTxAiBmv/dlhqkJ4rV46fIXELZur0pj6WC3N7a4brR8a+CLLQIhAMQyerWl2cPNVtE/8tkziHKbwW3ZUiBXU24wFxedT9iV
+  ## 密码编码器配置
+  password:
+    enabled: true
+    # BCryptPasswordEncoder
+    encoding-id: bcrypt
+  ## 限流器配置
+  limiter:
+    enabled: true
+    key-prefix: RateLimiter
+
+--- ### 文件上传配置
+spring.servlet:
+  multipart:
+    enabled: true
+    # 单文件上传大小限制
+    max-file-size: 10MB
+    # 单次总上传文件大小限制
+    max-request-size: 20MB
+## 头像支持格式配置
+avatar:
+  support-suffix: jpg,jpeg,png,gif
+
+--- ### Snail Job 配置
+snail-job:
+  enabled: false
+  # 客户端地址(默认自动获取本机 IP)
+  #host: 127.0.0.1
+  # 客户端端口(默认:1789)
+  port: 1789
+  # 命名空间 ID
+  namespace: ${SCHEDULE_NAMESPACE:764d604ec6fc45f68cd92514c40e9e1a}
+  # 分组名
+  group: ${SCHEDULE_GROUP:continew-admin}
+  # 令牌
+  token: ${SCHEDULE_TOKEN:SJ_Wyz3dmsdbDOkDujOTSSoBjGQP1BMsVnj}
+  ## 服务端配置(任务调度中心)
+  server:
+    # 服务端地址,若服务端集群部署则此处配置域名
+    host: ${SCHEDULE_HOST:127.0.0.1}
+    # Netty 端口号
+    port: ${SCHEDULE_PORT:1788}
+    # API 配置
+    api:
+      # URL
+      url: http://127.0.0.1:8001/snail-job
+      # 用户名
+      username: admin
+      # 密码
+      password: admin
+  ## 重试数据批量上报滑动窗口配置
+  retry:
+    reportSlidingWindow:
+      # 窗口期单位
+      chrono-unit: SECONDS
+      # 窗口期时间长度
+      duration: 10
+      # 总量窗口期阈值
+      total-threshold: 50
+      # 窗口数量预警
+      window-total-threshold: 150
+  ## 调度线程池配置
+  dispatcherThreadPool:
+    # 核心线程数
+    corePoolSize: 16
+    # 最大线程数
+    maximumPoolSize: 16
+    # 线程存活时间
+    keepAliveTime: 1
+    # 时间单位
+    timeUnit: SECONDS
+    # 队列容量
+    queueCapacity: 10000

+ 290 - 0
continew-appapi/src/main/resources/config/application.yml

@@ -0,0 +1,290 @@
+--- ### 项目配置
+project:
+  # 名称
+  name: ContiNew AppApi
+  # 应用名称
+  app-name: continew-app
+  # 版本
+  version: 3.4.0
+  # 描述
+  description: 持续迭代优化的前后端分离中后台管理系统框架,开箱即用,持续提供舒适的开发体验。
+  # 基本包
+  base-package: top.continew.admin
+  ## 作者信息配置
+  contact:
+    name: Charles7c
+    email: charles7c@126.com
+    url: https://blog.charles7c.top/about/me
+  ## 许可协议信息配置
+  license:
+    name: Apache-2.0
+    url: https://github.com/continew-org/continew-admin/blob/dev/LICENSE
+
+--- ### 日志配置
+continew-starter.log:
+  # 包含信息
+  includes:
+    - DESCRIPTION
+    - MODULE
+    - REQUEST_HEADERS
+    - REQUEST_BODY
+    - IP_ADDRESS
+    - BROWSER
+    - OS
+    - RESPONSE_HEADERS
+    - RESPONSE_BODY
+## 项目日志配置
+logging:
+  config: classpath:logback-spring.xml
+
+--- ### 链路跟踪配置
+continew-starter.web:
+  trace:
+    enabled: true
+    trace-id-name: traceId
+    ## TLog 配置
+    tlog:
+      enable-invoke-time-print: false
+      pattern: '[$spanId][$traceId]'
+      mdc-enable: false
+
+--- ### 全局响应配置
+continew-starter.web:
+  response:
+    # 是否开启国际化(默认:false)
+    i18n: false
+    # 自定义失败 HTTP 状态码(默认:200,建议业务和通信状态码区分)
+    default-http-status-code-on-error: 200
+    # 自定义成功响应码(默认:0)
+    default-success-code: 0
+    # 自定义成功提示(默认:ok)
+    default-success-msg: ok
+    # 自定义失败响应码(默认:1)
+    default-error-code: 1
+    # 自定义失败提示(默认:error)
+    default-error-msg: error
+    # 是否将原生异常错误信息填充到状态信息中
+    origin-exception-using-detail-message: false
+
+--- ### 全局树结构配置(简单树,对应前端 UI)
+continew-starter.crud:
+  tree:
+    id-key: key
+    name-key: title
+    weight-key: sort
+
+--- ### 接口文档配置
+springdoc:
+  # 设置对象型参数的展示形式(设为 true 表示将对象型参数平展开,即对象内的属性直接作为参数展示而不是嵌套在对象内,默认 false)
+  # 如果不添加该全局配置,可以在需要如此处理的对象参数类上使用 @ParameterObject
+  default-flat-param-object: true
+  # 分组配置
+  group-configs:
+    - group: all
+      paths-to-match: /**
+      paths-to-exclude:
+        - /error
+    - group: auth
+      display-name: 系统认证
+      packages-to-scan: ${project.base-package}.controller.auth
+    - group: common
+      display-name: 通用接口
+      packages-to-scan: ${project.base-package}.controller.common
+    - group: system
+      display-name: 系统管理
+      packages-to-scan: ${project.base-package}.controller.system
+    - group: monitor
+      display-name: 系统监控
+      packages-to-scan: ${project.base-package}.controller.monitor
+    - group: schedule
+      display-name: 任务调度
+      packages-to-scan: ${project.base-package}.controller.schedule
+    - group: open
+      display-name: 能力开放
+      packages-to-scan: ${project.base-package}.controller.open
+    - group: code
+      display-name: 代码生成
+      packages-to-scan: ${project.base-package}.controller.code
+  ## 组件配置
+  components:
+    # 鉴权配置
+    security-schemes:
+      Authorization:
+        type: HTTP
+        in: HEADER
+        name: ${sa-token.token-name}
+        scheme: ${sa-token.token-prefix}
+## 接口文档增强配置
+knife4j:
+  enable: true
+  setting:
+    # 是否显示默认的 footer(默认 true,显示)
+    enable-footer: false
+    # 是否自定义 footer(默认 false,非自定义)
+    enable-footer-custom: true
+    # 自定义 footer 内容,支持 Markdown 语法
+    footer-custom-content: 'Copyright © 2022-present [${project.contact.name}](${project.contact.url})&nbsp;⋅&nbsp;[${project.name}](${project.url}) v${project.version}'
+
+--- ### Sa-Token 配置
+sa-token:
+  # token 名称(同时也是 cookie 名称)
+  token-name: Authorization
+  # token 有效期(单位:秒,默认 30 天,-1 代表永不过期)
+  timeout: 86400
+  # token 最低活跃频率(单位:秒,默认 -1,代表不限制,永不冻结。如果 token 超过此时间没有访问系统就会被冻结)
+  active-timeout: 1800
+  # 是否打开自动续签(如果此值为 true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作)
+  auto-renew: true
+  # 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录)
+  is-concurrent: true
+  # 在多人登录同一账号时,是否共用一个 token(为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token)
+  is-share: false
+  # 是否输出操作日志
+  is-log: false
+  # JWT 秘钥
+  jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk
+  ## 扩展配置
+  extension:
+    enabled: true
+    enableJwt: true
+    # 持久层配置
+    dao.type: REDIS
+
+--- ### MyBatis Plus 配置
+mybatis-plus:
+  # Mapper XML 文件目录配置
+  mapper-locations: classpath*:/mapper/**/*Mapper.xml
+  # 类型别名扫描包配置
+  type-aliases-package: ${project.base-package}.**.model
+  ## MyBatis 配置
+  configuration:
+    # MyBatis 自动映射策略
+    # NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
+    auto-mapping-behavior: PARTIAL
+  ## 全局配置
+  global-config:
+    banner: true
+    db-config:
+      # 主键类型(默认 assign_id,表示自行赋值)
+      # auto 代表使用数据库自增策略(需要在表中设置好自增约束)
+      id-type: ASSIGN_ID
+      # 逻辑删除字段
+      logic-delete-field: isDeleted
+      # 逻辑删除全局值(默认 1,表示已删除)
+      logic-delete-value: 1
+      # 逻辑未删除全局值(默认 0,表示未删除)
+      logic-not-delete-value: 0
+  ## 扩展配置
+  extension:
+    enabled: true
+    # Mapper 接口扫描包配置
+    mapper-package: ${project.base-package}.**.mapper
+    # ID 生成器配置
+    id-generator:
+      type: COSID
+    # 分页插件配置
+    pagination:
+      enabled: true
+      db-type: MYSQL
+
+--- ### CosId 配置
+cosid:
+  namespace: ${spring.application.name}
+  machine:
+    enabled: true
+    # 机器号分配器
+    distributor:
+      type: REDIS
+    guarder:
+      # 开启机器号守护
+      enabled: true
+  snowflake:
+    enabled: true
+    zone-id: Asia/Shanghai
+    epoch: 1577203200000
+    share:
+      # 开启时钟回拨同步
+      clock-sync: true
+      friendly: true
+    provider:
+      safe-js:
+        machine-bit: 7
+        sequence-bit: 9
+
+--- ### 认证配置
+auth:
+  ## 密码配置
+  password:
+    excludes:
+      - /auth/route
+      - /auth/user/info
+      - /auth/logout
+      - /system/user/password
+
+--- ### 服务器配置
+server:
+  servlet:
+    # 应用访问路径
+    context-path: /app
+  ## Undertow 服务器配置
+  undertow:
+    # HTTP POST 请求内容的大小上限(默认 -1,不限制)
+    max-http-post-size: -1
+    # 以下的配置会影响 buffer,这些 buffer 会用于服务器连接的 IO 操作,有点类似 Netty 的池化内存管理
+    # 每块 buffer的空间大小(越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可)
+    buffer-size: 512
+    # 是否分配的直接内存(NIO 直接分配的堆外内存)
+    direct-buffers: true
+    threads:
+      # 设置 IO 线程数,它主要执行非阻塞的任务,它们会负责多个连接(默认每个 CPU 核心一个线程)
+      io: 8
+      # 阻塞任务线程池,当执行类似 Servlet 请求阻塞操作,Undertow 会从这个线程池中取得线程(它的值设置取决于系统的负载)
+      worker: 256
+
+--- ### Spring 配置
+spring:
+  application:
+    name: ${project.app-name}
+  main:
+    # 允许定义重名的 bean 对象覆盖原有的 bean
+    allow-bean-definition-overriding: true
+    # 允许循环依赖
+    allow-circular-references: true
+  ## 环境配置
+  profiles:
+    # 启用的环境
+    active: dev
+    include:
+      - generator
+  ## 线程池配置(默认启用扩展配置,如未指定 corePoolSize、maxPoolSize 则根据机器配置自动设置)
+  task:
+    # 异步任务
+    execution:
+      thread-name-prefix: task-pool
+      # 任务拒绝策略(默认 ABORT,不执行新任务,直接抛出 RejectedExecutionException 异常)
+      # CALLER_RUNS:提交的任务在执行被拒绝时,会由提交任务的线程去执行
+      rejected-policy: CALLER_RUNS
+      pool:
+        keep-alive: 300s
+      shutdown:
+        # 是否等待任务执行完成再关闭线程池(默认 false)
+        await-termination: true
+        # 等待时间
+        await-termination-period: 30s
+    # 定时任务
+    scheduling:
+      thread-name-prefix: schedule-pool
+      # 任务拒绝策略(默认 ABORT,不执行新任务,直接抛出 RejectedExecutionException 异常)
+      # CALLER_RUNS:提交的任务在执行被拒绝时,会由提交任务的线程去执行
+      rejected-policy: CALLER_RUNS
+      shutdown:
+        # 是否等待任务执行完成再关闭线程池(默认 false)
+        await-termination: true
+        # 等待时间
+        await-termination-period: 30s
+
+--- ### 健康检查配置
+management.health:
+  mail:
+    # 关闭邮箱健康检查(邮箱配置错误或邮箱服务器不可用时,健康检查会报错)
+    enabled: false

+ 26 - 0
continew-appapi/src/main/resources/db/changelog/db.changelog-master.yaml

@@ -0,0 +1,26 @@
+databaseChangeLog:
+  - include:
+      file: db/changelog/mysql/main_table.sql
+  - include:
+      file: db/changelog/mysql/main_column.sql
+  - include:
+      file: db/changelog/mysql/main_data.sql
+  - include:
+      file: db/changelog/mysql/plugin/plugin_schedule.sql
+  - include:
+      file: db/changelog/mysql/plugin/plugin_open.sql
+  - include:
+      file: db/changelog/mysql/plugin/plugin_generator.sql
+# PostgreSQL
+#  - include:
+#      file: db/changelog/postgresql/main_table.sql
+#  - include:
+#      file: db/changelog/postgresql/main_column.sql
+#  - include:
+#      file: db/changelog/postgresql/main_data.sql
+#  - include:
+#      file: db/changelog/postgresql/plugin/plugin_schedule.sql
+#  - include:
+#      file: db/changelog/postgresql/plugin/plugin_open.sql
+#  - include:
+#      file: db/changelog/postgresql/plugin/plugin_generator.sql

+ 2 - 0
continew-appapi/src/main/resources/db/changelog/mysql/main_column.sql

@@ -0,0 +1,2 @@
+-- liquibase formatted sql
+

+ 190 - 0
continew-appapi/src/main/resources/db/changelog/mysql/main_data.sql

@@ -0,0 +1,190 @@
+-- liquibase formatted sql
+
+-- changeset Charles7c:1
+-- comment 初始化表数据
+-- 初始化默认菜单
+INSERT INTO `sys_menu`
+(`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `redirect`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1000, '系统管理', 0, 1, '/system', 'System', 'Layout', '/system/user', 'settings', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
+(1010, '用户管理', 1000, 2, '/system/user', 'SystemUser', 'system/user/index', NULL, 'user', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
+(1011, '列表', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:list', 1, 1, 1, NOW(), NULL, NULL),
+(1012, '详情', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1013, '新增', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:add', 3, 1, 1, NOW(), NULL, NULL),
+(1014, '修改', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:update', 4, 1, 1, NOW(), NULL, NULL),
+(1015, '删除', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1016, '导出', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:export', 6, 1, 1, NOW(), NULL, NULL),
+(1017, '导入', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:import', 7, 1, 1, NOW(), NULL, NULL),
+(1018, '重置密码', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:resetPwd', 8, 1, 1, NOW(), NULL, NULL),
+(1019, '分配角色', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:updateRole', 9, 1, 1, NOW(), NULL, NULL),
+
+(1030, '角色管理', 1000, 2, '/system/role', 'SystemRole', 'system/role/index', NULL, 'user-group', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), NULL, NULL),
+(1031, '列表', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:list', 1, 1, 1, NOW(), NULL, NULL),
+(1032, '详情', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1033, '新增', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:add', 3, 1, 1, NOW(), NULL, NULL),
+(1034, '修改', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:update', 4, 1, 1, NOW(), NULL, NULL),
+(1035, '删除', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1036, '分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:assign', 6, 1, 1, NOW(), NULL, NULL),
+
+(1050, '菜单管理', 1000, 2, '/system/menu', 'SystemMenu', 'system/menu/index', NULL, 'menu', b'0', b'0', b'0', NULL, 3, 1, 1, NOW(), NULL, NULL),
+(1051, '列表', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:list', 1, 1, 1, NOW(), NULL, NULL),
+(1052, '详情', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1053, '新增', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:add', 3, 1, 1, NOW(), NULL, NULL),
+(1054, '修改', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:update', 4, 1, 1, NOW(), NULL, NULL),
+(1055, '删除', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1060, '部门管理', 1000, 2, '/system/dept', 'SystemDept', 'system/dept/index', NULL, 'mind-mapping', b'0', b'0', b'0', NULL, 4, 1, 1, NOW(), NULL, NULL),
+(1061, '列表', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:list', 1, 1, 1, NOW(), NULL, NULL),
+(1062, '详情', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1063, '新增', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:add', 3, 1, 1, NOW(), NULL, NULL),
+(1064, '修改', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:update', 4, 1, 1, NOW(), NULL, NULL),
+(1065, '删除', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1066, '导出', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:export', 6, 1, 1, NOW(), NULL, NULL),
+
+(1070, '字典管理', 1000, 2, '/system/dict', 'SystemDict', 'system/dict/index', NULL, 'bookmark', b'0', b'0', b'0', NULL, 5, 1, 1, NOW(), NULL, NULL),
+(1071, '列表', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:list', 1, 1, 1, NOW(), NULL, NULL),
+(1072, '详情', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1073, '新增', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:add', 3, 1, 1, NOW(), NULL, NULL),
+(1074, '修改', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:update', 4, 1, 1, NOW(), NULL, NULL),
+(1075, '删除', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1080, '字典项管理', 1000, 2, '/system/dict/item', 'SystemDictItem', 'system/dict/item/index', NULL, 'bookmark', b'0', b'0', b'1', NULL, 5, 1, 1, NOW(), NULL, NULL),
+(1081, '列表', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:list', 1, 1, 1, NOW(), NULL, NULL),
+(1082, '详情', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1083, '新增', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:add', 3, 1, 1, NOW(), NULL, NULL),
+(1084, '修改', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:update', 4, 1, 1, NOW(), NULL, NULL),
+(1085, '删除', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1090, '通知公告', 1000, 2, '/system/notice', 'SystemNotice', 'system/notice/index', NULL, 'notification', b'0', b'0', b'0', NULL, 6, 1, 1, NOW(), NULL, NULL),
+(1091, '列表', 1090, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:notice:list', 1, 1, 1, NOW(), NULL, NULL),
+(1092, '详情', 1090, 2, '/system/notice/detail', 'SystemNoticeDetail', 'system/notice/detail/index', NULL, NULL, b'0', b'0', b'1', 'system:notice:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1093, '新增', 1090, 2, '/system/notice/add', 'SystemNoticeAdd', 'system/notice/add/index', NULL, NULL, b'0', b'0', b'1', 'system:notice:add', 3, 1, 1, NOW(), NULL, NULL),
+(1094, '修改', 1090, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:notice:update', 4, 1, 1, NOW(), NULL, NULL),
+(1095, '删除', 1090, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:notice:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1100, '文件管理', 1000, 2, '/system/file', 'SystemFile', 'system/file/index', NULL, 'file', b'0', b'0', b'0', NULL, 7, 1, 1, NOW(), NULL, NULL),
+(1101, '列表', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:list', 1, 1, 1, NOW(), NULL, NULL),
+(1102, '详情', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1103, '上传', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:upload', 3, 1, 1, NOW(), NULL, NULL),
+(1104, '修改', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:update', 4, 1, 1, NOW(), NULL, NULL),
+(1105, '删除', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1106, '下载', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:download', 6, 1, 1, NOW(), NULL, NULL),
+
+(1110, '存储管理', 1000, 2, '/system/storage', 'SystemStorage', 'system/storage/index', NULL, 'storage', b'0', b'0', b'0', NULL, 8, 1, 1, NOW(), NULL, NULL),
+(1111, '列表', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:list', 1, 1, 1, NOW(), NULL, NULL),
+(1112, '详情', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1113, '新增', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:add', 3, 1, 1, NOW(), NULL, NULL),
+(1114, '修改', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:update', 4, 1, 1, NOW(), NULL, NULL),
+(1115, '删除', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1190, '系统配置', 1000, 2, '/system/config', 'SystemConfig', 'system/config/index', NULL, 'config', b'0', b'0', b'0', NULL, 999, 1, 1, NOW(), NULL, NULL),
+(1191, '查看', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:list', 1, 1, 1, NOW(), NULL, NULL),
+(1192, '修改', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:update', 2, 1, 1, NOW(), NULL, NULL),
+(1193, '重置', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:reset', 3, 1, 1, NOW(), NULL, NULL),
+
+(2000, '系统监控', 0, 1, '/monitor', 'Monitor', 'Layout', '/monitor/online', 'computer', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), NULL, NULL),
+(2010, '在线用户', 2000, 2, '/monitor/online', 'MonitorOnline', 'monitor/online/index', NULL, 'user', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
+(2011, '列表', 2010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:online:list', 1, 1, 1, NOW(), NULL, NULL),
+(2012, '强退', 2010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:online:kickout', 2, 1, 1, NOW(), NULL, NULL),
+
+(2020, '系统日志', 2000, 2, '/monitor/log', 'MonitorLog', 'monitor/log/index', NULL, 'history', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), NULL, NULL),
+(2021, '列表', 2020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:log:list', 1, 1, 1, NOW(), NULL, NULL),
+(2022, '详情', 2020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:log:detail', 2, 1, 1, NOW(), NULL, NULL),
+(2023, '导出', 2020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:log:export', 3, 1, 1, NOW(), NULL, NULL);
+
+-- 初始化默认部门
+INSERT INTO `sys_dept`
+(`id`, `name`, `parent_id`, `ancestors`, `description`, `sort`, `status`, `is_system`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1, 'Xxx科技有限公司', 0, '0', '系统初始部门', 1, 1, b'1', 1, NOW(), NULL, NULL),
+(547887852587843590, '天津总部', 1, '0,1', NULL, 1, 1, b'0', 1, NOW(), NULL, NULL),
+(547888008188133385, '研发部', 547887852587843590, '0,1,547887852587843590', NULL, 1, 1, b'0', 1, NOW(), NULL, NULL),
+(547888460711591948, 'UI部', 547887852587843590, '0,1,547887852587843590', NULL, 2, 1, b'0', 1, NOW(), NULL, NULL),
+(547888483713155087, '测试部', 547887852587843590, '0,1,547887852587843590', NULL, 3, 1, b'0', 1, NOW(), NULL, NULL),
+(547888505959743506, '运维部', 547887852587843590, '0,1,547887852587843590', NULL, 4, 1, b'0', 1, NOW(), NULL, NULL),
+(547888556819873814, '研发一组', 547888008188133385, '0,1,547887852587843590,547888008188133385', NULL, 1, 1, b'0', 1, NOW(), NULL, NULL),
+(547888580614160409, '研发二组', 547888008188133385, '0,1,547887852587843590,547888008188133385', NULL, 2, 2, b'0', 1, NOW(), NULL, NULL);
+
+-- 初始化默认角色
+INSERT INTO `sys_role`
+(`id`, `name`, `code`, `data_scope`, `description`, `sort`, `is_system`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1, '系统管理员', 'admin', 1, '系统初始角色', 1, b'1', 1, NOW(), NULL, NULL),
+(547888897925840928, '测试人员', 'test', 5, NULL, 2, b'0', 1, NOW(), NULL, NULL);
+
+-- 初始化默认用户:admin/admin123;test/test123
+INSERT INTO `sys_user`
+(`id`, `username`, `nickname`, `password`, `gender`, `email`, `phone`, `avatar`, `description`, `status`, `is_system`, `pwd_reset_time`, `dept_id`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1, 'admin', '系统管理员', '{bcrypt}$2a$10$4jGwK2BMJ7FgVR.mgwGodey8.xR8FLoU1XSXpxJ9nZQt.pufhasSa', 1, '42190c6c5639d2ca4edb4150a35e058559ccf8270361a23745a2fd285a273c28', '5bda89a4609a65546422ea56bfe5eab4', NULL, '系统初始用户', 1, b'1', NOW(), 1, 1, NOW(), NULL, NULL),
+(547889293968801831, 'test', '测试员', '{bcrypt}$2a$10$xAsoeMJ.jc/kSxhviLAg7.j2iFrhi6yYAdniNdjLiIUWU/BRZl2Ti', 2, NULL, NULL, NULL, NULL, 1, b'0', NOW(), 547888483713155087, 1, NOW(), NULL, NULL);
+
+-- 初始化默认参数
+INSERT INTO `sys_option`
+(`id`, `category`, `name`, `code`, `value`, `default_value`, `description`, `update_user`, `update_time`)
+VALUES
+(1, 'SITE', '系统标题', 'SITE_TITLE', NULL, 'ContiNew Admin', '用于显示登录页面的系统标题。', NULL, NULL),
+(2, 'SITE', '系统描述', 'SITE_DESCRIPTION', NULL, '持续迭代优化的前后端分离中后台管理系统框架', NULL, NULL, NULL),
+(3, 'SITE', '版权信息', 'SITE_COPYRIGHT', NULL, 'Copyright © 2022 - present ContiNew Admin 版权所有', '用于显示登录页面的底部版权信息。', NULL, NULL),
+(4, 'SITE', '备案号', 'SITE_BEIAN', NULL, NULL, 'ICP备案号', NULL, NULL),
+(5, 'SITE', 'favicon', 'SITE_FAVICON', NULL, '/favicon.ico', '用于显示浏览器地址栏的系统LOGO。', NULL, NULL),
+(6, 'SITE', '系统LOGO', 'SITE_LOGO', NULL, '/logo.svg', '用于显示登录页面的系统LOGO。', NULL, NULL),
+(7, 'PASSWORD', '登录密码错误锁定账号的次数', 'PASSWORD_ERROR_LOCK_COUNT', NULL, '5', '取值范围为 0-10(0 表示不锁定)。', NULL, NULL),
+(8, 'PASSWORD', '登录密码错误锁定账号的时间(min)', 'PASSWORD_ERROR_LOCK_MINUTES', NULL, '5', '取值范围为 1-1440(一天)。', NULL, NULL),
+(9, 'PASSWORD', '密码有效期(天)', 'PASSWORD_EXPIRATION_DAYS', NULL, '0', '取值范围为 0-999(0 表示永久有效)。', NULL, NULL),
+(10, 'PASSWORD', '密码到期提前提示(天)', 'PASSWORD_EXPIRATION_WARNING_DAYS', NULL, '0', '密码到期 N 天前进行提示(0 表示不提示)。', NULL, NULL),
+(11, 'PASSWORD', '密码重复使用次数', 'PASSWORD_REPETITION_TIMES', NULL, '3', '不允许使用最近 N 次密码,取值范围为 3-32。', NULL, NULL),
+(12, 'PASSWORD', '密码最小长度', 'PASSWORD_MIN_LENGTH', NULL, '8', '取值范围为 8-32。', NULL, NULL),
+(13, 'PASSWORD', '密码是否允许包含正反序账号名', 'PASSWORD_ALLOW_CONTAIN_USERNAME', NULL, '1', NULL, NULL, NULL),
+(14, 'PASSWORD', '密码是否必须包含特殊字符', 'PASSWORD_REQUIRE_SYMBOLS', NULL, '0', NULL, NULL, NULL),
+(15, 'MAIL', '发送协议', 'MAIL_PROTOCOL', NULL, 'smtp', NULL, NULL, NULL),
+(16, 'MAIL', '服务器地址', 'MAIL_HOST', NULL, 'smtp.126.com', NULL, NULL, NULL),
+(17, 'MAIL', '服务器端口', 'MAIL_PORT', NULL, '465', NULL, NULL, NULL),
+(18, 'MAIL', '用户名', 'MAIL_USERNAME', NULL, 'charles7c@126.com', NULL, NULL, NULL),
+(19, 'MAIL', '密码', 'MAIL_PASSWORD', NULL, NULL, NULL, NULL, NULL),
+(20, 'MAIL', '是否启用SSL', 'MAIL_SSL_ENABLED', NULL, '1', NULL, NULL, NULL),
+(21, 'MAIL', 'SSL端口', 'MAIL_SSL_PORT', NULL, '465', NULL, NULL, NULL),
+(22, 'LOGIN', '是否启用验证码', 'LOGIN_CAPTCHA_ENABLED', NULL, '1', '是否启用验证码(1:是;0:否)', NULL, NULL);
+
+-- 初始化默认字典
+INSERT INTO `sys_dict`
+(`id`, `name`, `code`, `description`, `is_system`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1, '公告类型', 'notice_type', NULL, b'1', 1, NOW(), NULL, NULL),
+(2, '消息类型', 'message_type', NULL, b'1', 1, NOW(), NULL, NULL);
+
+INSERT INTO `sys_dict_item`
+(`id`, `label`, `value`, `color`, `sort`, `description`, `status`, `dict_id`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1, '通知', '1', 'blue', 1, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(2, '活动', '2', 'orangered', 2, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(3, '安全消息', '1', 'blue', 1, NULL, 1, 2, 1, NOW(), NULL, NULL),
+(4, '活动消息', '2', 'orangered', 2, NULL, 1, 2, 1, NOW(), NULL, NULL);
+
+-- 初始化默认用户和角色关联数据
+INSERT INTO `sys_user_role`
+(`user_id`, `role_id`)
+VALUES
+(1, 1),
+(547889293968801831, 547888897925840928);
+
+-- 初始化默认角色和菜单关联数据
+INSERT INTO `sys_role_menu`
+(`role_id`, `menu_id`)
+VALUES
+(547888897925840928, 1000),
+(547888897925840928, 1010),
+(547888897925840928, 1011),
+(547888897925840928, 1012),
+(547888897925840928, 1013),
+(547888897925840928, 1014);
+
+-- 初始化默认角色和部门关联数据
+INSERT INTO `sys_role_dept` (`role_id`, `dept_id`) VALUES (547888897925840928, 547888483713155087);
+
+-- 初始化默认存储
+INSERT INTO `sys_storage`
+(`id`, `name`, `code`, `type`, `access_key`, `secret_key`, `endpoint`, `bucket_name`, `domain`, `description`, `is_default`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(1, '开发环境', 'local_dev', 2, NULL, NULL, NULL, 'C:/continew-admin/data/file/', 'http://localhost:8000/file', '本地存储', b'1', 1, 1, 1, NOW(), NULL, NULL),
+(2, '生产环境', 'local_prod', 2, NULL, NULL, NULL, '../data/file/', 'http://api.continew.top/file', '本地存储', b'0', 2, 2, 1, NOW(), NULL, NULL);
+

+ 296 - 0
continew-appapi/src/main/resources/db/changelog/mysql/main_table.sql

@@ -0,0 +1,296 @@
+-- liquibase formatted sql
+
+-- changeset charles7c:1
+-- comment 初始化表结构
+CREATE TABLE IF NOT EXISTS `sys_menu` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `title`       varchar(30)  NOT NULL                    COMMENT '标题',
+    `parent_id`   bigint(20)   NOT NULL DEFAULT 0          COMMENT '上级菜单ID',
+    `type`        tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型(1:目录;2:菜单;3:按钮)',
+    `path`        varchar(255) DEFAULT NULL                COMMENT '路由地址',
+    `name`        varchar(50)  DEFAULT NULL                COMMENT '组件名称',
+    `component`   varchar(255) DEFAULT NULL                COMMENT '组件路径',
+    `redirect`    varchar(255) DEFAULT NULL                COMMENT '重定向地址',
+    `icon`        varchar(50)  DEFAULT NULL                COMMENT '图标',
+    `is_external` bit(1)       DEFAULT b'0'                COMMENT '是否外链',
+    `is_cache`    bit(1)       DEFAULT b'0'                COMMENT '是否缓存',
+    `is_hidden`   bit(1)       DEFAULT b'0'                COMMENT '是否隐藏',
+    `permission`  varchar(100) DEFAULT NULL                COMMENT '权限标识',
+    `sort`        int          NOT NULL DEFAULT 999        COMMENT '排序',
+    `status`      tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
+    `create_user` bigint(20)   NOT NULL                    COMMENT '创建人',
+    `create_time` datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user` bigint(20)   DEFAULT NULL                COMMENT '修改人',
+    `update_time` datetime     DEFAULT NULL                COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_title_parent_id`(`title`, `parent_id`),
+    INDEX `idx_parent_id`(`parent_id`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜单表';
+
+CREATE TABLE IF NOT EXISTS `sys_dept` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `name`        varchar(30)  NOT NULL                    COMMENT '名称',
+    `parent_id`   bigint(20)   NOT NULL DEFAULT 0          COMMENT '上级部门ID',
+    `ancestors`   varchar(512) NOT NULL DEFAULT ''         COMMENT '祖级列表',
+    `description` varchar(200) DEFAULT NULL                COMMENT '描述',
+    `sort`        int          NOT NULL DEFAULT 999        COMMENT '排序',
+    `status`      tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
+    `is_system`   bit(1)       NOT NULL DEFAULT b'0'       COMMENT '是否为系统内置数据',
+    `create_user` bigint(20)   NOT NULL                    COMMENT '创建人',
+    `create_time` datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user` bigint(20)   DEFAULT NULL                COMMENT '修改人',
+    `update_time` datetime     DEFAULT NULL                COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_name_parent_id`(`name`, `parent_id`),
+    INDEX `idx_parent_id`(`parent_id`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表';
+
+CREATE TABLE IF NOT EXISTS `sys_role` (
+    `id`                  bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `name`                varchar(30)  NOT NULL                COMMENT '名称',
+    `code`                varchar(30)  NOT NULL                COMMENT '编码',
+    `data_scope`          tinyint(1)   NOT NULL DEFAULT 4      COMMENT '数据权限(1:全部数据权限;2:本部门及以下数据权限;3:本部门数据权限;4:仅本人数据权限;5:自定义数据权限)',
+    `description`         varchar(200) DEFAULT NULL            COMMENT '描述',
+    `sort`                int          NOT NULL DEFAULT 999    COMMENT '排序',
+    `is_system`           bit(1)       NOT NULL DEFAULT b'0'   COMMENT '是否为系统内置数据',
+    `menu_check_strictly` bit(1)       DEFAULT b'0'            COMMENT '菜单选择是否父子节点关联',
+    `dept_check_strictly` bit(1)       DEFAULT b'0'            COMMENT '部门选择是否父子节点关联',
+    `create_user`         bigint(20)   NOT NULL                COMMENT '创建人',
+    `create_time`         datetime     NOT NULL                COMMENT '创建时间',
+    `update_user`         bigint(20)   DEFAULT NULL            COMMENT '修改人',
+    `update_time`         datetime     DEFAULT NULL            COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_name`(`name`),
+    UNIQUE INDEX `uk_code`(`code`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
+
+CREATE TABLE IF NOT EXISTS `sys_user` (
+    `id`             bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `username`       varchar(64)  NOT NULL                    COMMENT '用户名',
+    `nickname`       varchar(30)  NOT NULL                    COMMENT '昵称',
+    `password`       varchar(255) DEFAULT NULL                COMMENT '密码',
+    `gender`         tinyint(1)   UNSIGNED NOT NULL DEFAULT 0 COMMENT '性别(0:未知;1:男;2:女)',
+    `email`          varchar(255) DEFAULT NULL                COMMENT '邮箱',
+    `phone`          varchar(255) DEFAULT NULL                COMMENT '手机号码',
+    `avatar`         longtext     DEFAULT NULL                COMMENT '头像',
+    `description`    varchar(200) DEFAULT NULL                COMMENT '描述',
+    `status`         tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
+    `is_system`      bit(1)       NOT NULL DEFAULT b'0'       COMMENT '是否为系统内置数据',
+    `pwd_reset_time` datetime     DEFAULT NULL                COMMENT '最后一次修改密码时间',
+    `dept_id`        bigint(20)   NOT NULL                    COMMENT '部门ID',
+    `create_user`    bigint(20)   DEFAULT NULL                COMMENT '创建人',
+    `create_time`    datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user`    bigint(20)   DEFAULT NULL                COMMENT '修改人',
+    `update_time`    datetime     DEFAULT NULL                COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_username`(`username`),
+    UNIQUE INDEX `uk_email`(`email`),
+    UNIQUE INDEX `uk_phone`(`phone`),
+    INDEX `idx_dept_id`(`dept_id`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
+
+CREATE TABLE IF NOT EXISTS `sys_user_password_history` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `user_id`     bigint(20)   NOT NULL                COMMENT '用户ID',
+    `password`    varchar(255) NOT NULL                COMMENT '密码',
+    `create_time` datetime     NOT NULL                COMMENT '创建时间',
+    PRIMARY KEY (`id`),
+    INDEX `idx_user_id`(`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户历史密码表';
+
+CREATE TABLE IF NOT EXISTS `sys_user_social` (
+    `id`              bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `source`          varchar(255) NOT NULL                COMMENT '来源',
+    `open_id`         varchar(255) NOT NULL                COMMENT '开放ID',
+    `user_id`         bigint(20)   NOT NULL                COMMENT '用户ID',
+    `meta_json`       text         DEFAULT NULL            COMMENT '附加信息',
+    `last_login_time` datetime     DEFAULT NULL            COMMENT '最后登录时间',
+    `create_time`     datetime     NOT NULL                COMMENT '创建时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_source_open_id`(`source`, `open_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户社会化关联表';
+
+CREATE TABLE IF NOT EXISTS `sys_user_role` (
+    `user_id` bigint(20) NOT NULL COMMENT '用户ID',
+    `role_id` bigint(20) NOT NULL COMMENT '角色ID',
+    PRIMARY KEY (`user_id`, `role_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户和角色关联表';
+
+CREATE TABLE IF NOT EXISTS `sys_role_menu` (
+    `role_id` bigint(20) NOT NULL COMMENT '角色ID',
+    `menu_id` bigint(20) NOT NULL COMMENT '菜单ID',
+    PRIMARY KEY (`role_id`, `menu_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和菜单关联表';
+
+CREATE TABLE IF NOT EXISTS `sys_role_dept` (
+    `role_id` bigint(20) NOT NULL COMMENT '角色ID',
+    `dept_id` bigint(20) NOT NULL COMMENT '部门ID',
+    PRIMARY KEY (`role_id`, `dept_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色和部门关联表';
+
+CREATE TABLE IF NOT EXISTS `sys_option` (
+    `id`            bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `category`      varchar(50)  NOT NULL                COMMENT '类别',
+    `name`          varchar(50)  NOT NULL                COMMENT '名称',
+    `code`          varchar(100) NOT NULL                COMMENT '键',
+    `value`         longtext     DEFAULT NULL            COMMENT '值',
+    `default_value` longtext     DEFAULT NULL            COMMENT '默认值',
+    `description`   varchar(200) DEFAULT NULL            COMMENT '描述',
+    `update_user`   bigint(20)   DEFAULT NULL            COMMENT '修改人',
+    `update_time`   datetime     DEFAULT NULL            COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_category_code`(`category`, `code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='参数表';
+
+CREATE TABLE IF NOT EXISTS `sys_dict` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `name`        varchar(30)  NOT NULL                COMMENT '名称',
+    `code`        varchar(30)  NOT NULL                COMMENT '编码',
+    `description` varchar(200) DEFAULT NULL            COMMENT '描述',
+    `is_system`   bit(1)       NOT NULL DEFAULT b'0'   COMMENT '是否为系统内置数据',
+    `create_user` bigint(20)   NOT NULL                COMMENT '创建人',
+    `create_time` datetime     NOT NULL                COMMENT '创建时间',
+    `update_user` bigint(20)   DEFAULT NULL            COMMENT '修改人',
+    `update_time` datetime     DEFAULT NULL            COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_name`(`name`),
+    UNIQUE INDEX `uk_code`(`code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典表';
+
+CREATE TABLE IF NOT EXISTS `sys_dict_item` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `label`       varchar(30)  NOT NULL                    COMMENT '标签',
+    `value`       varchar(30)  NOT NULL                    COMMENT '值',
+    `color`       varchar(30)  DEFAULT NULL                COMMENT '标签颜色',
+    `sort`        int          NOT NULL DEFAULT 999        COMMENT '排序',
+    `description` varchar(200) DEFAULT NULL                COMMENT '描述',
+    `status`      tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
+    `dict_id`     bigint(20)   NOT NULL                    COMMENT '字典ID',
+    `create_user` bigint(20)   NOT NULL                    COMMENT '创建人',
+    `create_time` datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user` bigint(20)   DEFAULT NULL                COMMENT '修改人',
+    `update_time` datetime     DEFAULT NULL                COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_value_dict_id`(`value`, `dict_id`),
+    INDEX `idx_dict_id`(`dict_id`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典项表';
+
+CREATE TABLE IF NOT EXISTS `sys_log` (
+    `id`               bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `trace_id`         varchar(255) DEFAULT NULL                COMMENT '链路ID',
+    `description`      varchar(255) NOT NULL                    COMMENT '日志描述',
+    `module`           varchar(50)  NOT NULL                    COMMENT '所属模块',
+    `request_url`      varchar(512) NOT NULL                    COMMENT '请求URL',
+    `request_method`   varchar(10)  NOT NULL                    COMMENT '请求方式',
+    `request_headers`  text         DEFAULT NULL                COMMENT '请求头',
+    `request_body`     text         DEFAULT NULL                COMMENT '请求体',
+    `status_code`      int          NOT NULL                    COMMENT '状态码',
+    `response_headers` text         DEFAULT NULL                COMMENT '响应头',
+    `response_body`    mediumtext   DEFAULT NULL                COMMENT '响应体',
+    `time_taken`       bigint(20)   NOT NULL                    COMMENT '耗时(ms)',
+    `ip`               varchar(100) DEFAULT NULL                COMMENT 'IP',
+    `address`          varchar(255) DEFAULT NULL                COMMENT 'IP归属地',
+    `browser`          varchar(100) DEFAULT NULL                COMMENT '浏览器',
+    `os`               varchar(100) DEFAULT NULL                COMMENT '操作系统',
+    `status`           tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:成功;2:失败)',
+    `error_msg`        text         DEFAULT NULL                COMMENT '错误信息',
+    `create_user`      bigint(20)   DEFAULT NULL                COMMENT '创建人',
+    `create_time`      datetime     NOT NULL                    COMMENT '创建时间',
+    PRIMARY KEY (`id`),
+    INDEX `idx_module`(`module`),
+    INDEX `idx_ip`(`ip`),
+    INDEX `idx_address`(`address`),
+    INDEX `idx_create_time`(`create_time`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统日志表';
+
+CREATE TABLE IF NOT EXISTS `sys_message` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `title`       varchar(50)  NOT NULL                    COMMENT '标题',
+    `content`     varchar(255) DEFAULT NULL                COMMENT '内容',
+    `type`        tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型(1:系统消息)',
+    `create_user` bigint(20)   DEFAULT NULL                COMMENT '创建人',
+    `create_time` datetime     NOT NULL                    COMMENT '创建时间',
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息表';
+
+CREATE TABLE IF NOT EXISTS `sys_message_user` (
+    `message_id` bigint(20) NOT NULL              COMMENT '消息ID',
+    `user_id`    bigint(11) NOT NULL              COMMENT '用户ID',
+    `is_read`    bit(1)     NOT NULL DEFAULT b'0' COMMENT '是否已读',
+    `read_time`  datetime   DEFAULT NULL          COMMENT '读取时间',
+    PRIMARY KEY (`message_id`, `user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息和用户关联表';
+
+CREATE TABLE IF NOT EXISTS `sys_notice` (
+    `id`             bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `title`          varchar(150) NOT NULL                COMMENT '标题',
+    `content`        mediumtext   NOT NULL                COMMENT '内容',
+    `type`           varchar(30)  NOT NULL                COMMENT '类型',
+    `effective_time` datetime     DEFAULT NULL            COMMENT '生效时间',
+    `terminate_time` datetime     DEFAULT NULL            COMMENT '终止时间',
+    `notice_scope`   int          NOT NULL                COMMENT '通知范围',
+    `notice_users`   json         DEFAULT NULL            COMMENT '通知用户',
+    `sort`           int          NOT NULL DEFAULT 999    COMMENT '排序',
+    `create_user`    bigint(20)   NOT NULL                COMMENT '创建人',
+    `create_time`    datetime     NOT NULL                COMMENT '创建时间',
+    `update_user`    bigint(20)   DEFAULT NULL            COMMENT '修改人',
+    `update_time`    datetime     DEFAULT NULL            COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='公告表';
+
+CREATE TABLE IF NOT EXISTS `sys_storage` (
+    `id`          bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `name`        varchar(100) NOT NULL                    COMMENT '名称',
+    `code`        varchar(30)  NOT NULL                    COMMENT '编码',
+    `type`        tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型(1:兼容S3协议存储;2:本地存储)',
+    `access_key`  varchar(255) DEFAULT NULL                COMMENT 'Access Key(访问密钥)',
+    `secret_key`  varchar(255) DEFAULT NULL                COMMENT 'Secret Key(私有密钥)',
+    `endpoint`    varchar(255) DEFAULT NULL                COMMENT 'Endpoint(终端节点)',
+    `bucket_name` varchar(255) DEFAULT NULL                COMMENT '桶名称',
+    `domain`      varchar(255) NOT NULL DEFAULT ''         COMMENT '域名',
+    `description` varchar(200) DEFAULT NULL                COMMENT '描述',
+    `is_default`  bit(1)       NOT NULL DEFAULT b'0'       COMMENT '是否为默认存储',
+    `sort`        int          NOT NULL DEFAULT 999        COMMENT '排序',
+    `status`      tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
+    `create_user` bigint(20)   NOT NULL                    COMMENT '创建人',
+    `create_time` datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user` bigint(20)   DEFAULT NULL                COMMENT '修改人',
+    `update_time` datetime     DEFAULT NULL                COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_code`(`code`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储表';
+
+CREATE TABLE IF NOT EXISTS `sys_file` (
+    `id`             bigint(20)   NOT NULL AUTO_INCREMENT     COMMENT 'ID',
+    `name`           varchar(255) NOT NULL                    COMMENT '名称',
+    `size`           bigint(20)   NOT NULL                    COMMENT '大小(字节)',
+    `url`            varchar(512) NOT NULL                    COMMENT 'URL',
+    `extension`      varchar(100) DEFAULT NULL                COMMENT '扩展名',
+    `thumbnail_size` bigint(20)   DEFAULT NULL                COMMENT '缩略图大小(字节)',
+    `thumbnail_url`  varchar(512) DEFAULT NULL                COMMENT '缩略图URL',
+    `type`           tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型(1:其他;2:图片;3:文档;4:视频;5:音频)',
+    `storage_id`     bigint(20)   NOT NULL                    COMMENT '存储ID',
+    `create_user`    bigint(20)   NOT NULL                    COMMENT '创建人',
+    `create_time`    datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user`    bigint(20)   NOT NULL                    COMMENT '修改人',
+    `update_time`    datetime     NOT NULL                    COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    INDEX `idx_url`(`url`),
+    INDEX `idx_type`(`type`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件表';

+ 50 - 0
continew-appapi/src/main/resources/db/changelog/mysql/plugin/plugin_generator.sql

@@ -0,0 +1,50 @@
+-- liquibase formatted sql
+
+-- changeset charles7c:1
+-- comment 初始化代码生成插件
+-- 初始化表结构
+CREATE TABLE IF NOT EXISTS `gen_config` (
+    `table_name`    varchar(64)  NOT NULL              COMMENT '表名称',
+    `module_name`   varchar(60)  NOT NULL              COMMENT '模块名称',
+    `package_name`  varchar(60)  NOT NULL              COMMENT '包名称',
+    `business_name` varchar(50)  NOT NULL              COMMENT '业务名称',
+    `author`        varchar(100) NOT NULL              COMMENT '作者',
+    `table_prefix`  varchar(20)  DEFAULT NULL          COMMENT '表前缀',
+    `is_override`   bit(1)       NOT NULL DEFAULT b'0' COMMENT '是否覆盖',
+    `create_time`   datetime     NOT NULL              COMMENT '创建时间',
+    `update_time`   datetime     DEFAULT NULL          COMMENT '修改时间',
+    PRIMARY KEY (`table_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='生成配置表';
+
+CREATE TABLE IF NOT EXISTS `gen_field_config` (
+    `id`            bigint(20)   NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `table_name`    varchar(64)  NOT NULL                COMMENT '表名称',
+    `column_name`   varchar(64)  NOT NULL                COMMENT '列名称',
+    `column_type`   varchar(25)  NOT NULL                COMMENT '列类型',
+    `column_size`   bigint(20)   DEFAULT NULL            COMMENT '列大小',
+    `field_name`    varchar(64)  NOT NULL                COMMENT '字段名称',
+    `field_type`    varchar(25)  NOT NULL                COMMENT '字段类型',
+    `field_sort`    int          NOT NULL DEFAULT 999    COMMENT '字段排序',
+    `comment`       varchar(512) DEFAULT NULL            COMMENT '注释',
+    `is_required`   bit(1)       NOT NULL DEFAULT b'1'   COMMENT '是否必填',
+    `show_in_list`  bit(1)       NOT NULL DEFAULT b'1'   COMMENT '是否在列表中显示',
+    `show_in_form`  bit(1)       NOT NULL DEFAULT b'1'   COMMENT '是否在表单中显示',
+    `show_in_query` bit(1)       NOT NULL DEFAULT b'1'   COMMENT '是否在查询中显示',
+    `form_type`     tinyint(1)   UNSIGNED DEFAULT NULL   COMMENT '表单类型',
+    `query_type`    tinyint(1)   UNSIGNED DEFAULT NULL   COMMENT '查询方式',
+    `dict_code`     varchar(30)  DEFAULT NULL            COMMENT '字典编码',
+    `create_time`   datetime NOT NULL COMMENT '创建时间',
+    PRIMARY KEY (`id`),
+    INDEX `idx_table_name`(`table_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字段配置表';
+
+-- 初始化默认菜单
+INSERT INTO `sys_menu`
+(`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `redirect`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(9000, '代码生成', 0, 1, '/code', 'Code', 'Layout', '/code/generator', 'code-release-managment', b'0', b'0', b'0', NULL, 9, 1, 1, NOW(), NULL, NULL),
+(9010, '代码生成', 9000, 2, '/code/generator', 'CodeGenerator', 'code/generator/index', NULL, 'code', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
+(9011, '列表', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:list', 1, 1, 1, NOW(), NULL, NULL),
+(9012, '配置', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:config', 2, 1, 1, NOW(), NULL, NULL),
+(9013, '预览', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:preview', 3, 1, 1, NOW(), NULL, NULL),
+(9014, '生成', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:generate', 4, 1, 1, NOW(), NULL, NULL);

+ 37 - 0
continew-appapi/src/main/resources/db/changelog/mysql/plugin/plugin_open.sql

@@ -0,0 +1,37 @@
+-- liquibase formatted sql
+
+-- changeset chengzi:1
+-- comment 初始化能力开放插件
+-- 初始化表结构
+CREATE TABLE IF NOT EXISTS `sys_app`  (
+    `id`          bigint(20)   NOT NULL     AUTO_INCREMENT COMMENT 'ID',
+    `name`        varchar(100) NOT NULL                    COMMENT '名称',
+    `access_key`  varchar(255) NOT NULL                    COMMENT 'Access Key(访问密钥)',
+    `secret_key`  varchar(255) NOT NULL                    COMMENT 'Secret Key(私有密钥)',
+    `expire_time` datetime     DEFAULT NULL                COMMENT '失效时间',
+    `description` varchar(200) DEFAULT NULL                COMMENT '描述',
+    `status`      tinyint(1)   UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
+    `create_user` bigint(20)   NOT NULL                    COMMENT '创建人',
+    `create_time` datetime     NOT NULL                    COMMENT '创建时间',
+    `update_user` bigint(20)   DEFAULT NULL                COMMENT '修改人',
+    `update_time` datetime     DEFAULT NULL                COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    UNIQUE INDEX `uk_access_key`(`access_key`),
+    INDEX `idx_create_user`(`create_user`),
+    INDEX `idx_update_user`(`update_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用表';
+
+-- 初始化默认菜单
+INSERT INTO `sys_menu`
+(`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `redirect`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(7000, '能力开放', 0, 1, '/open', 'Open', 'Layout', '/open/app', 'expand', b'0', b'0', b'0', NULL, 7, 1, 1, NOW(), NULL, NULL),
+(7010, '应用管理', 7000, 2, '/open/app', 'OpenApp', 'open/app/index', NULL, 'common', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
+(7011, '列表', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:list', 1, 1, 1, NOW(), NULL, NULL),
+(7012, '详情', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:detail', 2, 1, 1, NOW(), NULL, NULL),
+(7013, '新增', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:add', 3, 1, 1, NOW(), NULL, NULL),
+(7014, '修改', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:update', 4, 1, 1, NOW(), NULL, NULL),
+(7015, '删除', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:delete', 5, 1, 1, NOW(), NULL, NULL),
+(7016, '导出', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:export', 6, 1, 1, NOW(), NULL, NULL),
+(7017, '查看密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:secret', 7, 1, 1, NOW(), NULL, NULL),
+(7018, '重置密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:resetSecret', 8, 1, 1, NOW(), NULL, NULL);

+ 21 - 0
continew-appapi/src/main/resources/db/changelog/mysql/plugin/plugin_schedule.sql

@@ -0,0 +1,21 @@
+-- liquibase formatted sql
+
+-- changeset kai:1
+-- comment 初始化任务调度插件
+-- 初始化默认菜单
+INSERT INTO `sys_menu`
+(`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `redirect`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
+VALUES
+(3000, '任务调度', 0, 1, '/schedule', 'Schedule', 'Layout', '/schedule/job', 'schedule', b'0', b'0', b'0', NULL, 3, 1, 1, NOW(), NULL, NULL),
+(3010, '任务管理', 3000, 2, '/schedule/job', 'ScheduleJob', 'schedule/job/index', NULL, 'select-all', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
+(3011, '列表', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:list', 1, 1, 1, NOW(), NULL, NULL),
+(3012, '详情', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:detail', 2, 1, 1, NOW(), NULL, NULL),
+(3013, '新增', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:add', 3, 1, 1, NOW(), NULL, NULL),
+(3014, '修改', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:update', 4, 1, 1, NOW(), NULL, NULL),
+(3015, '删除', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:delete', 5, 1, 1, NOW(), NULL, NULL),
+(3016, '执行', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:trigger', 6, 1, 1, NOW(), NULL, NULL),
+(3020, '任务日志', 3000, 2, '/schedule/log', 'ScheduleLog', 'schedule/log/index', NULL, 'find-replace', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), NULL, NULL),
+(3021, '列表', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:list', 1, 1, 1, NOW(), NULL, NULL),
+(3022, '详情', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:detail', 2, 1, 1, NOW(), NULL, NULL),
+(3023, '停止', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:stop', 3, 1, 1, NOW(), NULL, NULL),
+(3024, '重试', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:retry', 4, 1, 1, NOW(), NULL, NULL);

+ 2 - 0
continew-appapi/src/main/resources/db/changelog/postgresql/main_column.sql

@@ -0,0 +1,2 @@
+-- liquibase formatted sql
+

+ 189 - 0
continew-appapi/src/main/resources/db/changelog/postgresql/main_data.sql

@@ -0,0 +1,189 @@
+-- liquibase formatted sql
+
+-- changeset Charles7c:1
+-- comment 初始化表数据
+-- 初始化默认菜单
+INSERT INTO "sys_menu"
+("id", "title", "parent_id", "type", "path", "name", "component", "redirect", "icon", "is_external", "is_cache", "is_hidden", "permission", "sort", "status", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1000, '系统管理', 0, 1, '/system', 'System', 'Layout', '/system/user', 'settings', false, false, false, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(1010, '用户管理', 1000, 2, '/system/user', 'SystemUser', 'system/user/index', NULL, 'user', false, false, false, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(1011, '列表', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:list', 1, 1, 1, NOW(), NULL, NULL),
+(1012, '详情', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1013, '新增', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:add', 3, 1, 1, NOW(), NULL, NULL),
+(1014, '修改', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:update', 4, 1, 1, NOW(), NULL, NULL),
+(1015, '删除', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1016, '导出', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:export', 6, 1, 1, NOW(), NULL, NULL),
+(1017, '导入', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:import', 7, 1, 1, NOW(), NULL, NULL),
+(1018, '重置密码', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:resetPwd', 8, 1, 1, NOW(), NULL, NULL),
+(1019, '分配角色', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:user:updateRole', 9, 1, 1, NOW(), NULL, NULL),
+
+(1030, '角色管理', 1000, 2, '/system/role', 'SystemRole', 'system/role/index', NULL, 'user-group', false, false, false, NULL, 2, 1, 1, NOW(), NULL, NULL),
+(1031, '列表', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:list', 1, 1, 1, NOW(), NULL, NULL),
+(1032, '详情', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1033, '新增', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:add', 3, 1, 1, NOW(), NULL, NULL),
+(1034, '修改', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:update', 4, 1, 1, NOW(), NULL, NULL),
+(1035, '删除', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1036, '分配', 1030, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:role:assign', 6, 1, 1, NOW(), NULL, NULL),
+
+(1050, '菜单管理', 1000, 2, '/system/menu', 'SystemMenu', 'system/menu/index', NULL, 'menu', false, false, false, NULL, 3, 1, 1, NOW(), NULL, NULL),
+(1051, '列表', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:list', 1, 1, 1, NOW(), NULL, NULL),
+(1052, '详情', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1053, '新增', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:add', 3, 1, 1, NOW(), NULL, NULL),
+(1054, '修改', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:update', 4, 1, 1, NOW(), NULL, NULL),
+(1055, '删除', 1050, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:menu:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1060, '部门管理', 1000, 2, '/system/dept', 'SystemDept', 'system/dept/index', NULL, 'mind-mapping', false, false, false, NULL, 4, 1, 1, NOW(), NULL, NULL),
+(1061, '列表', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:list', 1, 1, 1, NOW(), NULL, NULL),
+(1062, '详情', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1063, '新增', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:add', 3, 1, 1, NOW(), NULL, NULL),
+(1064, '修改', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:update', 4, 1, 1, NOW(), NULL, NULL),
+(1065, '删除', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1066, '导出', 1060, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dept:export', 6, 1, 1, NOW(), NULL, NULL),
+
+(1070, '字典管理', 1000, 2, '/system/dict', 'SystemDict', 'system/dict/index', NULL, 'bookmark', false, false, false, NULL, 5, 1, 1, NOW(), NULL, NULL),
+(1071, '列表', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:list', 1, 1, 1, NOW(), NULL, NULL),
+(1072, '详情', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1073, '新增', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:add', 3, 1, 1, NOW(), NULL, NULL),
+(1074, '修改', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:update', 4, 1, 1, NOW(), NULL, NULL),
+(1075, '删除', 1070, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1080, '字典项管理', 1000, 2, '/system/dict/item', 'SystemDictItem', 'system/dict/item/index', NULL, 'bookmark', false, false, true, NULL, 5, 1, 1, NOW(), NULL, NULL),
+(1081, '列表', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:list', 1, 1, 1, NOW(), NULL, NULL),
+(1082, '详情', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1083, '新增', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:add', 3, 1, 1, NOW(), NULL, NULL),
+(1084, '修改', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:update', 4, 1, 1, NOW(), NULL, NULL),
+(1085, '删除', 1080, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:dict:item:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1090, '通知公告', 1000, 2, '/system/notice', 'SystemNotice', 'system/notice/index', NULL, 'notification', false, false, false, NULL, 6, 1, 1, NOW(), NULL, NULL),
+(1091, '列表', 1090, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:notice:list', 1, 1, 1, NOW(), NULL, NULL),
+(1092, '详情', 1090, 2, '/system/notice/detail', 'SystemNoticeDetail', 'system/notice/detail/index', NULL, NULL, false, false, true, 'system:notice:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1093, '新增', 1090, 2, '/system/notice/add', 'SystemNoticeAdd', 'system/notice/add/index', NULL, NULL, false, false, true, 'system:notice:add', 3, 1, 1, NOW(), NULL, NULL),
+(1094, '修改', 1090, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:notice:update', 4, 1, 1, NOW(), NULL, NULL),
+(1095, '删除', 1090, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:notice:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1100, '文件管理', 1000, 2, '/system/file', 'SystemFile', 'system/file/index', NULL, 'file', false, false, false, NULL, 7, 1, 1, NOW(), NULL, NULL),
+(1101, '列表', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:list', 1, 1, 1, NOW(), NULL, NULL),
+(1102, '详情', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1103, '上传', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:upload', 3, 1, 1, NOW(), NULL, NULL),
+(1104, '修改', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:update', 4, 1, 1, NOW(), NULL, NULL),
+(1105, '删除', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:delete', 5, 1, 1, NOW(), NULL, NULL),
+(1106, '下载', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:download', 6, 1, 1, NOW(), NULL, NULL),
+
+(1110, '存储管理', 1000, 2, '/system/storage', 'SystemStorage', 'system/storage/index', NULL, 'storage', false, false, false, NULL, 8, 1, 1, NOW(), NULL, NULL),
+(1111, '列表', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:list', 1, 1, 1, NOW(), NULL, NULL),
+(1112, '详情', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:detail', 2, 1, 1, NOW(), NULL, NULL),
+(1113, '新增', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:add', 3, 1, 1, NOW(), NULL, NULL),
+(1114, '修改', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:update', 4, 1, 1, NOW(), NULL, NULL),
+(1115, '删除', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:delete', 5, 1, 1, NOW(), NULL, NULL),
+
+(1190, '系统配置', 1000, 2, '/system/config', 'SystemConfig', 'system/config/index', NULL, 'config', false, false, false, NULL, 999, 1, 1, NOW(), NULL, NULL),
+(1191, '查看', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:list', 1, 1, 1, NOW(), NULL, NULL),
+(1192, '修改', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:update', 2, 1, 1, NOW(), NULL, NULL),
+(1193, '重置', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:reset', 3, 1, 1, NOW(), NULL, NULL),
+
+(2000, '系统监控', 0, 1, '/monitor', 'Monitor', 'Layout', '/monitor/online', 'computer', false, false, false, NULL, 2, 1, 1, NOW(), NULL, NULL),
+(2010, '在线用户', 2000, 2, '/monitor/online', 'MonitorOnline', 'monitor/online/index', NULL, 'user', false, false, false, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(2011, '列表', 2010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:online:list', 1, 1, 1, NOW(), NULL, NULL),
+(2012, '强退', 2010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:online:kickout', 2, 1, 1, NOW(), NULL, NULL),
+
+(2020, '系统日志', 2000, 2, '/monitor/log', 'MonitorLog', 'monitor/log/index', NULL, 'history', false, false, false, NULL, 2, 1, 1, NOW(), NULL, NULL),
+(2021, '列表', 2020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:log:list', 1, 1, 1, NOW(), NULL, NULL),
+(2022, '详情', 2020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:log:detail', 2, 1, 1, NOW(), NULL, NULL),
+(2023, '导出', 2020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'monitor:log:export', 3, 1, 1, NOW(), NULL, NULL);
+
+-- 初始化默认部门
+INSERT INTO "sys_dept"
+("id", "name", "parent_id", "ancestors", "description", "sort", "status", "is_system", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1, 'Xxx科技有限公司', 0, '0', '系统初始部门', 1, 1, true, 1, NOW(), NULL, NULL),
+(547887852587843590, '天津总部', 1, '0,1', NULL, 1, 1, false, 1, NOW(), NULL, NULL),
+(547888008188133385, '研发部', 547887852587843590, '0,1,547887852587843590', NULL, 1, 1, false, 1, NOW(), NULL, NULL),
+(547888460711591948, 'UI部', 547887852587843590, '0,1,547887852587843590', NULL, 2, 1, false, 1, NOW(), NULL, NULL),
+(547888483713155087, '测试部', 547887852587843590, '0,1,547887852587843590', NULL, 3, 1, false, 1, NOW(), NULL, NULL),
+(547888505959743506, '运维部', 547887852587843590, '0,1,547887852587843590', NULL, 4, 1, false, 1, NOW(), NULL, NULL),
+(547888556819873814, '研发一组', 547888008188133385, '0,1,547887852587843590,547888008188133385', NULL, 1, 1, false, 1, NOW(), NULL, NULL),
+(547888580614160409, '研发二组', 547888008188133385, '0,1,547887852587843590,547888008188133385', NULL, 2, 2, false, 1, NOW(), NULL, NULL);
+
+-- 初始化默认角色
+INSERT INTO "sys_role"
+("id", "name", "code", "data_scope", "description", "sort", "is_system", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1, '系统管理员', 'admin', 1, '系统初始角色', 1, true, 1, NOW(), NULL, NULL),
+(547888897925840928, '测试人员', 'test', 5, NULL, 2, false, 1, NOW(), NULL, NULL);
+
+-- 初始化默认用户:admin/admin123;test/test123
+INSERT INTO "sys_user"
+("id", "username", "nickname", "password", "gender", "email", "phone", "avatar", "description", "status", "is_system", "pwd_reset_time", "dept_id", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1, 'admin', '系统管理员', '{bcrypt}$2a$10$4jGwK2BMJ7FgVR.mgwGodey8.xR8FLoU1XSXpxJ9nZQt.pufhasSa', 1, '42190c6c5639d2ca4edb4150a35e058559ccf8270361a23745a2fd285a273c28', '5bda89a4609a65546422ea56bfe5eab4', NULL, '系统初始用户', 1, true, NOW(), 1, 1, NOW(), NULL, NULL),
+(547889293968801831, 'test', '测试员', '{bcrypt}$2a$10$xAsoeMJ.jc/kSxhviLAg7.j2iFrhi6yYAdniNdjLiIUWU/BRZl2Ti', 2, NULL, NULL, NULL, NULL, 1, false, NOW(), 547888483713155087, 1, NOW(), NULL, NULL);
+
+-- 初始化默认参数
+INSERT INTO "sys_option"
+("id", "category", "name", "code", "value", "default_value", "description", "update_user", "update_time")
+VALUES
+(1, 'SITE', '系统标题', 'SITE_TITLE', NULL, 'ContiNew Admin', '用于显示登录页面的系统标题。', NULL, NULL),
+(2, 'SITE', '系统描述', 'SITE_DESCRIPTION', NULL, '持续迭代优化的前后端分离中后台管理系统框架', NULL, NULL, NULL),
+(3, 'SITE', '版权信息', 'SITE_COPYRIGHT', NULL, 'Copyright © 2022 - present ContiNew Admin 版权所有', '用于显示登录页面的底部版权信息。', NULL, NULL),
+(4, 'SITE', '备案号', 'SITE_BEIAN', NULL, '津ICP备2022005864号-3', 'ICP备案号', NULL, NULL),
+(5, 'SITE', 'favicon', 'SITE_FAVICON', NULL, '/favicon.ico', '用于显示浏览器地址栏的系统LOGO。', NULL, NULL),
+(6, 'SITE', '系统LOGO', 'SITE_LOGO', NULL, '/logo.svg', '用于显示登录页面的系统LOGO。', NULL, NULL),
+(7, 'PASSWORD', '登录密码错误锁定账号的次数', 'PASSWORD_ERROR_LOCK_COUNT', NULL, '5', '取值范围为 0-10(0 表示不锁定)。', NULL, NULL),
+(8, 'PASSWORD', '登录密码错误锁定账号的时间(min)', 'PASSWORD_ERROR_LOCK_MINUTES', NULL, '5', '取值范围为 1-1440(一天)。', NULL, NULL),
+(9, 'PASSWORD', '密码有效期(天)', 'PASSWORD_EXPIRATION_DAYS', NULL, '0', '取值范围为 0-999(0 表示永久有效)。', NULL, NULL),
+(10, 'PASSWORD', '密码到期提前提示(天)', 'PASSWORD_EXPIRATION_WARNING_DAYS', NULL, '0', '密码到期 N 天前进行提示(0 表示不提示)。', NULL, NULL),
+(11, 'PASSWORD', '密码重复使用次数', 'PASSWORD_REPETITION_TIMES', NULL, '3', '不允许使用最近 N 次密码,取值范围为 3-32。', NULL, NULL),
+(12, 'PASSWORD', '密码最小长度', 'PASSWORD_MIN_LENGTH', NULL, '8', '取值范围为 8-32。', NULL, NULL),
+(13, 'PASSWORD', '密码是否允许包含正反序账号名', 'PASSWORD_ALLOW_CONTAIN_USERNAME', NULL, '1', NULL, NULL, NULL),
+(14, 'PASSWORD', '密码是否必须包含特殊字符', 'PASSWORD_REQUIRE_SYMBOLS', NULL, '0', NULL, NULL, NULL),
+(15, 'MAIL', '发送协议', 'MAIL_PROTOCOL', NULL, 'smtp', NULL, NULL, NULL),
+(16, 'MAIL', '服务器地址', 'MAIL_HOST', NULL, 'smtp.126.com', NULL, NULL, NULL),
+(17, 'MAIL', '服务器端口', 'MAIL_PORT', NULL, '465', NULL, NULL, NULL),
+(18, 'MAIL', '用户名', 'MAIL_USERNAME', NULL, 'charles7c@126.com', NULL, NULL, NULL),
+(19, 'MAIL', '密码', 'MAIL_PASSWORD', NULL, NULL, NULL, NULL, NULL),
+(20, 'MAIL', '是否启用SSL', 'MAIL_SSL_ENABLED', NULL, '1', NULL, NULL, NULL),
+(21, 'MAIL', 'SSL端口', 'MAIL_SSL_PORT', NULL, '465', NULL, NULL, NULL),
+(22, 'LOGIN', '是否启用验证码', 'LOGIN_CAPTCHA_ENABLED', NULL, '1', '是否启用验证码(1:是;0:否)', NULL, NULL);
+
+-- 初始化默认字典
+INSERT INTO "sys_dict"
+("id", "name", "code", "description", "is_system", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1, '公告类型', 'notice_type', NULL, true, 1, NOW(), NULL, NULL),
+(2, '消息类型', 'message_type', NULL, true, 1, NOW(), NULL, NULL);
+
+INSERT INTO "sys_dict_item"
+("id", "label", "value", "color", "sort", "description", "status", "dict_id", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1, '通知', '1', 'blue', 1, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(2, '活动', '2', 'orangered', 2, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(3, '安全消息', '1', 'blue', 1, NULL, 1, 2, 1, NOW(), NULL, NULL),
+(4, '活动消息', '2', 'orangered', 2, NULL, 1, 2, 1, NOW(), NULL, NULL);
+
+-- 初始化默认用户和角色关联数据
+INSERT INTO "sys_user_role"
+("user_id", "role_id")
+VALUES
+(1, 1),
+(547889293968801831, 547888897925840928);
+
+-- 初始化默认角色和菜单关联数据
+INSERT INTO "sys_role_menu"
+("role_id", "menu_id")
+VALUES
+(547888897925840928, 1000),
+(547888897925840928, 1010),
+(547888897925840928, 1011),
+(547888897925840928, 1012),
+(547888897925840928, 1013),
+(547888897925840928, 1014);
+
+-- 初始化默认角色和部门关联数据
+INSERT INTO "sys_role_dept" ("role_id", "dept_id") VALUES (547888897925840928, 547888483713155087);
+
+-- 初始化默认存储
+INSERT INTO "sys_storage"
+("id", "name", "code", "type", "access_key", "secret_key", "endpoint", "bucket_name", "domain", "description", "is_default", "sort", "status", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(1, '开发环境', 'local_dev', 2, NULL, NULL, NULL, 'C:/continew-admin/data/file/', 'http://localhost:8000/file', '本地存储', true, 1, 1, 1, NOW(), NULL, NULL),
+(2, '生产环境', 'local_prod', 2, NULL, NULL, NULL, '../data/file/', 'http://api.continew.top/file', '本地存储', false, 2, 2, 1, NOW(), NULL, NULL);

+ 492 - 0
continew-appapi/src/main/resources/db/changelog/postgresql/main_table.sql

@@ -0,0 +1,492 @@
+-- liquibase formatted sql
+
+-- changeset Charles7c:1
+-- comment 初始化表结构
+CREATE TABLE IF NOT EXISTS "sys_menu" (
+    "id"          int8         NOT NULL,
+    "title"       varchar(30)  NOT NULL,
+    "parent_id"   int8         NOT NULL DEFAULT 0,
+    "type"        int2         NOT NULL DEFAULT 1,
+    "path"        varchar(255) DEFAULT NULL,
+    "name"        varchar(50)  DEFAULT NULL,
+    "component"   varchar(255) DEFAULT NULL,
+    "redirect"    varchar(255) DEFAULT NULL,
+    "icon"        varchar(50)  DEFAULT NULL,
+    "is_external" bool         DEFAULT false,
+    "is_cache"    bool         DEFAULT false,
+    "is_hidden"   bool         DEFAULT false,
+    "permission"  varchar(100) DEFAULT NULL,
+    "sort"        int4         NOT NULL DEFAULT 999,
+    "status"      int2         NOT NULL DEFAULT 1,
+    "create_user" int8         NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    "update_user" int8         DEFAULT NULL,
+    "update_time" timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_menu_parent_id"   ON "sys_menu" ("parent_id");
+CREATE INDEX "idx_menu_create_user" ON "sys_menu" ("create_user");
+CREATE INDEX "idx_menu_update_user" ON "sys_menu" ("update_user");
+CREATE UNIQUE INDEX "uk_menu_title_parent_id" ON "sys_menu" ("title", "parent_id");
+COMMENT ON COLUMN "sys_menu"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_menu"."title"       IS '标题';
+COMMENT ON COLUMN "sys_menu"."parent_id"   IS '上级菜单ID';
+COMMENT ON COLUMN "sys_menu"."type"        IS '类型(1:目录;2:菜单;3:按钮)';
+COMMENT ON COLUMN "sys_menu"."path"        IS '路由地址';
+COMMENT ON COLUMN "sys_menu"."name"        IS '组件名称';
+COMMENT ON COLUMN "sys_menu"."component"   IS '组件路径';
+COMMENT ON COLUMN "sys_menu"."redirect"    IS '重定向地址';
+COMMENT ON COLUMN "sys_menu"."icon"        IS '图标';
+COMMENT ON COLUMN "sys_menu"."is_external" IS '是否外链';
+COMMENT ON COLUMN "sys_menu"."is_cache"    IS '是否缓存';
+COMMENT ON COLUMN "sys_menu"."is_hidden"   IS '是否隐藏';
+COMMENT ON COLUMN "sys_menu"."permission"  IS '权限标识';
+COMMENT ON COLUMN "sys_menu"."sort"        IS '排序';
+COMMENT ON COLUMN "sys_menu"."status"      IS '状态(1:启用;2:禁用)';
+COMMENT ON COLUMN "sys_menu"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_menu"."create_time" IS '创建时间';
+COMMENT ON COLUMN "sys_menu"."update_user" IS '修改人';
+COMMENT ON COLUMN "sys_menu"."update_time" IS '修改时间';
+COMMENT ON TABLE  "sys_menu"               IS '菜单表';
+
+CREATE TABLE IF NOT EXISTS "sys_dept" (
+    "id"          int8         NOT NULL,
+    "name"        varchar(30)  NOT NULL,
+    "parent_id"   int8         NOT NULL DEFAULT 0,
+    "ancestors"   varchar(512) NOT NULL DEFAULT '',
+    "description" varchar(200) DEFAULT NULL,
+    "sort"        int4         NOT NULL DEFAULT 999,
+    "status"      int2         NOT NULL DEFAULT 1,
+    "is_system"   bool         NOT NULL DEFAULT false,
+    "create_user" int8         NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    "update_user" int8         DEFAULT NULL,
+    "update_time" timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_dept_parent_id"   ON "sys_dept" ("parent_id");
+CREATE INDEX "idx_dept_create_user" ON "sys_dept" ("create_user");
+CREATE INDEX "idx_dept_update_user" ON "sys_dept" ("update_user");
+CREATE UNIQUE INDEX "uk_dept_name_parent_id" ON "sys_dept" ("name", "parent_id");
+COMMENT ON COLUMN "sys_dept"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_dept"."name"        IS '名称';
+COMMENT ON COLUMN "sys_dept"."parent_id"   IS '上级部门ID';
+COMMENT ON COLUMN "sys_dept"."ancestors"   IS '祖级列表';
+COMMENT ON COLUMN "sys_dept"."description" IS '描述';
+COMMENT ON COLUMN "sys_dept"."sort"        IS '排序';
+COMMENT ON COLUMN "sys_dept"."status"      IS '状态(1:启用;2:禁用)';
+COMMENT ON COLUMN "sys_dept"."is_system"   IS '是否为系统内置数据';
+COMMENT ON COLUMN "sys_dept"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_dept"."create_time" IS '创建时间';
+COMMENT ON COLUMN "sys_dept"."update_user" IS '修改人';
+COMMENT ON COLUMN "sys_dept"."update_time" IS '修改时间';
+COMMENT ON TABLE  "sys_dept"               IS '部门表';
+
+CREATE TABLE IF NOT EXISTS "sys_role" (
+    "id"                  int8         NOT NULL,
+    "name"                varchar(30)  NOT NULL,
+    "code"                varchar(30)  NOT NULL,
+    "data_scope"          int2         NOT NULL DEFAULT 4,
+    "description"         varchar(200) DEFAULT NULL,
+    "sort"                int4         NOT NULL DEFAULT 999,
+    "is_system"           bool         NOT NULL DEFAULT false,
+    "menu_check_strictly" bool DEFAULT false,
+    "dept_check_strictly" bool DEFAULT false,
+    "create_user"         int8         NOT NULL,
+    "create_time"         timestamp    NOT NULL,
+    "update_user"         int8         DEFAULT NULL,
+    "update_time"         timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_role_name"  ON "sys_role" ("name");
+CREATE UNIQUE INDEX "uk_role_code"  ON "sys_role" ("code");
+CREATE INDEX "idx_role_create_user" ON "sys_role" ("create_user");
+CREATE INDEX "idx_role_update_user" ON "sys_role" ("update_user");
+COMMENT ON COLUMN "sys_role"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_role"."name"        IS '名称';
+COMMENT ON COLUMN "sys_role"."code"        IS '编码';
+COMMENT ON COLUMN "sys_role"."data_scope"  IS '数据权限(1:全部数据权限;2:本部门及以下数据权限;3:本部门数据权限;4:仅本人数据权限;5:自定义数据权限)';
+COMMENT ON COLUMN "sys_role"."description" IS '描述';
+COMMENT ON COLUMN "sys_role"."sort"        IS '排序';
+COMMENT ON COLUMN "sys_role"."is_system"   IS '是否为系统内置数据';
+COMMENT ON COLUMN "sys_role"."menu_check_strictly" IS '菜单选择是否父子节点关联';
+COMMENT ON COLUMN "sys_role"."dept_check_strictly" IS '部门选择是否父子节点关联';
+COMMENT ON COLUMN "sys_role"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_role"."create_time" IS '创建时间';
+COMMENT ON COLUMN "sys_role"."update_user" IS '修改人';
+COMMENT ON COLUMN "sys_role"."update_time" IS '修改时间';
+COMMENT ON TABLE  "sys_role"               IS '角色表';
+
+CREATE TABLE IF NOT EXISTS "sys_user" (
+    "id"             int8         NOT NULL,
+    "username"       varchar(64)  NOT NULL,
+    "nickname"       varchar(30)  NOT NULL,
+    "password"       varchar(255) DEFAULT NULL,
+    "gender"         int2         NOT NULL DEFAULT 0,
+    "email"          varchar(255) DEFAULT NULL,
+    "phone"          varchar(255) DEFAULT NULL,
+    "avatar"         text         DEFAULT NULL,
+    "description"    varchar(200) DEFAULT NULL,
+    "status"         int2         NOT NULL DEFAULT 1,
+    "is_system"      bool         NOT NULL DEFAULT false,
+    "pwd_reset_time" timestamp    DEFAULT NULL,
+    "dept_id"        int8         NOT NULL,
+    "create_user"    int8         DEFAULT NULL,
+    "create_time"    timestamp    NOT NULL,
+    "update_user"    int8         DEFAULT NULL,
+    "update_time"    timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_user_username" ON "sys_user" ("username");
+CREATE UNIQUE INDEX "uk_user_email"    ON "sys_user" ("email");
+CREATE UNIQUE INDEX "uk_user_phone"    ON "sys_user" ("phone");
+CREATE INDEX "idx_user_dept_id"        ON "sys_user" ("dept_id");
+CREATE INDEX "idx_user_create_user"    ON "sys_user" ("create_user");
+CREATE INDEX "idx_user_update_user"    ON "sys_user" ("update_user");
+COMMENT ON COLUMN "sys_user"."id"             IS 'ID';
+COMMENT ON COLUMN "sys_user"."username"       IS '用户名';
+COMMENT ON COLUMN "sys_user"."nickname"       IS '昵称';
+COMMENT ON COLUMN "sys_user"."password"       IS '密码';
+COMMENT ON COLUMN "sys_user"."gender"         IS '性别(0:未知;1:男;2:女)';
+COMMENT ON COLUMN "sys_user"."email"          IS '邮箱';
+COMMENT ON COLUMN "sys_user"."phone"          IS '手机号码';
+COMMENT ON COLUMN "sys_user"."avatar"         IS '头像';
+COMMENT ON COLUMN "sys_user"."description"    IS '描述';
+COMMENT ON COLUMN "sys_user"."status"         IS '状态(1:启用;2:禁用)';
+COMMENT ON COLUMN "sys_user"."is_system"      IS '是否为系统内置数据';
+COMMENT ON COLUMN "sys_user"."pwd_reset_time" IS '最后一次修改密码时间';
+COMMENT ON COLUMN "sys_user"."dept_id"        IS '部门ID';
+COMMENT ON COLUMN "sys_user"."create_user"    IS '创建人';
+COMMENT ON COLUMN "sys_user"."create_time"    IS '创建时间';
+COMMENT ON COLUMN "sys_user"."update_user"    IS '修改人';
+COMMENT ON COLUMN "sys_user"."update_time"    IS '修改时间';
+COMMENT ON TABLE  "sys_user"                  IS '用户表';
+
+CREATE TABLE IF NOT EXISTS "sys_user_password_history" (
+    "id"          int8         NOT NULL,
+    "user_id"     int8         NOT NULL,
+    "password"    varchar(255) NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_uph_user_id" ON "sys_user_password_history" ("user_id");
+COMMENT ON COLUMN "sys_user_password_history"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_user_password_history"."user_id"     IS '用户ID';
+COMMENT ON COLUMN "sys_user_password_history"."password"    IS '密码';
+COMMENT ON COLUMN "sys_user_password_history"."create_time" IS '创建时间';
+COMMENT ON TABLE  "sys_user_password_history"               IS '用户历史密码表';
+
+CREATE TABLE IF NOT EXISTS "sys_user_social" (
+    "id"              int8         NOT NULL,
+    "source"          varchar(255) NOT NULL,
+    "open_id"         varchar(255) NOT NULL,
+    "user_id"         int8         NOT NULL,
+    "meta_json"       text         DEFAULT NULL,
+    "last_login_time" timestamp    DEFAULT NULL,
+    "create_time"     timestamp    NOT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_user_source_open_id" ON "sys_user_social" ("source", "open_id");
+COMMENT ON COLUMN "sys_user_social"."id"              IS 'ID';
+COMMENT ON COLUMN "sys_user_social"."source"          IS '来源';
+COMMENT ON COLUMN "sys_user_social"."open_id"         IS '开放ID';
+COMMENT ON COLUMN "sys_user_social"."user_id"         IS '用户ID';
+COMMENT ON COLUMN "sys_user_social"."meta_json"       IS '附加信息';
+COMMENT ON COLUMN "sys_user_social"."last_login_time" IS '最后登录时间';
+COMMENT ON COLUMN "sys_user_social"."create_time"     IS '创建时间';
+COMMENT ON TABLE  "sys_user_social"                   IS '用户社会化关联表';
+
+CREATE TABLE IF NOT EXISTS "sys_user_role" (
+    "user_id" int8 NOT NULL,
+    "role_id" int8 NOT NULL,
+    PRIMARY KEY ("user_id", "role_id")
+);
+COMMENT ON COLUMN "sys_user_role"."user_id" IS '用户ID';
+COMMENT ON COLUMN "sys_user_role"."role_id" IS '角色ID';
+COMMENT ON TABLE  "sys_user_role"           IS '用户和角色关联表';
+
+CREATE TABLE IF NOT EXISTS "sys_role_menu" (
+    "role_id" int8 NOT NULL,
+    "menu_id" int8 NOT NULL,
+    PRIMARY KEY ("role_id", "menu_id")
+);
+COMMENT ON COLUMN "sys_role_menu"."role_id" IS '角色ID';
+COMMENT ON COLUMN "sys_role_menu"."menu_id" IS '菜单ID';
+COMMENT ON TABLE  "sys_role_menu"           IS '角色和菜单关联表';
+
+CREATE TABLE IF NOT EXISTS "sys_role_dept" (
+    "role_id" int8 NOT NULL,
+    "dept_id" int8 NOT NULL,
+    PRIMARY KEY ("role_id", "dept_id")
+);
+COMMENT ON COLUMN "sys_role_dept"."role_id" IS '角色ID';
+COMMENT ON COLUMN "sys_role_dept"."dept_id" IS '部门ID';
+COMMENT ON TABLE  "sys_role_dept"           IS '角色和部门关联表';
+
+CREATE TABLE IF NOT EXISTS "sys_option" (
+    "id"            int8         NOT NULL,
+    "category"      varchar(50)  NOT NULL,
+    "name"          varchar(50)  NOT NULL,
+    "code"          varchar(100) NOT NULL,
+    "value"         text         DEFAULT NULL,
+    "default_value" text         DEFAULT NULL,
+    "description"   varchar(200) DEFAULT NULL,
+    "update_user"   int8         DEFAULT NULL,
+    "update_time"   timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_option_category_code" ON "sys_option" ("category", "code");
+COMMENT ON COLUMN "sys_option"."id"            IS 'ID';
+COMMENT ON COLUMN "sys_option"."category"      IS '类别';
+COMMENT ON COLUMN "sys_option"."name"          IS '名称';
+COMMENT ON COLUMN "sys_option"."code"          IS '键';
+COMMENT ON COLUMN "sys_option"."value"         IS '值';
+COMMENT ON COLUMN "sys_option"."default_value" IS '默认值';
+COMMENT ON COLUMN "sys_option"."description"   IS '描述';
+COMMENT ON COLUMN "sys_option"."update_user"   IS '修改人';
+COMMENT ON COLUMN "sys_option"."update_time"   IS '修改时间';
+COMMENT ON TABLE  "sys_option"                 IS '参数表';
+
+CREATE TABLE IF NOT EXISTS "sys_dict" (
+    "id"          int8         NOT NULL,
+    "name"        varchar(30)  NOT NULL,
+    "code"        varchar(30)  NOT NULL,
+    "description" varchar(200) DEFAULT NULL,
+    "is_system"   bool         NOT NULL DEFAULT false,
+    "create_user" int8         NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    "update_user" int8         DEFAULT NULL,
+    "update_time" timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_dict_name" ON "sys_dict" ("name");
+CREATE UNIQUE INDEX "uk_dict_code" ON "sys_dict" ("code");
+COMMENT ON COLUMN "sys_dict"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_dict"."name"        IS '名称';
+COMMENT ON COLUMN "sys_dict"."code"        IS '编码';
+COMMENT ON COLUMN "sys_dict"."description" IS '描述';
+COMMENT ON COLUMN "sys_dict"."is_system"   IS '是否为系统内置数据';
+COMMENT ON COLUMN "sys_dict"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_dict"."create_time" IS '创建时间';
+COMMENT ON COLUMN "sys_dict"."update_user" IS '修改人';
+COMMENT ON COLUMN "sys_dict"."update_time" IS '修改时间';
+COMMENT ON TABLE  "sys_dict"               IS '字典表';
+
+CREATE TABLE IF NOT EXISTS "sys_dict_item" (
+    "id"          int8         NOT NULL,
+    "label"       varchar(30)  NOT NULL,
+    "value"       varchar(30)  NOT NULL,
+    "color"       varchar(30)  DEFAULT NULL,
+    "sort"        int4         NOT NULL DEFAULT 999,
+    "description" varchar(200) DEFAULT NULL,
+    "status"      int2         NOT NULL DEFAULT 1,
+    "dict_id"     int8         NOT NULL,
+    "create_user" int8         NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    "update_user" int8         DEFAULT NULL,
+    "update_time" timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_dict_item_value_dict_id" ON "sys_dict_item" ("value", "dict_id");
+CREATE INDEX "idx_dict_item_dict_id"     ON "sys_dict_item" ("dict_id");
+CREATE INDEX "idx_dict_item_create_user" ON "sys_dict_item" ("create_user");
+CREATE INDEX "idx_dict_item_update_user" ON "sys_dict_item" ("update_user");
+COMMENT ON COLUMN "sys_dict_item"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_dict_item"."label"       IS '标签';
+COMMENT ON COLUMN "sys_dict_item"."value"       IS '值';
+COMMENT ON COLUMN "sys_dict_item"."color"       IS '标签颜色';
+COMMENT ON COLUMN "sys_dict_item"."sort"        IS '排序';
+COMMENT ON COLUMN "sys_dict_item"."description" IS '描述';
+COMMENT ON COLUMN "sys_dict_item"."status"      IS '状态(1:启用;2:禁用)';
+COMMENT ON COLUMN "sys_dict_item"."dict_id"     IS '字典ID';
+COMMENT ON COLUMN "sys_dict_item"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_dict_item"."create_time" IS '创建时间';
+COMMENT ON COLUMN "sys_dict_item"."update_user" IS '修改人';
+COMMENT ON COLUMN "sys_dict_item"."update_time" IS '修改时间';
+COMMENT ON TABLE  "sys_dict_item"               IS '字典项表';
+
+CREATE TABLE IF NOT EXISTS "sys_log" (
+    "id"               int8         NOT NULL,
+    "trace_id"         varchar(255) DEFAULT NULL,
+    "description"      varchar(255) NOT NULL,
+    "module"           varchar(50)  NOT NULL,
+    "request_url"      varchar(512) NOT NULL,
+    "request_method"   varchar(10)  NOT NULL,
+    "request_headers"  text         DEFAULT NULL,
+    "request_body"     text         DEFAULT NULL,
+    "status_code"      int4         NOT NULL,
+    "response_headers" text         DEFAULT NULL,
+    "response_body"    text         DEFAULT NULL,
+    "time_taken"       int8         NOT NULL,
+    "ip"               varchar(100) DEFAULT NULL,
+    "address"          varchar(255) DEFAULT NULL,
+    "browser"          varchar(100) DEFAULT NULL,
+    "os"               varchar(100) DEFAULT NULL,
+    "status"           int2         NOT NULL DEFAULT 1,
+    "error_msg"        text         DEFAULT NULL,
+    "create_user"      int8         DEFAULT NULL,
+    "create_time"      timestamp    NOT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_log_module"      ON "sys_log" ("module");
+CREATE INDEX "idx_log_ip"          ON "sys_log" ("ip");
+CREATE INDEX "idx_log_address"     ON "sys_log" ("address");
+CREATE INDEX "idx_log_create_time" ON "sys_log" ("create_time");
+COMMENT ON COLUMN "sys_log"."id"               IS 'ID';
+COMMENT ON COLUMN "sys_log"."trace_id"         IS '链路ID';
+COMMENT ON COLUMN "sys_log"."description"      IS '日志描述';
+COMMENT ON COLUMN "sys_log"."module"           IS '所属模块';
+COMMENT ON COLUMN "sys_log"."request_url"      IS '请求URL';
+COMMENT ON COLUMN "sys_log"."request_method"   IS '请求方式';
+COMMENT ON COLUMN "sys_log"."request_headers"  IS '请求头';
+COMMENT ON COLUMN "sys_log"."request_body"     IS '请求体';
+COMMENT ON COLUMN "sys_log"."status_code"      IS '状态码';
+COMMENT ON COLUMN "sys_log"."response_headers" IS '响应头';
+COMMENT ON COLUMN "sys_log"."response_body"    IS '响应体';
+COMMENT ON COLUMN "sys_log"."time_taken"       IS '耗时(ms)';
+COMMENT ON COLUMN "sys_log"."ip"               IS 'IP';
+COMMENT ON COLUMN "sys_log"."address"          IS 'IP归属地';
+COMMENT ON COLUMN "sys_log"."browser"          IS '浏览器';
+COMMENT ON COLUMN "sys_log"."os"               IS '操作系统';
+COMMENT ON COLUMN "sys_log"."status"           IS '状态(1:成功;2:失败)';
+COMMENT ON COLUMN "sys_log"."error_msg"        IS '错误信息';
+COMMENT ON COLUMN "sys_log"."create_user"      IS '创建人';
+COMMENT ON COLUMN "sys_log"."create_time"      IS '创建时间';
+COMMENT ON TABLE  "sys_log"                    IS '系统日志表';
+
+CREATE TABLE IF NOT EXISTS "sys_message" (
+    "id"          int8         NOT NULL,
+    "title"       varchar(50)  NOT NULL,
+    "content"     varchar(255) DEFAULT NULL,
+    "type"        int2         NOT NULL DEFAULT 1,
+    "create_user" int8         DEFAULT NULL,
+    "create_time" timestamp    NOT NULL,
+    PRIMARY KEY ("id")
+);
+COMMENT ON COLUMN "sys_message"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_message"."title"       IS '标题';
+COMMENT ON COLUMN "sys_message"."content"     IS '内容';
+COMMENT ON COLUMN "sys_message"."type"        IS '类型(1:系统消息)';
+COMMENT ON COLUMN "sys_message"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_message"."create_time" IS '创建时间';
+COMMENT ON TABLE  "sys_message"               IS '消息表';
+
+CREATE TABLE IF NOT EXISTS "sys_message_user" (
+    "message_id" int8      NOT NULL,
+    "user_id"    int8      NOT NULL,
+    "is_read"    bool      NOT NULL DEFAULT false,
+    "read_time"  timestamp DEFAULT NULL,
+    PRIMARY KEY ("message_id", "user_id")
+);
+COMMENT ON COLUMN "sys_message_user"."message_id" IS '消息ID';
+COMMENT ON COLUMN "sys_message_user"."user_id"    IS '用户ID';
+COMMENT ON COLUMN "sys_message_user"."is_read"    IS '是否已读';
+COMMENT ON COLUMN "sys_message_user"."read_time"  IS '读取时间';
+COMMENT ON TABLE  "sys_message_user"              IS '消息和用户关联表';
+
+CREATE TABLE IF NOT EXISTS "sys_notice" (
+    "id"             int8         NOT NULL,
+    "title"          varchar(150) NOT NULL,
+    "content"        text         NOT NULL,
+    "type"           varchar(30)  NOT NULL,
+    "effective_time" timestamp    DEFAULT NULL,
+    "terminate_time" timestamp    DEFAULT NULL,
+    "sort"           int4         NOT NULL DEFAULT 999,
+    "create_user"    int8         NOT NULL,
+    "create_time"    timestamp    NOT NULL,
+    "update_user"    int8         DEFAULT NULL,
+    "update_time"    timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_notice_create_user" ON "sys_notice" ("create_user");
+CREATE INDEX "idx_notice_update_user" ON "sys_notice" ("update_user");
+COMMENT ON COLUMN "sys_notice"."id"             IS 'ID';
+COMMENT ON COLUMN "sys_notice"."title"          IS '标题';
+COMMENT ON COLUMN "sys_notice"."content"        IS '内容';
+COMMENT ON COLUMN "sys_notice"."type"           IS '类型';
+COMMENT ON COLUMN "sys_notice"."effective_time" IS '生效时间';
+COMMENT ON COLUMN "sys_notice"."terminate_time" IS '终止时间';
+COMMENT ON COLUMN "sys_notice"."sort"           IS '排序';
+COMMENT ON COLUMN "sys_notice"."create_user"    IS '创建人';
+COMMENT ON COLUMN "sys_notice"."create_time"    IS '创建时间';
+COMMENT ON COLUMN "sys_notice"."update_user"    IS '修改人';
+COMMENT ON COLUMN "sys_notice"."update_time"    IS '修改时间';
+COMMENT ON TABLE  "sys_notice"                  IS '公告表';
+
+CREATE TABLE IF NOT EXISTS "sys_storage" (
+    "id"          int8         NOT NULL,
+    "name"        varchar(100) NOT NULL,
+    "code"        varchar(30)  NOT NULL,
+    "type"        int2         NOT NULL DEFAULT 1,
+    "access_key"  varchar(255) DEFAULT NULL,
+    "secret_key"  varchar(255) DEFAULT NULL,
+    "endpoint"    varchar(255) DEFAULT NULL,
+    "bucket_name" varchar(255) DEFAULT NULL,
+    "domain"      varchar(255) NOT NULL DEFAULT '',
+    "description" varchar(200) DEFAULT NULL,
+    "is_default"  bool         NOT NULL DEFAULT false,
+    "sort"        int4         NOT NULL DEFAULT 999,
+    "status"      int2         NOT NULL DEFAULT 1,
+    "create_user" int8         NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    "update_user" int8         DEFAULT NULL,
+    "update_time" timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_storage_code"  ON "sys_storage" ("code");
+CREATE INDEX "idx_storage_create_user" ON "sys_storage" ("create_user");
+CREATE INDEX "idx_storage_update_user" ON "sys_storage" ("update_user");
+COMMENT ON COLUMN "sys_storage"."id"          IS 'ID';
+COMMENT ON COLUMN "sys_storage"."name"        IS '名称';
+COMMENT ON COLUMN "sys_storage"."code"        IS '编码';
+COMMENT ON COLUMN "sys_storage"."type"        IS '类型(1:兼容S3协议存储;2:本地存储)';
+COMMENT ON COLUMN "sys_storage"."access_key"  IS 'Access Key(访问密钥)';
+COMMENT ON COLUMN "sys_storage"."secret_key"  IS 'Secret Key(私有密钥)';
+COMMENT ON COLUMN "sys_storage"."endpoint"    IS 'Endpoint(终端节点)';
+COMMENT ON COLUMN "sys_storage"."bucket_name" IS '桶名称';
+COMMENT ON COLUMN "sys_storage"."domain"      IS '域名';
+COMMENT ON COLUMN "sys_storage"."description" IS '描述';
+COMMENT ON COLUMN "sys_storage"."is_default"  IS '是否为默认存储';
+COMMENT ON COLUMN "sys_storage"."sort"        IS '排序';
+COMMENT ON COLUMN "sys_storage"."status"      IS '状态(1:启用;2:禁用)';
+COMMENT ON COLUMN "sys_storage"."create_user" IS '创建人';
+COMMENT ON COLUMN "sys_storage"."create_time" IS '创建时间';
+COMMENT ON COLUMN "sys_storage"."update_user" IS '修改人';
+COMMENT ON COLUMN "sys_storage"."update_time" IS '修改时间';
+COMMENT ON TABLE  "sys_storage"               IS '存储表';
+
+CREATE TABLE IF NOT EXISTS "sys_file" (
+    "id"             int8         NOT NULL,
+    "name"           varchar(255) NOT NULL,
+    "size"           int8         NOT NULL,
+    "url"            varchar(512) NOT NULL,
+    "extension"      varchar(100) DEFAULT NULL,
+    "thumbnail_size" int8         DEFAULT NULL,
+    "thumbnail_url"  varchar(512) DEFAULT NULL,
+    "type"           int2         NOT NULL DEFAULT 1,
+    "storage_id"     int8         NOT NULL,
+    "create_user"    int8         NOT NULL,
+    "create_time"    timestamp    NOT NULL,
+    "update_user"    int8         NOT NULL,
+    "update_time"    timestamp    NOT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_file_url"  ON "sys_file" ("url");
+CREATE INDEX "idx_file_type" ON "sys_file" ("type");
+CREATE INDEX "idx_file_create_user" ON "sys_file" ("create_user");
+CREATE INDEX "idx_file_update_user" ON "sys_file" ("update_user");
+COMMENT ON COLUMN "sys_file"."id"             IS 'ID';
+COMMENT ON COLUMN "sys_file"."name"           IS '名称';
+COMMENT ON COLUMN "sys_file"."size"           IS '大小(字节)';
+COMMENT ON COLUMN "sys_file"."url"            IS 'URL';
+COMMENT ON COLUMN "sys_file"."extension"      IS '扩展名';
+COMMENT ON COLUMN "sys_file"."thumbnail_size" IS '缩略图大小(字节)';
+COMMENT ON COLUMN "sys_file"."thumbnail_url"  IS '缩略图URL';
+COMMENT ON COLUMN "sys_file"."type"           IS '类型(1:其他;2:图片;3:文档;4:视频;5:音频)';
+COMMENT ON COLUMN "sys_file"."storage_id"     IS '存储ID';
+COMMENT ON COLUMN "sys_file"."create_user"    IS '创建人';
+COMMENT ON COLUMN "sys_file"."create_time"    IS '创建时间';
+COMMENT ON COLUMN "sys_file"."update_user"    IS '修改人';
+COMMENT ON COLUMN "sys_file"."update_time"    IS '修改时间';
+COMMENT ON TABLE  "sys_file"                  IS '文件表';
+

+ 78 - 0
continew-appapi/src/main/resources/db/changelog/postgresql/plugin/plugin_generator.sql

@@ -0,0 +1,78 @@
+-- liquibase formatted sql
+
+-- changeset charles7c:1
+-- comment 初始化代码生成插件
+-- 初始化表结构
+CREATE TABLE IF NOT EXISTS "gen_config" (
+    "table_name"    varchar(64)  NOT NULL,
+    "module_name"   varchar(60)  NOT NULL,
+    "package_name"  varchar(60)  NOT NULL,
+    "business_name" varchar(50)  NOT NULL,
+    "author"        varchar(100) NOT NULL,
+    "table_prefix"  varchar(20)  DEFAULT NULL,
+    "is_override"   bool         NOT NULL DEFAULT false,
+    "create_time"   timestamp    NOT NULL,
+    "update_time"   timestamp    DEFAULT NULL,
+    PRIMARY KEY ("table_name")
+);
+COMMENT ON COLUMN "gen_config"."table_name"    IS '表名称';
+COMMENT ON COLUMN "gen_config"."module_name"   IS '模块名称';
+COMMENT ON COLUMN "gen_config"."package_name"  IS '包名称';
+COMMENT ON COLUMN "gen_config"."business_name" IS '业务名称';
+COMMENT ON COLUMN "gen_config"."author"        IS '作者';
+COMMENT ON COLUMN "gen_config"."table_prefix"  IS '表前缀';
+COMMENT ON COLUMN "gen_config"."is_override"   IS '是否覆盖';
+COMMENT ON COLUMN "gen_config"."create_time"   IS '创建时间';
+COMMENT ON COLUMN "gen_config"."update_time"   IS '修改时间';
+COMMENT ON TABLE  "gen_config"                 IS '生成配置表';
+
+CREATE TABLE IF NOT EXISTS "gen_field_config" (
+    "id"            int8         NOT NULL,
+    "table_name"    varchar(64)  NOT NULL,
+    "column_name"   varchar(64)  NOT NULL,
+    "column_type"   varchar(25)  NOT NULL,
+    "column_size"   int8         DEFAULT NULL,
+    "field_name"    varchar(64)  NOT NULL,
+    "field_type"    varchar(25)  NOT NULL,
+    "field_sort"    int4         NOT NULL DEFAULT 999,
+    "comment"       varchar(512) DEFAULT NULL,
+    "is_required"   bool         NOT NULL DEFAULT true,
+    "show_in_list"  bool         NOT NULL DEFAULT true,
+    "show_in_form"  bool         NOT NULL DEFAULT true,
+    "show_in_query" bool         NOT NULL DEFAULT true,
+    "form_type"     int2         DEFAULT NULL,
+    "query_type"    int2         DEFAULT NULL,
+    "dict_code"     varchar(30)  DEFAULT NULL,
+    "create_time"   timestamp    NOT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE INDEX "idx_field_config_table_name" ON "gen_field_config" ("table_name");
+COMMENT ON COLUMN "gen_field_config"."id"            IS 'ID';
+COMMENT ON COLUMN "gen_field_config"."table_name"    IS '表名称';
+COMMENT ON COLUMN "gen_field_config"."column_name"   IS '列名称';
+COMMENT ON COLUMN "gen_field_config"."column_type"   IS '列类型';
+COMMENT ON COLUMN "gen_field_config"."column_size"   IS '列大小';
+COMMENT ON COLUMN "gen_field_config"."field_name"    IS '字段名称';
+COMMENT ON COLUMN "gen_field_config"."field_type"    IS '字段类型';
+COMMENT ON COLUMN "gen_field_config"."field_sort"    IS '字段排序';
+COMMENT ON COLUMN "gen_field_config"."comment"       IS '注释';
+COMMENT ON COLUMN "gen_field_config"."is_required"   IS '是否必填';
+COMMENT ON COLUMN "gen_field_config"."show_in_list"  IS '是否在列表中显示';
+COMMENT ON COLUMN "gen_field_config"."show_in_form"  IS '是否在表单中显示';
+COMMENT ON COLUMN "gen_field_config"."show_in_query" IS '是否在查询中显示';
+COMMENT ON COLUMN "gen_field_config"."form_type"     IS '表单类型';
+COMMENT ON COLUMN "gen_field_config"."query_type"    IS '查询方式';
+COMMENT ON COLUMN "gen_field_config"."dict_code"     IS '字典编码';
+COMMENT ON COLUMN "gen_field_config"."create_time"   IS '创建时间';
+COMMENT ON TABLE  "gen_field_config"                 IS '字段配置表';
+
+-- 初始化默认菜单
+INSERT INTO "sys_menu"
+("id", "title", "parent_id", "type", "path", "name", "component", "redirect", "icon", "is_external", "is_cache", "is_hidden", "permission", "sort", "status", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(9000, '代码生成', 0, 1, '/code', 'Code', 'Layout', '/code/generator', 'code-release-managment', false, false, false, NULL, 9, 1, 1, NOW(), NULL, NULL),
+(9010, '代码生成', 9000, 2, '/code/generator', 'CodeGenerator', 'code/generator/index', NULL, 'code', false, false, false, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(9011, '列表', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:list', 1, 1, 1, NOW(), NULL, NULL),
+(9012, '配置', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:config', 2, 1, 1, NOW(), NULL, NULL),
+(9013, '预览', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:preview', 3, 1, 1, NOW(), NULL, NULL),
+(9014, '生成', 9010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'code:generator:generate', 4, 1, 1, NOW(), NULL, NULL);

+ 49 - 0
continew-appapi/src/main/resources/db/changelog/postgresql/plugin/plugin_open.sql

@@ -0,0 +1,49 @@
+-- liquibase formatted sql
+
+-- changeset chengzi:1
+-- comment 初始化能力开放插件
+-- 初始化表结构
+CREATE TABLE IF NOT EXISTS "sys_app" (
+    "id"          int8         NOT NULL,
+    "name"        varchar(100) NOT NULL,
+    "access_key"  varchar(255) NOT NULL,
+    "secret_key"  varchar(255) NOT NULL,
+    "expire_time" timestamp    DEFAULT NULL,
+    "description" varchar(200) DEFAULT NULL,
+    "status"      int2         NOT NULL DEFAULT 1,
+    "create_user" int8         NOT NULL,
+    "create_time" timestamp    NOT NULL,
+    "update_user" int8         DEFAULT NULL,
+    "update_time" timestamp    DEFAULT NULL,
+    PRIMARY KEY ("id")
+);
+CREATE UNIQUE INDEX "uk_app_access_key" ON "sys_app" ("access_key");
+CREATE INDEX "idx_app_create_user" ON "sys_app" ("create_user");
+CREATE INDEX "idx_app_update_user" ON "sys_app" ("update_user");
+COMMENT ON COLUMN "sys_app"."id"              IS 'ID';
+COMMENT ON COLUMN "sys_app"."name"            IS '名称';
+COMMENT ON COLUMN "sys_app"."access_key"      IS 'Access Key(访问密钥)';
+COMMENT ON COLUMN "sys_app"."secret_key"      IS 'Secret Key(私有密钥)';
+COMMENT ON COLUMN "sys_app"."expire_time"     IS '失效时间';
+COMMENT ON COLUMN "sys_app"."description"     IS '描述';
+COMMENT ON COLUMN "sys_app"."status"          IS '状态(1:启用;2:禁用)';
+COMMENT ON COLUMN "sys_app"."create_user"     IS '创建人';
+COMMENT ON COLUMN "sys_app"."create_time"     IS '创建时间';
+COMMENT ON COLUMN "sys_app"."update_user"     IS '修改人';
+COMMENT ON COLUMN "sys_app"."update_time"     IS '修改时间';
+COMMENT ON TABLE  "sys_app"                   IS '应用表';
+
+-- 初始化默认菜单
+INSERT INTO "sys_menu"
+("id", "title", "parent_id", "type", "path", "name", "component", "redirect", "icon", "is_external", "is_cache", "is_hidden", "permission", "sort", "status", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(7000, '能力开放', 0, 1, '/open', 'Open', 'Layout', '/open/app', 'expand', false, false, false, NULL, 7, 1, 1, NOW(), NULL, NULL),
+(7010, '应用管理', 7000, 2, '/open/app', 'OpenApp', 'open/app/index', NULL, 'common', false, false, false, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(7011, '列表', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:list', 1, 1, 1, NOW(), NULL, NULL),
+(7012, '详情', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:detail', 2, 1, 1, NOW(), NULL, NULL),
+(7013, '新增', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:add', 3, 1, 1, NOW(), NULL, NULL),
+(7014, '修改', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:update', 4, 1, 1, NOW(), NULL, NULL),
+(7015, '删除', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:delete', 5, 1, 1, NOW(), NULL, NULL),
+(7016, '导出', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:export', 6, 1, 1, NOW(), NULL, NULL),
+(7017, '查看密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:secret', 7, 1, 1, NOW(), NULL, NULL),
+(7018, '重置密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:resetSecret', 8, 1, 1, NOW(), NULL, NULL);

+ 21 - 0
continew-appapi/src/main/resources/db/changelog/postgresql/plugin/plugin_schedule.sql

@@ -0,0 +1,21 @@
+-- liquibase formatted sql
+
+-- changeset kai:1
+-- comment 初始化任务调度插件
+-- 初始化默认菜单
+INSERT INTO "sys_menu"
+("id", "title", "parent_id", "type", "path", "name", "component", "redirect", "icon", "is_external", "is_cache", "is_hidden", "permission", "sort", "status", "create_user", "create_time", "update_user", "update_time")
+VALUES
+(3000, '任务调度', 0, 1, '/schedule', 'Schedule', 'Layout', '/schedule/job', 'schedule', false, false, false, NULL, 3, 1, 1, NOW(), NULL, NULL),
+(3010, '任务管理', 3000, 2, '/schedule/job', 'ScheduleJob', 'schedule/job/index', NULL, 'select-all', false, false, false, NULL, 1, 1, 1, NOW(), NULL, NULL),
+(3011, '列表', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:list', 1, 1, 1, NOW(), NULL, NULL),
+(3012, '详情', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:detail', 2, 1, 1, NOW(), NULL, NULL),
+(3013, '新增', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:add', 3, 1, 1, NOW(), NULL, NULL),
+(3014, '修改', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:update', 4, 1, 1, NOW(), NULL, NULL),
+(3015, '删除', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:delete', 5, 1, 1, NOW(), NULL, NULL),
+(3016, '执行', 3010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:trigger', 6, 1, 1, NOW(), NULL, NULL),
+(3020, '任务日志', 3000, 2, '/schedule/log', 'ScheduleLog', 'schedule/log/index', NULL, 'find-replace', false, false, false, NULL, 2, 1, 1, NOW(), NULL, NULL),
+(3021, '列表', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:list', 1, 1, 1, NOW(), NULL, NULL),
+(3022, '详情', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:detail', 2, 1, 1, NOW(), NULL, NULL),
+(3023, '停止', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:stop', 3, 1, 1, NOW(), NULL, NULL),
+(3024, '重试', 3020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:retry', 4, 1, 1, NOW(), NULL, NULL);

+ 88 - 0
continew-appapi/src/main/resources/logback-spring.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 日志级别从低到高分为 TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为 WARN,则低于 WARN 的信息都不会输出 -->
+<!-- scan:当此属性设置为 true 时,配置文档如果发生改变,将会被重新加载,默认值为 true -->
+<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
+       当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟。 -->
+<!-- debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态。默认 false。 -->
+<configuration debug="false" scan="true" scanPeriod="30 seconds">
+
+    <!-- 关闭 Logback 的状态监听器(通过更换默认状态监听器实现) -->
+    <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
+
+    <!-- 应用名 -->
+    <springProperty name="APP_NAME" source="spring.application.name" scope="context"/>
+    <!-- 保存路径 -->
+    <property name="LOG_PATH" value="${LOG_PATH:-./logs}"/>
+    <!-- 字符集 -->
+    <property name="LOG_CHARSET" value="utf-8"/>
+    <!-- 格式化输出:%d 表示日期;%thread 表示线程名;%-5level:级别从左显示 5 个字符宽度;%msg:日志消息;%n 是换行符 -->
+    <!-- 控制台输出格式(带颜色) -->
+    <property name="CONSOLE_LOG_PATTERN" value="%red(%d{yyyy-MM-dd HH:mm:ss}) %highlight(%-5level) %green([%thread]) %boldMagenta(%logger{50}) - %msg%n"/>
+    <!-- 文件输出格式 -->
+    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{50} - %msg%n"/>
+    <!-- 单个日志文件大小上限 -->
+    <property name="FILE_MAX_SIZE" value="20MB"/>
+
+    <!-- 输出日志到控制台 -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>${LOG_CHARSET}</charset>
+        </encoder>
+    </appender>
+
+    <!-- 输出日志到控制台(不带颜色) -->
+    <appender name="CONSOLE_PROD" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+            <charset>${LOG_CHARSET}</charset>
+        </encoder>
+    </appender>
+
+    <!-- 输出日志到文件 -->
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/${APP_NAME}.log</file>
+        <!-- 滚动策略:基于文件大小和时间归档日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 日志文件的路径及文件名 -->
+            <fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/${APP_NAME}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <!-- 日志文件大小(超过指定大小后,会切分新文件,从索引 0 开始计数,例如:app.2024-01-01.1.log.gz ) -->
+            <maxFileSize>${FILE_MAX_SIZE}</maxFileSize>
+            <!-- 日志保留天数 -->
+            <maxHistory>${FILE_MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+            <charset>${LOG_CHARSET}</charset>
+        </encoder>
+    </appender>
+
+    <!-- 输出日志到文件(异步) -->
+    <appender name="ASYNC_FILE" class="com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender">
+        <!-- 不丢失日志,默认:如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能,默认:256 -->
+        <queueSize>512</queueSize>
+        <!-- 添加附加的 appender,最多只能添加一个 -->
+        <appender-ref ref="FILE"/>
+    </appender>
+
+    <!-- 开发环境:只打印到控制台 -->
+    <springProfile name="dev">
+        <!-- 如果配置的日志等级,和 application.yml 中的日志等级配置重叠,application.yml 配置优先级高 -->
+        <root level="INFO">
+            <appender-ref ref="CONSOLE"/>
+        </root>
+    </springProfile>
+
+    <!-- 生产环境:打印到控制台并输出到文件 -->
+    <springProfile name="prod">
+        <root level="INFO">
+            <appender-ref ref="CONSOLE_PROD"/>
+            <appender-ref ref="ASYNC_FILE"/>
+        </root>
+        <!-- 日志保留天数(根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存的日志不少于六个月,并且进行网络多机备份。) -->
+        <property name="FILE_MAX_HISTORY" value="180"/>
+    </springProfile>
+</configuration>

+ 13 - 0
continew-appapi/src/test/java/top/continew/admin/ContinewAppapiApplicationTests.java

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

+ 33 - 0
continew-module-coin-core/pom.xml

@@ -0,0 +1,33 @@
+<?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>top.continew</groupId>
+        <artifactId>continew-admin</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <groupId>top.continew</groupId>
+    <artifactId>continew-module-coin-core</artifactId>
+    <version>${revision}</version>
+    <name>continew-module-coin-core</name>
+    <description>continew-module-coin-core</description>
+
+    <properties>
+        <!-- 项目版本号 -->
+        <revision>3.4.0</revision>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>top.continew</groupId>
+            <artifactId>continew-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.5.8</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 16 - 0
continew-module-coin-core/src/main/java/top/continew/admin/user/mapper/TgUserMapper.java

@@ -0,0 +1,16 @@
+package top.continew.admin.user.mapper;
+
+import top.continew.admin.user.model.entity.TgUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * tg用户 Mapper 接口
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+public interface TgUserMapper extends BaseMapper<TgUser> {
+
+}

+ 258 - 0
continew-module-coin-core/src/main/java/top/continew/admin/user/model/entity/TgUser.java

@@ -0,0 +1,258 @@
+package top.continew.admin.user.model.entity;
+
+import cn.hutool.log.Log;
+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 com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * tg用户
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+@Getter
+@Setter
+@TableName("b_tg_user")
+@Builder
+public class TgUser extends Model<TgUser> {
+
+    /**
+     * id
+     */
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    /**
+     * tg小程序id
+     */
+    @TableField("tg_id")
+    private String tgId;
+
+    /**
+     * tg账号
+     */
+    @TableField("tg_account")
+    private String tgAccount;
+
+    /**
+     * 名
+     */
+    @TableField("first_name")
+    private String firstName;
+
+    /**
+     * 姓
+     */
+    @TableField("last_name")
+    private String lastName;
+
+    /**
+     * 昵称
+     */
+    @TableField("nickname")
+    private String nickname;
+
+    /**
+     * 真实姓名
+     */
+    @TableField("real_name")
+    private String realName;
+
+    /**
+     * 头像
+     */
+    @TableField("avatar")
+    private String avatar;
+
+    /**
+     * 用户的语言的编码
+     */
+    @TableField("language_code")
+    private String languageCode;
+
+    /**
+     * 钱包地址
+     */
+    @TableField("wallet_address")
+    private String walletAddress;
+
+    /**
+     * 年限
+     */
+    @TableField("age_limit")
+    private Integer ageLimit;
+
+    /**
+     * 是否老用户
+     */
+    @TableField("old_user")
+    private Integer oldUser;
+
+    /**
+     * 选择的语言
+     */
+    @TableField("check_language")
+    private String checkLanguage;
+
+    /**
+     * 最后登录的IP
+     */
+    @TableField("login_ip")
+    private String loginIp;
+
+    /**
+     * 最后登录时间
+     */
+    @TableField("login_time")
+    private LocalDateTime loginTime;
+
+    /**
+     * ip转换实际地址
+     */
+    @TableField("ip_address_convert")
+    private String ipAddressConvert;
+
+    /**
+     * 是否禁用: [0=否, 1=是]
+     */
+    @TableField("disable_flag")
+    private Integer disableFlag;
+
+    /**
+     * 注册渠道: [1-微信小程序 2-微信公众号 3-手机H5 4-电脑PC 5-苹果APP 6-安卓APP]
+     */
+    @TableField("channel")
+    private Integer channel;
+
+    /**
+     * 用户授权telegram登录后的唯一标识
+     */
+    @TableField("login_telegram")
+    private String loginTelegram;
+
+    /**
+     * 币账户进入的唯一标识地址
+     */
+    @TableField("coin_address")
+    private String coinAddress;
+
+    /**
+     * 用户密码
+     */
+    @TableField("password")
+    private String password;
+
+    /**
+     * 用户电话
+     */
+    @TableField("mobile")
+    private String mobile;
+
+    /**
+     * 用户性别: [1=男, 2=女]
+     */
+    @TableField("sex")
+    private String sex;
+
+    /**
+     * 邀请码
+     */
+    @TableField("invite_code")
+    private String inviteCode;
+
+    /**
+     * 介绍人_id
+     */
+    @TableField("referrer_id")
+    private String referrerId;
+
+    /**
+     * 0单独可奖励1已经奖励
+     */
+    @TableField("invite_reward")
+    private Integer inviteReward;
+
+    /**
+     * 是否是新注册用户: [1-是, 0-否]
+     */
+    @TableField("new_user_flag")
+    private Integer newUserFlag;
+
+    /**
+     * 历史钥匙数量
+     */
+    @TableField("history_key")
+    private Integer historyKey;
+
+    /**
+     * 钥匙数量
+     */
+    @TableField("key_num")
+    private Integer keyNum;
+
+    /**
+     * 空投数量
+     */
+    @TableField("airdrop_coin")
+    private Integer airdropCoin;
+
+    /**
+     * 金币余额
+     */
+    @TableField("gold_coin_amount")
+    private BigDecimal goldCoinAmount;
+
+    /**
+     * 金币总数量
+     */
+    @TableField("gold_coin_total_his")
+    private BigDecimal goldCoinTotalHis;
+
+    /**
+     * 该用户每10s生产的金币数量
+     */
+    @TableField("development_gold_coin")
+    private Integer developmentGoldCoin;
+
+    /**
+     * 在线时间 单位秒
+     */
+    @TableField("online_time")
+    private Integer onlineTime;
+
+    /**
+     * 用户余额
+     */
+    @TableField("user_amount")
+    private BigDecimal userAmount;
+
+    /**
+     * 创建时间
+     */
+    @TableField("created_time")
+    private LocalDateTime createdTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("updated_time")
+    private LocalDateTime updatedTime;
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+}

+ 39 - 0
continew-module-coin-core/src/main/java/top/continew/admin/user/model/req/AppLoginReq.java

@@ -0,0 +1,39 @@
+package top.continew.admin.user.model.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Schema(description = "app端登录参数")
+@Data
+public class AppLoginReq implements Serializable {
+    @Schema(description = "", example = "true")
+    private boolean allowsWriteToPm;
+
+    @Schema(description = "名", example = "st")
+    private String firstName;
+    @Schema(description = "姓", example = "prpr")
+    private String lastName;
+
+    @Schema(description = "tg小程序用户id", example = "7678353292")
+    @NotBlank(message = "tg小程序用户id不能为空")
+    private String id;
+
+    @Schema(description = "语言编码", example = "zh-hans")
+    private String languageCode;
+
+    @Schema(description = "头像地址", example = "https%3A%2F%2Ft.me%2Fi%2Fuserpic%2F320%2F8CkFbucM04aA4Q1DYkGM_CSPabAPuL9e24ywa-bD4uLSil5_TxdNx_KrHD-SnS6v.svg")
+    private String photoUrl;
+
+    @Schema(description = "tg用户名", example = "baptistUnilamellar")
+    private String username;
+
+
+    @Schema(description = "年限", example = "1")
+    private String age_limit;
+
+    @Schema(description = "邀请码")
+    private String share_code;
+}

+ 12 - 0
continew-module-coin-core/src/main/java/top/continew/admin/user/model/resp/AppLoginResp.java

@@ -0,0 +1,12 @@
+package top.continew.admin.user.model.resp;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@Builder
+public class AppLoginResp implements Serializable {
+    private String token;
+}

+ 27 - 0
continew-module-coin-core/src/main/java/top/continew/admin/user/service/ITgUserService.java

@@ -0,0 +1,27 @@
+package top.continew.admin.user.service;
+
+import cn.dev33.satoken.stp.SaTokenInfo;
+import top.continew.admin.user.model.entity.TgUser;
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.user.model.req.AppLoginReq;
+import top.continew.admin.user.model.resp.AppLoginResp;
+
+/**
+ * <p>
+ * tg用户 服务类
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+public interface ITgUserService extends IService<TgUser> {
+    /**
+     * tg小程序用户登录
+     *
+     * @param appLoginReq
+     * @return
+     */
+    SaTokenInfo tgLogin(AppLoginReq appLoginReq);
+
+
+}

+ 102 - 0
continew-module-coin-core/src/main/java/top/continew/admin/user/service/Impl/TgUserServiceImpl.java

@@ -0,0 +1,102 @@
+package top.continew.admin.user.service.Impl;
+
+import cn.dev33.satoken.stp.SaLoginConfig;
+import cn.dev33.satoken.stp.SaTokenInfo;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import jakarta.annotation.Resource;
+import me.ahoo.cosid.IdGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
+import top.continew.admin.common.context.RoleContext;
+import top.continew.admin.common.context.UserContext;
+import top.continew.admin.common.context.UserContextHolder;
+import top.continew.admin.common.context.UserExtraContext;
+import top.continew.admin.user.model.entity.TgUser;
+import top.continew.admin.user.mapper.TgUserMapper;
+import top.continew.admin.user.model.req.AppLoginReq;
+import top.continew.admin.user.model.resp.AppLoginResp;
+import top.continew.admin.user.service.ITgUserService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import top.continew.admin.utils.InviteCodeGenerator;
+import top.continew.starter.cache.redisson.util.RedisUtils;
+import top.continew.starter.core.validation.CheckUtils;
+import top.continew.starter.web.util.SpringWebUtils;
+
+import java.time.LocalDateTime;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * <p>
+ * tg用户 服务实现类
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+@Service
+public class TgUserServiceImpl extends ServiceImpl<TgUserMapper, TgUser> implements ITgUserService {
+
+
+    @Override
+    public SaTokenInfo tgLogin(AppLoginReq loginReq) {
+        LambdaQueryWrapper<TgUser> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(TgUser::getTgId, loginReq.getId());
+        TgUser user = getOne(queryWrapper);
+        if (ObjUtil.isNull(user)) {
+            user = registerToSys(loginReq);
+        }
+        return this.login(user, loginReq);
+    }
+
+    /**
+     * 注册用户到系统中
+     *
+     * @param loginReq
+     * @return
+     */
+    private TgUser registerToSys(AppLoginReq loginReq) {
+        TgUser user = TgUser.builder()
+                .tgAccount(loginReq.getUsername())
+                .tgId(loginReq.getId())
+                .avatar(loginReq.getPhotoUrl())
+                .firstName(loginReq.getFirstName())
+                .lastName(loginReq.getLastName())
+                //注册时指定用户的唯一邀请码
+                .inviteCode(InviteCodeGenerator.generateInviteCode())
+                .languageCode(loginReq.getLanguageCode())
+                .ageLimit(Integer.parseInt(loginReq.getAge_limit()))
+                .createdTime(LocalDateTime.now())
+                .updatedTime(LocalDateTime.now())
+                .build();
+        if (StrUtil.isNotBlank(loginReq.getShare_code())) {
+            //如邀请码不为空 则写入邀请人信息
+            LambdaQueryWrapper<TgUser> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(TgUser::getInviteCode, user.getId());
+            TgUser inviteUser = getOne(queryWrapper);
+            if (ObjUtil.isNotNull(inviteUser)) {
+                user.setReferrerId(String.valueOf(inviteUser.getId()));
+            }
+        }
+        this.save(user);
+        return user;
+    }
+
+    private SaTokenInfo login(TgUser user, AppLoginReq loginReq) {
+        Long userId = user.getId();
+        UserContext userContext = new UserContext();
+        userContext.setId(userId);
+        userContext.setUsername(user.getTgAccount());
+        // 登录并缓存用户信息
+        StpUtil.login(userId, SaLoginConfig.setExtraData(BeanUtil
+                .beanToMap(new UserExtraContext(SpringWebUtils.getRequest()))));
+        UserContextHolder.setContext(userContext);
+        return StpUtil.getTokenInfo();
+    }
+
+
+}

+ 27 - 0
continew-module-coin-core/src/main/java/top/continew/admin/utils/InviteCodeGenerator.java

@@ -0,0 +1,27 @@
+package top.continew.admin.utils;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+public class InviteCodeGenerator {
+    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    private static final int CODE_LENGTH = 8; // 邀请码长度
+
+    public static String generateInviteCode() {
+        Random random = new SecureRandom();
+        StringBuilder code = new StringBuilder();
+
+        for (int i = 0; i < CODE_LENGTH; i++) {
+            int index = random.nextInt(CHARACTERS.length());
+            code.append(CHARACTERS.charAt(index));
+        }
+        return code.toString();
+    }
+
+    public static void main(String[] args) {
+        // 生成5个邀请码示例
+        for (int i = 0; i < 5; i++) {
+            System.out.println("邀请码 " + (i + 1) + ": " + generateInviteCode());
+        }
+    }
+}

+ 185 - 0
continew-module-coin-core/src/main/java/top/continew/admin/utils/MyGenerator.java

@@ -0,0 +1,185 @@
+package top.continew.admin.utils;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.OutputFile;
+import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+import com.baomidou.mybatisplus.generator.fill.Column;
+import org.apache.commons.lang3.ClassUtils;
+
+import java.io.File;
+import java.sql.Types;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author zoutao
+ * @date 2023/09/13
+ */
+public class MyGenerator {
+
+    //数据库连接信息
+    static String url = "jdbc:mysql://192.168.241.129:3306/continew?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai",
+            username = "continew",
+            password = "continew123456";
+
+    // 设置作者
+    static String author = "xudm";
+    // 指定输出目录
+    static String outputDir = "D:\\DevelopmentSpace\\MyWorkSpace\\OutPutDir\\coin-core";
+
+    // 设置父包名
+    static String parent = "top.continew.admin";
+    // 表前缀
+    static String[] tablePrefix = {"t_", "b_"};
+    // 字段前缀
+    static String[] fieldPrefix = {"f_"};
+    //自动填充字段
+    static Column[] fillColumns = new Column[]{
+            new Column("f_updated_time", FieldFill.INSERT_UPDATE),
+            new Column("f_created_time", FieldFill.INSERT),
+            new Column("f_corp_id", FieldFill.INSERT),
+            new Column("f_corp_name", FieldFill.INSERT),
+            new Column("f_created_user_business_id", FieldFill.INSERT),
+            new Column("f_created_user_name", FieldFill.INSERT),
+            new Column("f_updated_user_business_id", FieldFill.INSERT_UPDATE),
+            new Column("f_updated_user_name", FieldFill.INSERT_UPDATE),
+            new Column("f_delete_flag", FieldFill.INSERT),
+            new Column("f_status", FieldFill.INSERT),
+    };
+
+
+    public static void main(String[] args) {
+        // 项目名 例如app  web
+        generatorByBusinessModule("user", new String[]{"b_tg_user"});
+    }
+
+    /**
+     * @param businessModuleName 业务模块名称,可以为空
+     * @param generatorTables    需要生成的表名称
+     */
+    private static void generatorByBusinessModule(String businessModuleName, String[] generatorTables) {
+
+
+        //设置 entity 包名
+        String entityPackageName = businessModuleName + ".model.entity";
+        //设置 controller 包名
+        String controllerPackageName = businessModuleName + ".controller";
+        //设置 service 包名
+        String servicePackageName = businessModuleName + ".service";
+        //设置 serviceImpl 包名
+        String serviceImplPackageName = businessModuleName + ".service.Impl";
+        //设置 mapper 包名
+        String mapperPackageName = businessModuleName + ".mapper";
+
+        // 设置mapperXml生成路径
+        String mapperXmlPath = outputDir + "/mapper/";
+
+        // 设置 service 父类
+        String superServiceName = "com.baomidou.mybatisplus.extension.service.IService";
+        // 设置 serviceImpl 父类
+        String superServiceImplName = "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl";
+
+        FastAutoGenerator.create(url, username, password)
+                .globalConfig(builder -> {
+                    builder.author(author)
+                            .outputDir(outputDir);
+                })
+                .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
+                    int typeCode = metaInfo.getJdbcType().TYPE_CODE;
+                    if (typeCode == Types.SMALLINT) {
+                        // 自定义类型转换
+                        return DbColumnType.INTEGER;
+                    }
+                    if (typeCode == Types.BIGINT) {
+                        return DbColumnType.STRING;
+                    }
+                    if (typeCode == Types.TINYINT) {
+                        return DbColumnType.INTEGER;
+                    }
+                    return typeRegistry.getColumnType(metaInfo);
+
+                }))
+
+                .packageConfig(builder -> {
+                    builder.entity(entityPackageName)
+                            .controller(controllerPackageName)
+                            .mapper(mapperPackageName)
+                            .service(servicePackageName)
+                            .serviceImpl(serviceImplPackageName)
+                            .parent(parent) // 设置父包名
+                            .pathInfo(Collections.singletonMap(OutputFile.xml, mapperXmlPath)); // 设置mapperXml生成路径
+                })
+                .strategyConfig(builder -> {
+
+                    builder.controllerBuilder()
+                            .enableFileOverride()
+                            .enableRestStyle();
+
+                    builder.serviceBuilder()
+                            .enableFileOverride()
+                            .superServiceClass(superServiceName)
+                            .superServiceImplClass(superServiceImplName)
+                            .build();
+
+                    builder.mapperBuilder()
+                            .enableBaseColumnList()
+                            .enableBaseResultMap()
+                            .enableFileOverride();
+                    builder.entityBuilder()
+                            .addTableFills(fillColumns)
+                            .enableFileOverride()
+                            .enableLombok()
+                            .idType(IdType.ASSIGN_ID) // 主键类型,生成策略
+                            .enableTableFieldAnnotation()
+                            .naming(NamingStrategy.underline_to_camel)
+                            .disableSerialVersionUID()
+                            .enableActiveRecord();// 开启 ActiveRecord 模式
+                    builder
+                            .addInclude(generatorTables)
+                            .addTablePrefix(tablePrefix)// 设置过滤表前缀
+                            .addFieldPrefix(fieldPrefix)
+                    ;
+                }).templateEngine(new FreemarkerTemplateEngine())
+                .execute();
+    }
+
+    static class ModuleTableGenerator {
+        public static Map<String, String[]> moduleTablesMap = new HashMap<>();
+
+        static {
+            moduleTablesMap.put("user", new String[]{"t_cmttg_human_role", "t_human_user", "t_test_user", "t_cmttg_user_basic", "t_cmttg_user_business", "t_cmttg_user_business_rel", "t_cmttg_user_platform"});
+            moduleTablesMap.put("role", new String[]{"t_cmttg_role_inc", "t_cmttg_role_type", "t_cmttg_role_type_rel", "t_cmttg_sys_role"});
+
+            moduleTablesMap.put("center", new String[]{"t_human_dept", "t_cmttg_human_org",
+                    "t_human_position", "t_cmttg_sys_base_org", "t_cmttg_sys_base_org_region",
+                    "t_cmttg_sys_base_org_role", "t_cmttg_sys_org", "t_cmttg_sys_org_role"
+            });
+            moduleTablesMap.put("menu", new String[]{"t_cmttg_app_info", "t_cmttg_app_menu", "t_cmttg_role_app_menu", "t_cmttg_role_web_menu", "t_cmttg_user_app_menu", "t_cmttg_user_web_menu", "t_cmttg_web_menu"
+            });
+            moduleTablesMap.put("system", new String[]{"t_cmttg_dict", "t_cmttg_sys_region",
+            });
+        }
+
+
+        private static void getFileTableNames() throws ClassNotFoundException {
+            String moduleName = "system";
+            String path = "C:\\Users\\Administrator\\IdeaProjects\\cmttg\\cmttg-common\\src\\main\\java\\com\\xwtec\\cmttg\\common\\pojo\\" + moduleName;
+
+            String packageName = "com.xwtec.cmttg.common.pojo." + moduleName;
+            File file = new File(path);
+            for (File listFile : file.listFiles()) {
+                String className = packageName + "." + listFile.getName().replace(".java", "");
+                Class<?> aClass = ClassUtils.getClass(className);
+                TableName annotation = aClass.getAnnotation(TableName.class);
+                System.err.print(",\"" + annotation.value() + "\"");
+            }
+        }
+
+    }
+}

+ 51 - 0
continew-module-coin-core/src/main/resources/mapper/TgUserMapper.xml

@@ -0,0 +1,51 @@
+<?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="top.continew.admin.user.mapper.TgUserMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="top.continew.admin.user.model.entity.TgUser">
+        <id column="id" property="id" />
+        <result column="tg_id" property="tgId" />
+        <result column="tg_account" property="tgAccount" />
+        <result column="first_name" property="firstName" />
+        <result column="last_name" property="lastName" />
+        <result column="nickname" property="nickname" />
+        <result column="real_name" property="realName" />
+        <result column="avatar" property="avatar" />
+        <result column="language_code" property="languageCode" />
+        <result column="wallet_address" property="walletAddress" />
+        <result column="age_limit" property="ageLimit" />
+        <result column="old_user" property="oldUser" />
+        <result column="check_language" property="checkLanguage" />
+        <result column="login_ip" property="loginIp" />
+        <result column="login_time" property="loginTime" />
+        <result column="ip_address_convert" property="ipAddressConvert" />
+        <result column="disable_flag" property="disableFlag" />
+        <result column="channel" property="channel" />
+        <result column="login_telegram" property="loginTelegram" />
+        <result column="coin_address" property="coinAddress" />
+        <result column="password" property="password" />
+        <result column="mobile" property="mobile" />
+        <result column="sex" property="sex" />
+        <result column="invite_code" property="inviteCode" />
+        <result column="referrer_id" property="referrerId" />
+        <result column="invite_reward" property="inviteReward" />
+        <result column="new_user_flag" property="newUserFlag" />
+        <result column="history_key" property="historyKey" />
+        <result column="key_num" property="keyNum" />
+        <result column="airdrop_coin" property="airdropCoin" />
+        <result column="gold_coin_amount" property="goldCoinAmount" />
+        <result column="gold_coin_total_his" property="goldCoinTotalHis" />
+        <result column="development_gold_coin" property="developmentGoldCoin" />
+        <result column="online_time" property="onlineTime" />
+        <result column="user_amount" property="userAmount" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, tg_id, tg_account, first_name, last_name, nickname, real_name, avatar, language_code, wallet_address, age_limit, old_user, check_language, login_ip, login_time, ip_address_convert, disable_flag, channel, login_telegram, coin_address, password, mobile, sex, invite_code, referrer_id, invite_reward, new_user_flag, history_key, key_num, airdrop_coin, gold_coin_amount, gold_coin_total_his, development_gold_coin, online_time, user_amount, created_time, updated_time
+    </sql>
+
+</mapper>

+ 16 - 0
continew-module-system/src/main/java/top/continew/admin/business/mapper/TgUserMapper.java

@@ -0,0 +1,16 @@
+package top.continew.admin.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import top.continew.admin.business.model.entity.TgUser;
+
+/**
+ * <p>
+ * tg用户 Mapper 接口
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+public interface TgUserMapper extends BaseMapper<TgUser> {
+
+}

+ 264 - 0
continew-module-system/src/main/java/top/continew/admin/business/model/entity/TgUser.java

@@ -0,0 +1,264 @@
+package top.continew.admin.business.model.entity;
+
+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 com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * tg用户
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+@Getter
+@Setter
+@TableName("b_tg_user")
+@Builder
+public class TgUser extends Model<TgUser> {
+
+    /**
+     * id
+     */
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    /**
+     * tg小程序id
+     */
+    @TableField("tg_id")
+    private String tgId;
+
+    /**
+     * tg账号
+     */
+    @TableField("tg_account")
+    private String tgAccount;
+
+    /**
+     * 名
+     */
+    @TableField("first_name")
+    private String firstName;
+
+    /**
+     * 姓
+     */
+    @TableField("last_name")
+    private String lastName;
+
+    /**
+     * 昵称
+     */
+    @TableField("nickname")
+    private String nickname;
+
+    /**
+     * 真实姓名
+     */
+    @TableField("real_name")
+    private String realName;
+
+    /**
+     * 头像
+     */
+    @TableField("avatar")
+    private String avatar;
+
+    /**
+     * 用户的语言的编码
+     */
+    @TableField("language_code")
+    private String languageCode;
+
+    /**
+     * 钱包地址
+     */
+    @TableField("wallet_address")
+    private String walletAddress;
+
+    /**
+     * 年限
+     */
+    @TableField("age_limit")
+    private Integer ageLimit;
+
+    /**
+     * 是否老用户
+     */
+    @TableField("old_user")
+    private Integer oldUser;
+
+    /**
+     * 选择的语言
+     */
+    @TableField("check_language")
+    private String checkLanguage;
+
+    /**
+     * 最后登录的IP
+     */
+    @TableField("login_ip")
+    private String loginIp;
+
+    /**
+     * 最后登录时间
+     */
+    @TableField("login_time")
+    private LocalDateTime loginTime;
+
+    /**
+     * ip转换实际地址
+     */
+    @TableField("ip_address_convert")
+    private String ipAddressConvert;
+
+    /**
+     * 是否禁用: [0=否, 1=是]
+     */
+    @TableField("disable_flag")
+    private Integer disableFlag;
+
+    /**
+     * 注册渠道: [1-微信小程序 2-微信公众号 3-手机H5 4-电脑PC 5-苹果APP 6-安卓APP]
+     */
+    @TableField("channel")
+    private Integer channel;
+
+
+    /**
+     * 客流途径 1 新增 2 邀请
+     */
+    @TableField("passenger_flow_way")
+    private Integer passengerFlowWay;
+
+    /**
+     * 用户授权telegram登录后的唯一标识
+     */
+    @TableField("login_telegram")
+    private String loginTelegram;
+
+    /**
+     * 币账户进入的唯一标识地址
+     */
+    @TableField("coin_address")
+    private String coinAddress;
+
+    /**
+     * 用户密码
+     */
+    @TableField("password")
+    private String password;
+
+    /**
+     * 用户电话
+     */
+    @TableField("mobile")
+    private String mobile;
+
+    /**
+     * 用户性别: [1=男, 2=女]
+     */
+    @TableField("sex")
+    private String sex;
+
+    /**
+     * 邀请码
+     */
+    @TableField("invite_code")
+    private String inviteCode;
+
+    /**
+     * 介绍人_id
+     */
+    @TableField("referrer_id")
+    private String referrerId;
+
+    /**
+     * 0单独可奖励1已经奖励
+     */
+    @TableField("invite_reward")
+    private Integer inviteReward;
+
+    /**
+     * 是否是新注册用户: [1-是, 0-否]
+     */
+    @TableField("new_user_flag")
+    private Integer newUserFlag;
+
+    /**
+     * 历史钥匙数量
+     */
+    @TableField("history_key")
+    private Integer historyKey;
+
+    /**
+     * 钥匙数量
+     */
+    @TableField("key_num")
+    private Integer keyNum;
+
+    /**
+     * 空投数量
+     */
+    @TableField("airdrop_coin")
+    private Integer airdropCoin;
+
+    /**
+     * 金币余额
+     */
+    @TableField("gold_coin_amount")
+    private BigDecimal goldCoinAmount;
+
+    /**
+     * 金币总数量
+     */
+    @TableField("gold_coin_total_his")
+    private BigDecimal goldCoinTotalHis;
+
+    /**
+     * 该用户每10s生产的金币数量
+     */
+    @TableField("development_gold_coin")
+    private Integer developmentGoldCoin;
+
+    /**
+     * 在线时间 单位秒
+     */
+    @TableField("online_time")
+    private Integer onlineTime;
+
+    /**
+     * 用户余额
+     */
+    @TableField("user_amount")
+    private BigDecimal userAmount;
+
+    /**
+     * 创建时间
+     */
+    @TableField("created_time")
+    private LocalDateTime createdTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("updated_time")
+    private LocalDateTime updatedTime;
+
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+}

+ 29 - 0
continew-module-system/src/main/java/top/continew/admin/business/model/req/TgUserReq.java

@@ -0,0 +1,29 @@
+package top.continew.admin.business.model.req;
+
+import cn.hutool.core.date.DatePattern;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@Schema(description = "tg用户信息查询")
+public class TgUserReq implements Serializable {
+
+    @Schema(description = "用户昵称")
+    private String userName;
+
+    @Schema(description = "注册时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
+    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+    private List<Date> time;
+
+
+    @Schema(description = "当前页码")
+    private int page;
+
+    @Schema(description = "页大小")
+    private int size;
+}

+ 234 - 0
continew-module-system/src/main/java/top/continew/admin/business/model/resp/TgUserResp.java

@@ -0,0 +1,234 @@
+package top.continew.admin.business.model.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@Schema(description = "tg用户信息")
+public class TgUserResp implements Serializable {
+    /**
+     * id
+     */
+    @Schema(description = "主键")
+    private Long id;
+
+    /**
+     * tg小程序id
+     */
+    @Schema(description = "tg小程序id")
+    private String tgId;
+
+    /**
+     * tg账号
+     */
+    @Schema(description = "tg账号")
+    private String tgAccount;
+
+    /**
+     * 名
+     */
+    @Schema(description = "名")
+    private String firstName;
+
+    /**
+     * 姓
+     */
+    @Schema(description = "姓")
+    private String lastName;
+
+    /**
+     * 昵称
+     */
+    @Schema(description = "昵称")
+    private String nickname;
+
+    /**
+     * 真实姓名
+     */
+    @Schema(description = "真实姓名")
+    private String realName;
+
+    /**
+     * 头像
+     */
+    @Schema(description = "头像")
+    private String avatar;
+
+    /**
+     * 用户的语言的编码
+     */
+    @Schema(description = "用户的语言的编码")
+    private String languageCode;
+
+    /**
+     * 钱包地址
+     */
+    @Schema(description = "钱包地址")
+    private String walletAddress;
+
+    /**
+     * 年限
+     */
+    @Schema(description = "年限")
+    private Integer ageLimit;
+
+    /**
+     * 是否老用户
+     */
+    @Schema(description = "是否老用户")
+    private Integer oldUser;
+
+    /**
+     * 选择的语言
+     */
+    @Schema(description = "选择的语言")
+    private String checkLanguage;
+
+    /**
+     * 最后登录的IP
+     */
+    @Schema(description = "最后登录的IP")
+    private String loginIp;
+
+    /**
+     * 最后登录时间
+     */
+    @Schema(description = "最后登录时间")
+    private LocalDateTime loginTime;
+
+    /**
+     * ip转换实际地址
+     */
+    @Schema(description = "ip转换实际地址")
+    private String ipAddressConvert;
+
+    /**
+     * 是否禁用: [0=否, 1=是]
+     */
+    @Schema(description = "否禁用: [0=否, 1=是]")
+    private Integer disableFlag;
+
+    /**
+     * 注册渠道: [1-微信小程序 2-微信公众号 3-手机H5 4-电脑PC 5-苹果APP 6-安卓APP]
+     */
+    @Schema(description = "注册渠道: [1-微信小程序 2-微信公众号 3-手机H5 4-电脑PC 5-苹果APP 6-安卓APP]")
+    private Integer channel;
+
+    /**
+     * 用户授权telegram登录后的唯一标识
+     */
+    @Schema(description = "用户授权telegram登录后的唯一标识")
+    private String loginTelegram;
+
+    /**
+     * 币账户进入的唯一标识地址
+     */
+    @Schema(description = "币账户进入的唯一标识地址")
+    private String coinAddress;
+
+    /**
+     * 用户密码
+     */
+    @Schema(description = "用户密码")
+    private String password;
+
+    /**
+     * 用户电话
+     */
+    @Schema(description = "用户电话")
+    private String mobile;
+
+    /**
+     * 用户性别: [1=男, 2=女]
+     */
+    @Schema(description = "用户性别: [1=男, 2=女]")
+    private String sex;
+
+    /**
+     * 邀请码
+     */
+    @Schema(description = "邀请码")
+    private String inviteCode;
+
+    /**
+     * 介绍人_id
+     */
+    @Schema(description = "介绍人_id")
+    private String referrerId;
+
+    /**
+     * 0单独可奖励1已经奖励
+     */
+    @Schema(description = "0单独可奖励1已经奖励")
+    private Integer inviteReward;
+
+    /**
+     * 是否是新注册用户: [1-是, 0-否]
+     */
+    @Schema(description = "是否是新注册用户: [1-是, 0-否]")
+    private Integer newUserFlag;
+
+    /**
+     * 历史钥匙数量
+     */
+    @Schema(description = "历史钥匙数量")
+    private Integer historyKey;
+
+    /**
+     * 钥匙数量
+     */
+    @Schema(description = "钥匙数量")
+    private Integer keyNum;
+
+    /**
+     * 空投数量
+     */
+    @Schema(description = "空投数量")
+    private Integer airdropCoin;
+
+    /**
+     * 金币余额
+     */
+    @Schema(description = "金币余额")
+    private BigDecimal goldCoinAmount;
+
+    /**
+     * 金币总数量
+     */
+    @Schema(description = "金币总数量")
+    private BigDecimal goldCoinTotalHis;
+
+    /**
+     * 该用户每10s生产的金币数量
+     */
+    @Schema(description = "该用户每10s生产的金币数量")
+    private Integer developmentGoldCoin;
+
+    /**
+     * 在线时间 单位秒
+     */
+    @Schema(description = "在线时间 单位秒")
+    private Integer onlineTime;
+
+    /**
+     * 用户余额
+     */
+    @Schema(description = "用户余额")
+    private BigDecimal userAmount;
+
+    /**
+     * 创建时间
+     */
+    @Schema(description = "创建时间")
+    private LocalDateTime createdTime;
+
+    /**
+     * 更新时间
+     */
+    @Schema(description = "更新时间")
+    private LocalDateTime updatedTime;
+}

+ 27 - 0
continew-module-system/src/main/java/top/continew/admin/business/service/ITgUserService.java

@@ -0,0 +1,27 @@
+package top.continew.admin.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import top.continew.admin.business.model.entity.TgUser;
+import top.continew.admin.business.model.req.TgUserReq;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+
+
+/**
+ * <p>
+ * tg用户 服务类
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+public interface ITgUserService extends IService<TgUser> {
+    /**
+     * tg小程序用户登录
+     *
+     * @param appLoginReq
+     * @return
+     */
+    PageResp<TgUser> pageQuery(TgUserReq appLoginReq);
+
+
+}

+ 86 - 0
continew-module-system/src/main/java/top/continew/admin/business/service/Impl/TgUserServiceImpl.java

@@ -0,0 +1,86 @@
+package top.continew.admin.business.service.Impl;
+
+import cn.dev33.satoken.stp.SaLoginConfig;
+import cn.dev33.satoken.stp.SaTokenInfo;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import top.continew.admin.business.mapper.TgUserMapper;
+import top.continew.admin.business.model.entity.TgUser;
+import top.continew.admin.business.model.req.TgUserReq;
+import top.continew.admin.business.service.ITgUserService;
+import top.continew.admin.common.context.UserContext;
+import top.continew.admin.common.context.UserContextHolder;
+import top.continew.admin.common.context.UserExtraContext;
+import top.continew.starter.data.mp.base.BaseMapper;
+import top.continew.starter.extension.crud.model.resp.PageResp;
+import top.continew.starter.web.util.SpringWebUtils;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * tg用户 服务实现类
+ * </p>
+ *
+ * @author xudm
+ * @since 2024-12-14
+ */
+@Service
+public class TgUserServiceImpl extends ServiceImpl<TgUserMapper, TgUser> implements ITgUserService {
+    @Override
+    public PageResp<TgUser> pageQuery(TgUserReq queryVo) {
+        Page<TgUser> page = new Page<>();
+        page.setCurrent(queryVo.getPage() != 0 ? queryVo.getPage() : 1);
+        page.setSize(queryVo.getSize() != 0 ? queryVo.getSize() : 10);
+
+        LambdaQueryWrapper<TgUser> queryWrapper = new LambdaQueryWrapper<>();
+        String userName = queryVo.getUserName();
+        if (StrUtil.isNotBlank(userName)) {
+            queryWrapper.and(w -> {
+                w.like(StrUtil.isNotBlank(userName), TgUser::getFirstName, userName)
+                        .or()
+                        .like(StrUtil.isNotBlank(userName), TgUser::getLastName, userName)
+                        .or()
+                        .like(StrUtil.isNotBlank(userName), TgUser::getTgAccount, userName);
+            });
+        }
+        // 处理时间范围查询
+        try {
+            List<Date> times = queryVo.getTime();
+            if (CollUtil.isNotEmpty(times) && times.size() == 2) {
+                Date startime = times.get(0);
+                Date endtime = times.get(1);
+
+                LocalDateTime startDateTime = LocalDateTime.ofInstant(startime.toInstant(), ZoneId.systemDefault());
+                queryWrapper.ge(TgUser::getCreatedTime, startDateTime);
+
+                LocalDateTime endDateTime = LocalDateTime.ofInstant(endtime.toInstant(), ZoneId.systemDefault());
+                queryWrapper.le(TgUser::getCreatedTime, endDateTime);
+            }
+
+        } catch (DateTimeParseException e) {
+            throw new RuntimeException("日期格式错误,正确格式为:yyyy-MM-dd HH:mm:ss");
+        }
+
+        queryWrapper.orderByDesc(TgUser::getCreatedTime);
+        page = page(page, queryWrapper);
+        PageResp<TgUser> pageResp = PageResp.build(page, TgUser.class);
+        return pageResp;
+    }
+}

+ 50 - 0
continew-module-system/src/main/resources/mapper/TgUserMapper.xml

@@ -0,0 +1,50 @@
+<?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="top.continew.admin.business.mapper.TgUserMapper">
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="top.continew.admin.business.model.entity.TgUser">
+        <id column="id" property="id"/>
+        <result column="tg_id" property="tgId"/>
+        <result column="tg_account" property="tgAccount"/>
+        <result column="first_name" property="firstName"/>
+        <result column="last_name" property="lastName"/>
+        <result column="nickname" property="nickname"/>
+        <result column="real_name" property="realName"/>
+        <result column="avatar" property="avatar"/>
+        <result column="language_code" property="languageCode"/>
+        <result column="wallet_address" property="walletAddress"/>
+        <result column="age_limit" property="ageLimit"/>
+        <result column="old_user" property="oldUser"/>
+        <result column="check_language" property="checkLanguage"/>
+        <result column="login_ip" property="loginIp"/>
+        <result column="login_time" property="loginTime"/>
+        <result column="ip_address_convert" property="ipAddressConvert"/>
+        <result column="disable_flag" property="disableFlag"/>
+        <result column="channel" property="channel"/>
+        <result column="ppassenger_flow_way" property="passengerFlowWay"/>
+        <result column="login_telegram" property="loginTelegram"/>
+        <result column="coin_address" property="coinAddress"/>
+        <result column="password" property="password"/>
+        <result column="mobile" property="mobile"/>
+        <result column="sex" property="sex"/>
+        <result column="invite_code" property="inviteCode"/>
+        <result column="referrer_id" property="referrerId"/>
+        <result column="invite_reward" property="inviteReward"/>
+        <result column="new_user_flag" property="newUserFlag"/>
+        <result column="history_key" property="historyKey"/>
+        <result column="key_num" property="keyNum"/>
+        <result column="airdrop_coin" property="airdropCoin"/>
+        <result column="gold_coin_amount" property="goldCoinAmount"/>
+        <result column="gold_coin_total_his" property="goldCoinTotalHis"/>
+        <result column="development_gold_coin" property="developmentGoldCoin"/>
+        <result column="online_time" property="onlineTime"/>
+        <result column="user_amount" property="userAmount"/>
+        <result column="created_time" property="createdTime"/>
+        <result column="updated_time" property="updatedTime"/>
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, tg_id, tg_account, first_name, last_name, nickname, real_name, avatar, language_code, wallet_address, age_limit, old_user, check_language, login_ip, login_time, ip_address_convert, disable_flag, channel,passenger_flow_way, login_telegram, coin_address, password, mobile, sex, invite_code, referrer_id, invite_reward, new_user_flag, history_key, key_num, airdrop_coin, gold_coin_amount, gold_coin_total_his, development_gold_coin, online_time, user_amount, created_time, updated_time
+    </sql>
+</mapper>

+ 25 - 0
continew-webapi/src/main/java/top/continew/admin/controller/business/TgUserController.java

@@ -0,0 +1,25 @@
+package top.continew.admin.controller.business;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import top.continew.admin.business.model.entity.TgUser;
+import top.continew.admin.business.model.req.TgUserReq;
+import top.continew.admin.business.service.ITgUserService;
+import top.continew.starter.extension.crud.model.resp.BasePageResp;
+
+@RestController()
+@RequestMapping("/tgUser")
+@AllArgsConstructor
+@Tag(name = "tg用户管理 API")
+public class TgUserController {
+    private final ITgUserService userService;
+
+    @RequestMapping("/getTgUserList")
+    @Operation(summary = "获取tg用户列表", description = "获取tg用户列表")
+    public BasePageResp<TgUser> getTgUserList(TgUserReq req) {
+        return userService.pageQuery(req);
+    }
+}

+ 1 - 1
continew-webapi/src/main/resources/config/application-dev.yml

@@ -268,7 +268,7 @@ avatar:
 
 --- ### Snail Job 配置
 snail-job:
-  enabled: true
+  enabled: false
   # 客户端地址(默认自动获取本机 IP)
   #host: 127.0.0.1
   # 客户端端口(默认:1789)

+ 1 - 1
continew-webapi/src/main/resources/config/application.yml

@@ -225,7 +225,7 @@ auth:
 server:
   servlet:
     # 应用访问路径
-    context-path: /
+    context-path: /web
   ## Undertow 服务器配置
   undertow:
     # HTTP POST 请求内容的大小上限(默认 -1,不限制)

+ 20 - 1
pom.xml

@@ -20,7 +20,9 @@
     <artifactId>continew-admin</artifactId>
     <version>${revision}</version>
     <packaging>pom</packaging>
-    <description>ContiNew Admin(Continue New Admin)持续迭代优化的前后端分离中后台管理系统框架,开箱即用,持续提供舒适的开发体验。</description>
+    <description>ContiNew Admin(Continue New
+        Admin)持续迭代优化的前后端分离中后台管理系统框架,开箱即用,持续提供舒适的开发体验。
+    </description>
     <url>https://github.com/continew-org/continew-admin</url>
 
     <modules>
@@ -29,6 +31,8 @@
         <module>continew-plugin</module>
         <module>continew-common</module>
         <module>continew-extension</module>
+        <module>continew-appapi</module>
+        <module>continew-module-coin-core</module>
     </modules>
 
     <properties>
@@ -80,6 +84,21 @@
                 <artifactId>continew-plugin-generator</artifactId>
                 <version>${revision}</version>
             </dependency>
+
+
+            <!--   app端接口模块         -->
+            <dependency>
+                <groupId>top.continew</groupId>
+                <artifactId>continew-appapi</artifactId>
+                <version>${revision}</version>
+            </dependency>
+
+            <!--   tg机器人核心模块         -->
+            <dependency>
+                <groupId>top.continew</groupId>
+                <artifactId>continew-module-coin-core</artifactId>
+                <version>${revision}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>