diff --git a/src/main/java/com/frontleaves/mastercontrol/config/init/Initial.java b/src/main/java/com/frontleaves/mastercontrol/config/init/Initial.java index 2ccc8f4..61aeb3f 100644 --- a/src/main/java/com/frontleaves/mastercontrol/config/init/Initial.java +++ b/src/main/java/com/frontleaves/mastercontrol/config/init/Initial.java @@ -23,10 +23,17 @@ package com.frontleaves.mastercontrol.config.init; +import com.frontleaves.mastercontrol.constant.SystemConstant; +import com.frontleaves.mastercontrol.dao.InfoDAO; +import com.frontleaves.mastercontrol.dao.RoleDAO; +import com.frontleaves.mastercontrol.dao.TableDAO; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; /** * 系统初始化 @@ -34,19 +41,96 @@ * 该类用于系统初始化; * 该类使用 {@code @Configuration} 注解标记; * + * @author xiao_lfeng * @version v1.0.0 * @since 2024/09/10 - * @author xiao_lfeng */ @Slf4j @Configuration @RequiredArgsConstructor public class Initial { + private final TableDAO tableDAO; + private final InfoDAO infoDAO; + private final RoleDAO roleDAO; + private final JdbcTemplate jdbcTemplate; + private PrepareAlgorithm prepare; @PostConstruct public void init() { log.info("[INIT] 系统初始化"); + log.info("========== Start of Initialization =========="); + //初始化算法 + prepare = new PrepareAlgorithm(tableDAO, infoDAO, roleDAO, jdbcTemplate); + + //进行检查和初始化 + this.initSqlCheck(); + this.initInfoTableCheck(); + this.initGlobalVariableAssignment(); + this.initRole(); + + } + + /** + * 初始化结束 + * + * @return {@link CommandLineRunner} 命令行运行器 + */ + @Bean + public CommandLineRunner initFinal() { + return args -> { + log.info("=========== End of Initialization ==========="); + System.out.print(""" + \u001B[38;5;111m _____ __ __ __ \u001B[32m____ __ _ \s + \u001B[38;5;111m / ___/_____/ /_ ___ ____/ /_ __/ /__ \u001B[32m/ __ \\/ /___ _____ ____ (_)___ ____ _ + \u001B[38;5;111m \\__ \\/ ___/ __ \\/ _ \\/ __ / / / / / _ \\ \u001B[32m/ /_/ / / __ `/ __ \\/ __ \\/ / __ \\/ __ `/ + \u001B[38;5;111m ___/ / /__/ / / / __/ /_/ / /_/ / / __/ \u001B[32m/ ____/ / /_/ / / / / / / / / / / / /_/ /\s + \u001B[38;5;111m/____/\\___/_/ /_/\\___/\\__,_/\\__,_/_/\\___/\u001B[32m /_/ /_/\\__,_/_/ /_/_/ /_/_/_/ /_/\\__, / \s + \u001B[32m /____/ \s + """); + System.out.println("\t\t\t\u001B[33m::: " + SystemConstant.SYSTEM_AUTHOR + " :::\t\t\t\t\t\t\t ::: "+ SystemConstant.SYSTEM_VERSION +" :::\u001B[0m"); + }; + } + + /** + * 初始化数据库表完整性检查 + */ + private void initSqlCheck() { + log.info("[INIT] 检查表"); + prepare.checkTable("mc_info"); + prepare.checkTable("mc_logs"); + prepare.checkTable("mc_role"); + prepare.checkTable("mc_user"); + } + + /** + * 初始化 mc_info 表检查 + */ + private void initInfoTableCheck() { + log.info("[INIT] 数据表 mc_info 缺陷检查..."); + + prepare.checkInfoTableFields("system_initial_mode", "true"); + prepare.checkInfoTableFields("system_debug_mode", "true"); + prepare.checkInfoTableFields("system_super_admin_uuid", null); + prepare.checkInfoTableFields("system_test_user_uuid", null); + } + /** + * 初始化全局变量赋值 + */ + private void initGlobalVariableAssignment() { + log.info("[INIT] 全局变量初始化..."); + SystemConstant.isInitialMode = prepare.initGetGlobalVariable("system_initial_mode"); + SystemConstant.isDebugMode = Boolean.parseBoolean(prepare.initGetGlobalVariable("system_debug_mode")); + SystemConstant.superAdminUUID = prepare.initGetGlobalVariable("system_super_admin_uuid"); + SystemConstant.testUserUUID = prepare.initGetGlobalVariable("system_test_user_uuid"); + } + /** + * 初始化角色 + */ + private void initRole() { + log.info("[INIT] 初始化角色..."); + prepare.initRole("ADMIN", "管理员", "拥有软件的所有权限,包括用户管理、角色管理、日志管理、信息管理等。"); + prepare.initRole("USER", "用户", "拥有软件的部分权限,包括日志查看、信息查看等。"); } } diff --git a/src/main/java/com/frontleaves/mastercontrol/config/init/PrepareAlgorithm.java b/src/main/java/com/frontleaves/mastercontrol/config/init/PrepareAlgorithm.java new file mode 100644 index 0000000..84eb93a --- /dev/null +++ b/src/main/java/com/frontleaves/mastercontrol/config/init/PrepareAlgorithm.java @@ -0,0 +1,109 @@ +package com.frontleaves.mastercontrol.config.init; + +import com.frontleaves.mastercontrol.dao.InfoDAO; +import com.frontleaves.mastercontrol.dao.RoleDAO; +import com.frontleaves.mastercontrol.dao.TableDAO; +import com.frontleaves.mastercontrol.model.entity.InfoDO; +import com.frontleaves.mastercontrol.model.entity.RoleDO; +import com.frontleaves.mastercontrol.model.entity.TableDO; +import com.xlf.utility.util.UuidUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.util.FileCopyUtils; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + *准备算法 + * @since v1.0.0 + * @version v1.0.0 + * @author FLASHLACK1314 + * + */ +@Slf4j +@RequiredArgsConstructor +public class PrepareAlgorithm { + private final TableDAO tableDAO; + private final InfoDAO infoDAO; + private final RoleDAO roleDAO; + private final JdbcTemplate jdbcTemplate; + + /** + * 检查表 + *
+ * 该方法用于检查表;当表不存在时,创建表;若表存在,忽略数据库的检查。 + * + * @param tableName 表名 + */ + public void checkTable(String tableName) { + TableDO tableDO = tableDAO.lambdaQuery().eq(TableDO::getTableName, tableName).one(); + if (tableDO == null) { + ClassPathResource classPathResource = new ClassPathResource("/templates/sql/" + tableName + ".sql"); + try { + String getSql = FileCopyUtils.copyToString(new InputStreamReader(classPathResource.getInputStream(), StandardCharsets.UTF_8)); + getSql = getSql.replaceAll("(?s)/\\*.*?\\*/", ""); + for (String sql : getSql.split(";")) { + jdbcTemplate.execute(sql); + } + log.debug("[INIT] 创建表 | {}", tableName); + } catch (IOException e) { + log.error("[INIT] 读取SQL文件失败 | {}", e.getMessage(), e); + } + } + } + + /** + * 检查信息表字段 + *
+ * 该方法用于检查信息表字段,当字段不存在时,创建字段;若字段存在,忽略数据库的检查。 + * + * @param key 键 + * @param value 值 + */ + public void checkInfoTableFields(String key, String value) { + InfoDO infoDO = infoDAO.lambdaQuery().eq(InfoDO::getKey, key).one(); + if (infoDO == null) { + InfoDO newInfo = new InfoDO() + .setKey(key) + .setValue(value); + infoDAO.save(newInfo); + log.debug("[INIT] 创建信息表字段 | <{}>{}", key, value); + } + } + + /** + * 获取全局变量 + *
+ *该方法用于获取全局变量;当全局变量不存在时,初始化全局变量。 + */ + public String initGetGlobalVariable(String key) { + InfoDO infoDO = infoDAO.lambdaQuery().eq(InfoDO::getKey, key).one(); + if (infoDO == null) { + return null; + } + return infoDO.getValue(); + } + + /** + * 初始化角色 + * @param name 角色名 + * @param displayName 显示名 + * @param desc 描述 + */ + public void initRole(String name, String displayName, String desc) { + RoleDO roleDO = roleDAO.lambdaQuery().eq(RoleDO::getName, name).one(); + if (roleDO == null) { + RoleDO newRole = new RoleDO() + .setRoleUuid(UuidUtil.generateStringUuid()) + .setName(name) + .setDisplayName(displayName) + .setRoleDesc(desc); + roleDAO.save(newRole); + log.debug("[INIT] 创建角色 | [{}]{}", name, displayName); + } + } +} diff --git a/src/main/java/com/frontleaves/mastercontrol/constant/SystemConstant.java b/src/main/java/com/frontleaves/mastercontrol/constant/SystemConstant.java new file mode 100644 index 0000000..ec6cd89 --- /dev/null +++ b/src/main/java/com/frontleaves/mastercontrol/constant/SystemConstant.java @@ -0,0 +1,96 @@ +package com.frontleaves.mastercontrol.constant; +/** + * 系统常量 + *
+ * 该类用于定义系统中的常量信息; + * + * @since v1.0.0 + * @version v1.0.0 + * @author FLASHLACK1314 + */ +public class SystemConstant { + /** + * 系统名称 + */ + public static final String SYSTEM_NAME = "master control"; + /** + * 系统中文名称 + */ + public static final String SYSTEM_CHINESE_NAME = "主控"; + /** + * 系统版权 + */ + public static final String SYSTEM_COPYRIGHT = "2023 锋楪技术(深圳)有限公司 . All Rights Reserved. "; + /** + * 系统中文版权 + */ + public static final String SYSTEM_CHINESE_COPYRIGHT = "版权所有 2023 锋楪技术(深圳)有限公司 保留所有权利。"; + /** + * 系统版本 + */ + public static final String SYSTEM_VERSION = "v1.0.0"; + /** + * 作者信息 + */ + public static final String SYSTEM_AUTHOR = "XiaoLFeng and FLASHLACK1314"; + /** + * 作者邮箱 + */ + public static final String SYSTEM_AUTHOR_EMAIL = "gm@x-lf.cn"; + /** + * 作者网址 + */ + public static final String SYSTEM_AUTHOR_URL = "https://www.x-lf.com"; + /** + * 系统许可证 + */ + public static final String SYSTEM_LICENSE = "MIT"; + /** + * 系统许可证URL + */ + public static final String SYSTEM_LICENSE_URL = "https://opensource.org/license/MIT"; + /** + * 系统免责声明 + */ + public static final String SYSTEM_DISCLAIMER = "Since this project is in the model design stage, we are not responsible for any losses caused by using this project for commercial purposes. If you modify the code and redistribute it, you need to clearly indicate what changes you made in the corresponding file. If you want to modify it for commercial use, please contact me."; + /** + * 系统中文免责声明 + */ + public static final String SYSTEM_CHINESE_DISCLAIMER = "由于该项目处于模型设计阶段,我们不对使用该项目进行商业用途造成的任何损失负责。如果您修改了代码并重新分发它,您需要清楚地指出您在相应文件中所做的更改。如果您想将其用于商业用途,请与我联系。"; + /** + * 系统关于 + */ + public static final String SYSTEM_ABOUT = "The project contains the source code of com.frontleaves.mastercontrol. All source code for this project is licensed under the MIT open source license."; + /** + * 系统中文关于 + */ + public static final String SYSTEM_CHINESE_ABOUT = "该项目包含 com.xlf.schedule 的源代码。该项目的所有源代码均根据 MIT 开源许可证授权。"; + /** + * 系统许可证声明 + */ + public static final String SYSTEM_LICENSE_STATEMENT = "For more information about the MIT license, please view the LICENSE file in the project root directory or visit: https://opensource.org/license/MIT"; + /** + * 系统中文许可证声明 + */ + public static final String SYSTEM_CHINESE_LICENSE_STATEMENT = "有关 MIT 许可证的更多信息,请查看项目根目录中的 LICENSE 文件或访问: https://opensource.org/license/MIT"; + + /** + * 是否是初始化模式 + */ + public static String isInitialMode; + + /** + * 是否是调试模式 + */ + public static Boolean isDebugMode; + + /** + * 超级管理员UUID + */ + public static String superAdminUUID; + + /** + * 测试用户UUID + */ + public static String testUserUUID; +} diff --git a/src/main/java/com/frontleaves/mastercontrol/dao/InfoDAO.java b/src/main/java/com/frontleaves/mastercontrol/dao/InfoDAO.java new file mode 100644 index 0000000..78d0f16 --- /dev/null +++ b/src/main/java/com/frontleaves/mastercontrol/dao/InfoDAO.java @@ -0,0 +1,20 @@ +package com.frontleaves.mastercontrol.dao; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.frontleaves.mastercontrol.mapper.InfoMapper; +import com.frontleaves.mastercontrol.model.entity.InfoDO; +import org.springframework.stereotype.Repository; + +/** + * 信息数据访问对象 + *
+ * 该类用于定义信息数据访问对象
+ * 该类使用 {@link Repository} 注解标记
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ */
+@Repository
+public class InfoDAO extends ServiceImpl
+ * 该类用于定义日志数据访问对象
+ * 该类使用 {@link Repository} 注解标记
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ */
+@Repository
+public class LogsDAO extends ServiceImpl
+ * 该类用于定义角色数据访问对象
+ * 该类使用 {@link Repository} 注解标记
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ *
+ */
+@Repository
+public class RoleDAO extends ServiceImpl
+ * 该类用于定义表数据访问对象;
+ * 该类使用 {@link Repository} 注解标记;
+ * @author FLASHLACK1314
+ */
+@Repository
+public class TableDAO extends ServiceImpl
+ * 该类用于定义Token数据访问对象
+ * 该类使用 {@link Repository} 注解标记
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ *
+ */
+@Repository
+public class TokenDAO extends ServiceImpl
+ * 该类用于定义日志映射器。
+ * 该类继承 {@link BaseMapper} 接口。
+ * @author FLASHLACK1314
+ */
+@Mapper
+public interface LogsMapper extends BaseMapper
+ * 该类用于定义角色映射器。
+ * 该类继承 {@link BaseMapper} 接口。
+ * 该类使用 {@link Mapper} 注解。
+ * @author FLASHLACK1314
+ */
+@Mapper
+public interface RoleMapper extends BaseMapper
+ * 该类用于定义Token映射器。
+ * 该类继承 {@link BaseMapper} 接口。
+ * 该类使用 {@link Mapper} 注解。
+ *
+ * @author FLASHLACK1314
+ * @version v1.0.0
+ * @since v1.0.0
+ */
+@Mapper
+public interface TokenMapper extends BaseMapper
+ * 该类用于定义信息实体
+ * @author FLASHLACK1314
+ */
+@Data
+@TableName("mc_info")
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class InfoDO {
+ /**
+ * 信息表主键
+ */
+ @TableId(type = IdType.ASSIGN_UUID)
+ private String infoUuid;
+ /**
+ * 信息表键
+ */
+ private String key;
+ /**
+ * 信息表值
+ */
+ private String value;
+ /**
+ * 信息表更新时间
+ */
+ private Timestamp updatedAt;
+}
diff --git a/src/main/java/com/frontleaves/mastercontrol/model/entity/LogsDO.java b/src/main/java/com/frontleaves/mastercontrol/model/entity/LogsDO.java
new file mode 100644
index 0000000..0ab85d9
--- /dev/null
+++ b/src/main/java/com/frontleaves/mastercontrol/model/entity/LogsDO.java
@@ -0,0 +1,50 @@
+package com.frontleaves.mastercontrol.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.sql.Timestamp;
+
+/**
+ * 日志数据对象
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ */
+@Data
+@TableName("mc_logs")
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class LogsDO {
+ /**
+ * 日志UUID
+ */
+ @TableId(type = IdType.ASSIGN_UUID)
+ private String logUuid;
+ /**
+ * 日志类型
+ */
+ private Short type;
+ /**
+ * 业务
+ */
+ private String business;
+ /**
+ * 用户
+ */
+ private String user;
+ /**
+ * 值
+ */
+ private String value;
+ /**
+ * 创建时间
+ */
+ private Timestamp createdAt;
+}
diff --git a/src/main/java/com/frontleaves/mastercontrol/model/entity/RoleDO.java b/src/main/java/com/frontleaves/mastercontrol/model/entity/RoleDO.java
new file mode 100644
index 0000000..73a9564
--- /dev/null
+++ b/src/main/java/com/frontleaves/mastercontrol/model/entity/RoleDO.java
@@ -0,0 +1,46 @@
+package com.frontleaves.mastercontrol.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.sql.Timestamp;
+
+/**
+ * 角色数据对象
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ */
+@Data
+@TableName("mc_role")
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class RoleDO {
+ /**
+ * 用户角色表主键
+ */
+ @TableId(type = IdType.NONE)
+ private String roleUuid;
+ /**
+ * 用户角色表名称
+ */
+ private String name;
+ /**
+ * 用户角色表显示名称
+ */
+ private String displayName;
+ /**
+ * 用户角色表描述
+ */
+ private String roleDesc;
+ /**
+ * 用户角色表创建时间
+ */
+ private Timestamp createdAt;
+}
diff --git a/src/main/java/com/frontleaves/mastercontrol/model/entity/TableDO.java b/src/main/java/com/frontleaves/mastercontrol/model/entity/TableDO.java
new file mode 100644
index 0000000..ec05523
--- /dev/null
+++ b/src/main/java/com/frontleaves/mastercontrol/model/entity/TableDO.java
@@ -0,0 +1,37 @@
+package com.frontleaves.mastercontrol.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 表实体
+ *
+ * 该类用于定义表实体;
+ * 该类使用 {@link Mapper} 注解标记;
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ */
+@Data
+@TableName(value = "tables", schema = "information_schema")
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class TableDO {
+ private String tableCatalog;
+ private String tableSchema;
+ private String tableName;
+ private String tableType;
+ private String selfReferencingColumnName;
+ private String referenceGeneration;
+ private String userDefinedTypeCatalog;
+ private String userDefinedTypeSchema;
+ private String userDefinedTypeName;
+ private String isInsertableInto;
+ private String isTyped;
+ private String commitAction;
+}
diff --git a/src/main/java/com/frontleaves/mastercontrol/model/entity/TokenDO.java b/src/main/java/com/frontleaves/mastercontrol/model/entity/TokenDO.java
new file mode 100644
index 0000000..21d7244
--- /dev/null
+++ b/src/main/java/com/frontleaves/mastercontrol/model/entity/TokenDO.java
@@ -0,0 +1,32 @@
+package com.frontleaves.mastercontrol.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.sql.Timestamp;
+
+/**
+ * Token数据对象
+ * @since v1.0.0
+ * @version v1.0.0
+ * @author FLASHLACK1314
+ */
+@Data
+@TableName("mc_token")
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class TokenDO {
+ @TableId
+ private String tokenUuid;
+ private String userUuid;
+ private Timestamp createdAt;
+ private Timestamp expiredAt;
+ private String clientIp;
+ private String clientReferer;
+ private String clientUserAgent;
+}
diff --git a/src/main/resources/templates/sql/mc_info.sql b/src/main/resources/templates/sql/mc_info.sql
new file mode 100644
index 0000000..07357b4
--- /dev/null
+++ b/src/main/resources/templates/sql/mc_info.sql
@@ -0,0 +1,18 @@
+create table mc_info
+(
+ info_uuid varchar(36) not null
+ constraint mc_info_pk
+ primary key,
+ key varchar(128) not null,
+ value varchar,
+ updated_at timestamp default now() not null
+);
+
+comment on table mc_info is '信息表';
+comment on column mc_info.info_uuid is '信息表主键';
+comment on column mc_info.key is '键值对-键';
+comment on column mc_info.value is '键值对-值';
+comment on column mc_info.updated_at is '修改时间';
+
+create unique index mc_info_key_uindex
+ on mc_info (key);
\ No newline at end of file
diff --git a/src/main/resources/templates/sql/mc_logs.sql b/src/main/resources/templates/sql/mc_logs.sql
new file mode 100644
index 0000000..b9a8084
--- /dev/null
+++ b/src/main/resources/templates/sql/mc_logs.sql
@@ -0,0 +1,19 @@
+create table mc_logs
+(
+ log_uuid varchar(32) not null
+ constraint mc_logs_pk
+ primary key,
+ type smallint default 0 not null,
+ business varchar(16) not null,
+ "user" varchar(36),
+ value varchar not null,
+ created_at timestamp default now() not null
+);
+
+comment on table mc_logs is '日志数据表';
+comment on column mc_logs.log_uuid is '日志表主键';
+comment on column mc_logs.type is '日志类型';
+comment on column mc_logs.business is '业务类型';
+comment on column mc_logs."user" is '执行用户(可为空)';
+comment on column mc_logs.value is '日志内容';
+comment on column mc_logs.created_at is '日志创建时间';
\ No newline at end of file
diff --git a/src/main/resources/templates/sql/mc_role.sql b/src/main/resources/templates/sql/mc_role.sql
new file mode 100644
index 0000000..589dd5f
--- /dev/null
+++ b/src/main/resources/templates/sql/mc_role.sql
@@ -0,0 +1,20 @@
+create table mc_role
+(
+ role_uuid varchar(36) not null
+ constraint mc_role_pk
+ primary key,
+ name varchar(36) not null,
+ display_name varchar(36) not null,
+ role_desc varchar(256) not null,
+ created_at timestamp default now() not null
+);
+
+comment on table mc_role is '用户角色表';
+comment on column mc_role.role_uuid is '角色主键';
+comment on column mc_role.name is '角色名字';
+comment on column mc_role.display_name is '角色名字展示';
+comment on column mc_role.role_desc is '角色信息描述';
+comment on column mc_role.created_at is '创建时间';
+
+create unique index mc_role_name_uindex
+ on mc_role (name);
\ No newline at end of file
diff --git a/src/main/resources/templates/sql/mc_token.sql b/src/main/resources/templates/sql/mc_token.sql
new file mode 100644
index 0000000..216544a
--- /dev/null
+++ b/src/main/resources/templates/sql/mc_token.sql
@@ -0,0 +1,24 @@
+create table mc_token
+(
+ token_uuid varchar(36) not null
+ constraint mc_token_pk
+ primary key,
+ user_uuid varchar(36) not null
+ constraint mc_token_mc_user_uuid_fk
+ references mc_user
+ on update cascade on delete cascade,
+ created_at timestamp default now() not null,
+ expired_at timestamp not null,
+ client_ip varchar(39) not null,
+ client_referer varchar(1024),
+ client_user_agent varchar not null
+);
+
+comment on table mc_token is '令牌';
+comment on column mc_token.token_uuid is '令牌';
+comment on column mc_token.user_uuid is '用户主键';
+comment on column mc_token.created_at is '创建时间';
+comment on column mc_token.expired_at is '过期时间';
+comment on column mc_token.client_ip is '客户端登录时 IP';
+comment on column mc_token.client_referer is '客户端 Referer';
+comment on column mc_token.client_user_agent is '客户端用户信息';
\ No newline at end of file
diff --git a/src/main/resources/templates/sql/mc_user.sql b/src/main/resources/templates/sql/mc_user.sql
new file mode 100644
index 0000000..a632247
--- /dev/null
+++ b/src/main/resources/templates/sql/mc_user.sql
@@ -0,0 +1,40 @@
+create table mc_user
+(
+ uuid varchar(36) not null
+ constraint mc_user_pk
+ primary key,
+ username varchar(36),
+ phone varchar(11) not null,
+ email varchar(254),
+ password char(60) not null,
+ old_password char(60),
+ role varchar(36) not null
+ constraint mc_user_role_fk
+ references mc_role
+ on update restrict on delete restrict,
+ created_at timestamp default now() not null,
+ updated_at timestamp default now() not null,
+ enable boolean default true not null,
+ banned_at timestamp
+);
+
+comment on table mc_user is '用户表';
+comment on column mc_user.uuid is ' 角色主键';
+comment on column mc_user.username is '用户名';
+comment on column mc_user.phone is '手机号';
+comment on column mc_user.email is '用户邮箱';
+comment on column mc_user.password is '用户当前密码';
+comment on column mc_user.old_password is '用户旧密码';
+comment on column mc_user.created_at is '创建时间';
+comment on column mc_user.updated_at is '修改时间';
+comment on column mc_user.enable is '用户是否开启';
+comment on column mc_user.banned_at is '封禁到';
+
+create index mc_user_email_index
+ on mc_user (email);
+
+create unique index mc_user_phone_uindex
+ on mc_user (phone);
+
+create unique index mc_user_username_uindex
+ on mc_user (username);
\ No newline at end of file