diff --git a/urbanLifelineServ/.bin/database/postgres/sql/README_INIT.md b/urbanLifelineServ/.bin/database/postgres/sql/README_INIT.md deleted file mode 100644 index 307bfbb..0000000 --- a/urbanLifelineServ/.bin/database/postgres/sql/README_INIT.md +++ /dev/null @@ -1,225 +0,0 @@ -# 数据库初始化说明 - -## 概述 - -本目录包含城市生命线AI数智化平台的数据库初始化脚本,用于创建表结构和插入基础数据。 - -## 文件说明 - -### 表结构创建脚本 - -| 文件名 | 说明 | -|--------|------| -| `createDB.sql` | 创建数据库 | -| `createTablePermission.sql` | 创建权限相关表(部门、角色、权限、视图、ACL等) | -| `createTableUser.sql` | 创建用户相关表(用户、用户信息、登录日志) | -| `createTableFile.sql` | 创建文件管理表 | -| `createTableMessage.sql` | 创建消息通知表 | -| `createTableLog.sql` | 创建日志表 | -| `createTableConfig.sql` | 创建配置管理表 | -| `createTableKnowledge.sql` | 创建知识库表 | -| `createTableBidding.sql` | 创建招投标业务表 | -| `createTableCustomerService.sql` | 创建智能客服表 | -| `createTableAgent.sql` | 创建智能体表(暂不启用) | - -### 数据初始化脚本 - -| 文件名 | 说明 | 是否必需 | -|--------|------|----------| -| `initDataPermission.sql` | 初始化权限基础数据(部门、角色、权限、视图、模块) | ✅ 必需 | -| `initDataUser.sql` | 初始化用户数据(管理员账户、演示用户) | ✅ 必需 | -| `initDataMessage.sql` | 初始化消息渠道配置和模板 | ✅ 必需 | -| `initDataConfig.sql` | 初始化系统配置参数 | ✅ 必需 | - -### 总入口脚本 - -- `initAll.sql` - 一键执行所有建表和初始化脚本 - -## 使用方法 - -### 方式一:使用总入口脚本(推荐) - -```bash -# 进入 PostgreSQL 命令行 -psql -U postgres - -# 执行总初始化脚本 -\i /path/to/urbanLifelineServ/.bin/database/postgres/sql/initAll.sql -``` - -### 方式二:分步执行 - -#### 第一步:创建表结构 - -```bash -# 创建数据库 -\i createDB.sql - -# 创建各模块表结构 -\i createTablePermission.sql -\i createTableUser.sql -\i createTableFile.sql -\i createTableMessage.sql -\i createTableLog.sql -\i createTableConfig.sql -\i createTableKnowledge.sql -\i createTableBidding.sql -\i createTableCustomerService.sql -``` - -#### 第二步:初始化基础数据 - -```bash -# 按顺序执行初始化脚本 -\i initDataPermission.sql -\i initDataUser.sql -\i initDataMessage.sql -\i initDataConfig.sql -``` - -## 初始化数据说明 - -### 1. 权限基础数据 (initDataPermission.sql) - -**初始化内容:** -- **根部门**:dept_root -- **全局角色**: - - 超级管理员 (role_super_admin) - 拥有所有权限 - - 系统管理员 (role_system_admin) - 拥有系统管理权限 - - 普通用户 (role_user) - 基础查看和操作权限 - - 访客 (role_guest) - 仅查看权限 - -- **系统模块**: - - 系统管理 (mod_system) - - 文件管理 (mod_file) - - 消息通知 (mod_message) - - 配置管理 (mod_config) - - 知识库 (mod_knowledge) - - 招投标 (mod_bidding) - - 智能客服 (mod_customer_service) - -- **系统权限**:30+ 个基础权限,涵盖用户、角色、部门、权限、文件、消息、配置管理 - -- **系统视图(菜单)**: - - 系统管理菜单及其子菜单 - - 业务管理菜单框架 - -### 2. 用户数据 (initDataUser.sql) - -**初始化账户:** - -| 用户 | 账号 | 默认密码 | 角色 | 说明 | -|------|------|----------|------|------| -| 系统管理员 | admin | admin123 | 超级管理员 | 拥有所有权限 | -| 演示用户 | demo | admin123 | 普通用户 | 用于演示和测试 | - -**⚠️ 安全提示:** -- 生产环境部署前,必须修改默认密码 -- 密码使用 bcrypt 加密存储 -- 建议删除演示用户账户 - -### 3. 消息渠道配置 (initDataMessage.sql) - -**初始化内容:** -- **消息渠道**(默认禁用,需配置后启用): - - 应用内消息 (app) - 默认启用 - - 短信通知 (sms) - - 邮件通知 (email) - - 微信公众号 (wechat_official_account) - - 微信小程序 (wechat_applet) - - 钉钉通知 (dingtalk) - -- **消息模板**: - - 用户注册欢迎 - - 密码重置通知 - - 系统维护通知 - - 工单创建通知 - - 招标公告发布 - -### 4. 系统配置 (initDataConfig.sql) - -**初始化配置分组:** -- **站点配置**:站点名称、Logo、ICP备案 -- **国际化**:默认语言、时区 -- **安全认证**:密码策略、JWT过期时间、会话超时、注册开关 -- **存储上传**:最大上传大小、存储后端、存储路径 -- **通知配置**:邮件SMTP、短信服务商 -- **日志审计**:日志级别、审计日志保留天数 -- **平台特性**:维护模式、ACL策略开关 - -## 注意事项 - -1. **执行顺序**:必须按照 `initAll.sql` 中的顺序执行,先创建表结构,再插入数据 -2. **依赖关系**:初始化数据脚本有依赖关系,必须按顺序执行 -3. **数据库权限**:执行脚本需要具有创建数据库、创建表、插入数据的权限 -4. **字符编码**:确保数据库使用 UTF-8 编码 -5. **时区设置**:建议数据库时区设置为 Asia/Shanghai 或 UTC - -## 验证初始化结果 - -执行以下 SQL 验证初始化是否成功: - -```sql --- 检查表是否创建成功 -SELECT schemaname, tablename -FROM pg_tables -WHERE schemaname IN ('sys', 'file', 'message', 'config') -ORDER BY schemaname, tablename; - --- 检查角色数量 -SELECT COUNT(*) as role_count FROM sys.tb_sys_role WHERE deleted = false; --- 预期结果:4 - --- 检查权限数量 -SELECT COUNT(*) as permission_count FROM sys.tb_sys_permission WHERE deleted = false; --- 预期结果:30+ - --- 检查用户数量 -SELECT COUNT(*) as user_count FROM sys.tb_sys_user WHERE deleted = false; --- 预期结果:2 - --- 检查消息渠道数量 -SELECT COUNT(*) as channel_count FROM message.tb_message_channel WHERE deleted = false; --- 预期结果:6 - --- 检查系统配置数量 -SELECT COUNT(*) as config_count FROM config.tb_sys_config WHERE deleted = false; --- 预期结果:20+ -``` - -## 重置数据库 - -如需重新初始化数据库,可以执行以下操作: - -```sql --- 删除所有 schema(谨慎操作!) -DROP SCHEMA IF EXISTS sys CASCADE; -DROP SCHEMA IF EXISTS file CASCADE; -DROP SCHEMA IF EXISTS message CASCADE; -DROP SCHEMA IF EXISTS config CASCADE; -DROP SCHEMA IF EXISTS knowledge CASCADE; -DROP SCHEMA IF EXISTS bidding CASCADE; -DROP SCHEMA IF EXISTS customer_service CASCADE; -DROP SCHEMA IF EXISTS log CASCADE; - --- 然后重新执行 initAll.sql -\i initAll.sql -``` - -## 常见问题 - -### Q: 执行初始化脚本报错 "relation already exists" -A: 表已存在,可以选择删除对应的表或 schema 后重新执行 - -### Q: 如何修改管理员默认密码? -A: 修改 `initDataUser.sql` 中的 password 字段,使用 bcrypt 加密后的密码哈希 - -### Q: 如何自定义初始化数据? -A: 直接修改对应的 `initData*.sql` 文件,按照现有格式添加或修改数据 - -### Q: 业务表(知识库、招投标、客服)需要初始化数据吗? -A: 不需要,这些表的数据在系统运行时动态产生 - -## 联系支持 - -如有问题,请联系技术支持团队。 diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createDB.sql b/urbanLifelineServ/.bin/database/postgres/sql/createDB.sql index 51b05a1..19ad602 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createDB.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createDB.sql @@ -1,11 +1,11 @@ -- 删除已存在的数据库(如果存在) -DROP DATABASE IF EXISTS urban-lifeline; +DROP DATABASE IF EXISTS urban_lifeline; -- 创建新数据库,使用 UTF8 编码,并设置适合中文的排序规则 -- 使用 template0 确保干净的数据库模板 -- zh_CN.UTF-8 支持中文字符排序和比较 -CREATE DATABASE urban-lifeline +CREATE DATABASE urban_lifeline ENCODING 'UTF8' TEMPLATE template0 LC_COLLATE 'zh_CN.UTF-8' diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableConfig.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableConfig.sql index 9cf5931..f3bd68d 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createTableConfig.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableConfig.sql @@ -11,7 +11,7 @@ CREATE TABLE config.tb_sys_config ( description VARCHAR(255) NOT NULL, -- 配置描述 re JSON DEFAULT NULL, -- 正则表达式校验规则 options JSON DEFAULT NULL, -- 可选项,render_type为select、checkbox、radio时使用 - group VARCHAR(255) NOT NULL, -- 配置组 + "group" VARCHAR(255) NOT NULL, -- 配置组 module_id VARCHAR(255) NOT NULL, -- 模块id order_num INT NOT NULL, -- 配置顺序 status INT NOT NULL DEFAULT 0, -- 配置状态 0:启用 1:禁用 diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableCrontab.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableCrontab.sql index efd4b65..1dfc5e7 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createTableCrontab.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableCrontab.sql @@ -1,89 +1,153 @@ -- ==================================================== -- 定时任务表 -- ==================================================== -DROP TABLE IF EXISTS `tb_crontab_task`; -CREATE TABLE `tb_crontab_task` ( - `id` VARCHAR(64) NOT NULL COMMENT '主键ID', - `task_id` VARCHAR(64) NOT NULL COMMENT '任务ID', - `task_name` VARCHAR(100) NOT NULL COMMENT '任务名称', - `task_group` VARCHAR(50) NOT NULL DEFAULT 'DEFAULT' COMMENT '任务分组', - `meta_id` VARCHAR(64) NOT NULL COMMENT '任务元数据ID', - `default_recipient` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否使用默认接收人(0:否 1:是)', - `bean_name` VARCHAR(100) NOT NULL COMMENT 'Bean名称', - `method_name` VARCHAR(100) NOT NULL COMMENT '方法名称', - `method_params` VARCHAR(500) DEFAULT NULL COMMENT '方法参数', - `cron_expression` VARCHAR(100) NOT NULL COMMENT 'Cron表达式', - `status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '任务状态(0:暂停 1:运行中)', - `description` VARCHAR(500) DEFAULT NULL COMMENT '任务描述', - `concurrent` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否允许并发执行(0:否 1:是)', - `misfire_policy` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '错过执行策略(1:立即执行 2:执行一次 3:放弃执行)', - `creator` VARCHAR(64) DEFAULT NULL COMMENT '创建者', - `updater` VARCHAR(64) DEFAULT NULL COMMENT '更新者', - `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `delete_time` DATETIME DEFAULT NULL COMMENT '删除时间', - `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除(0:否 1:是)', - PRIMARY KEY (`id`), - KEY `idx_task_name` (`task_name`), - KEY `idx_bean_name` (`bean_name`), - KEY `idx_status` (`status`), - KEY `idx_deleted` (`deleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='定时任务配置表'; +CREATE SCHEMA IF NOT EXISTS crontab; +DROP TABLE IF EXISTS crontab.tb_crontab_task CASCADE; +CREATE TABLE crontab.tb_crontab_task ( + id VARCHAR(64) NOT NULL, + task_id VARCHAR(64) NOT NULL, + task_name VARCHAR(100) NOT NULL, + task_group VARCHAR(50) NOT NULL DEFAULT 'DEFAULT', + meta_id VARCHAR(64) NOT NULL, + default_recipient SMALLINT NOT NULL DEFAULT 0, -- 是否使用默认接收人(0:否 1:是) + bean_name VARCHAR(100) NOT NULL, + method_name VARCHAR(100) NOT NULL, + method_params VARCHAR(500) DEFAULT NULL, + cron_expression VARCHAR(100) NOT NULL, + status SMALLINT NOT NULL DEFAULT 0, -- 任务状态(0:暂停 1:运行中) + description VARCHAR(500) DEFAULT NULL, + concurrent SMALLINT NOT NULL DEFAULT 0, -- 是否允许并发执行(0:否 1:是) + misfire_policy SMALLINT NOT NULL DEFAULT 1, -- 错过执行策略(1:立即执行 2:执行一次 3:放弃执行) + creator VARCHAR(64) DEFAULT NULL, + updater VARCHAR(64) DEFAULT NULL, + create_time TIMESTAMPTZ NOT NULL DEFAULT now(), + update_time TIMESTAMPTZ DEFAULT NULL, + delete_time TIMESTAMPTZ DEFAULT NULL, + deleted SMALLINT NOT NULL DEFAULT 0, -- 是否删除(0:否 1:是) + PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_task_name ON crontab.tb_crontab_task(task_name); +CREATE INDEX IF NOT EXISTS idx_bean_name ON crontab.tb_crontab_task(bean_name); +CREATE INDEX IF NOT EXISTS idx_status ON crontab.tb_crontab_task(status); +CREATE INDEX IF NOT EXISTS idx_deleted ON crontab.tb_crontab_task(deleted); + +COMMENT ON TABLE crontab.tb_crontab_task IS '定时任务配置表'; +COMMENT ON COLUMN crontab.tb_crontab_task.id IS '主键ID'; +COMMENT ON COLUMN crontab.tb_crontab_task.task_id IS '任务ID'; +COMMENT ON COLUMN crontab.tb_crontab_task.task_name IS '任务名称'; +COMMENT ON COLUMN crontab.tb_crontab_task.task_group IS '任务分组'; +COMMENT ON COLUMN crontab.tb_crontab_task.meta_id IS '任务元数据ID'; +COMMENT ON COLUMN crontab.tb_crontab_task.default_recipient IS '是否使用默认接收人(0:否 1:是)'; +COMMENT ON COLUMN crontab.tb_crontab_task.bean_name IS 'Bean名称'; +COMMENT ON COLUMN crontab.tb_crontab_task.method_name IS '方法名称'; +COMMENT ON COLUMN crontab.tb_crontab_task.method_params IS '方法参数'; +COMMENT ON COLUMN crontab.tb_crontab_task.cron_expression IS 'Cron表达式'; +COMMENT ON COLUMN crontab.tb_crontab_task.status IS '任务状态(0:暂停 1:运行中)'; +COMMENT ON COLUMN crontab.tb_crontab_task.description IS '任务描述'; +COMMENT ON COLUMN crontab.tb_crontab_task.concurrent IS '是否允许并发执行(0:否 1:是)'; +COMMENT ON COLUMN crontab.tb_crontab_task.misfire_policy IS '错过执行策略(1:立即执行 2:执行一次 3:放弃执行)'; +COMMENT ON COLUMN crontab.tb_crontab_task.creator IS '创建者'; +COMMENT ON COLUMN crontab.tb_crontab_task.updater IS '更新者'; +COMMENT ON COLUMN crontab.tb_crontab_task.create_time IS '创建时间'; +COMMENT ON COLUMN crontab.tb_crontab_task.update_time IS '更新时间'; +COMMENT ON COLUMN crontab.tb_crontab_task.delete_time IS '删除时间'; +COMMENT ON COLUMN crontab.tb_crontab_task.deleted IS '是否删除(0:否 1:是)'; -- ==================================================== -- 定时任务执行日志表 -- ==================================================== -DROP TABLE IF EXISTS `tb_crontab_log`; -CREATE TABLE `tb_crontab_log` ( - `id` VARCHAR(64) NOT NULL COMMENT '主键ID', - `task_id` VARCHAR(64) NOT NULL COMMENT '任务ID', - `task_name` VARCHAR(100) NOT NULL COMMENT '任务名称', - `task_group` VARCHAR(50) NOT NULL DEFAULT 'DEFAULT' COMMENT '任务分组', - `bean_name` VARCHAR(100) NOT NULL COMMENT 'Bean名称', - `method_name` VARCHAR(100) NOT NULL COMMENT '方法名称', - `method_params` VARCHAR(500) DEFAULT NULL COMMENT '方法参数', - `execute_status` TINYINT(1) NOT NULL COMMENT '执行状态(0:失败 1:成功)', - `execute_message` TEXT DEFAULT NULL COMMENT '执行结果信息', - `exception_info` TEXT DEFAULT NULL COMMENT '异常信息', - `start_time` DATETIME NOT NULL COMMENT '开始时间', - `end_time` DATETIME DEFAULT NULL COMMENT '结束时间', - `execute_duration` INT DEFAULT NULL COMMENT '执行时长(毫秒)', - `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `delete_time` DATETIME DEFAULT NULL COMMENT '删除时间', - `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除(0:否 1:是)', - PRIMARY KEY (`id`), - KEY `idx_task_id` (`task_id`), - KEY `idx_task_name` (`task_name`), - KEY `idx_execute_status` (`execute_status`), - KEY `idx_start_time` (`start_time`), - KEY `idx_deleted` (`deleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='定时任务执行日志表'; +DROP TABLE IF EXISTS crontab.tb_crontab_log CASCADE; +CREATE TABLE crontab.tb_crontab_log ( + id VARCHAR(64) NOT NULL, + task_id VARCHAR(64) NOT NULL, + task_name VARCHAR(100) NOT NULL, + task_group VARCHAR(50) NOT NULL DEFAULT 'DEFAULT', + bean_name VARCHAR(100) NOT NULL, + method_name VARCHAR(100) NOT NULL, + method_params VARCHAR(500) DEFAULT NULL, + execute_status SMALLINT NOT NULL, -- 执行状态(0:失败 1:成功) + execute_message TEXT DEFAULT NULL, + exception_info TEXT DEFAULT NULL, + start_time TIMESTAMPTZ NOT NULL, + end_time TIMESTAMPTZ DEFAULT NULL, + execute_duration INT DEFAULT NULL, + create_time TIMESTAMPTZ NOT NULL DEFAULT now(), + update_time TIMESTAMPTZ DEFAULT NULL, + delete_time TIMESTAMPTZ DEFAULT NULL, + deleted SMALLINT NOT NULL DEFAULT 0, -- 是否删除(0:否 1:是) + PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_task_id ON crontab.tb_crontab_log(task_id); +CREATE INDEX IF NOT EXISTS idx_log_task_name ON crontab.tb_crontab_log(task_name); +CREATE INDEX IF NOT EXISTS idx_execute_status ON crontab.tb_crontab_log(execute_status); +CREATE INDEX IF NOT EXISTS idx_start_time ON crontab.tb_crontab_log(start_time); +CREATE INDEX IF NOT EXISTS idx_log_deleted ON crontab.tb_crontab_log(deleted); + +COMMENT ON TABLE crontab.tb_crontab_log IS '定时任务执行日志表'; +COMMENT ON COLUMN crontab.tb_crontab_log.id IS '主键ID'; +COMMENT ON COLUMN crontab.tb_crontab_log.task_id IS '任务ID'; +COMMENT ON COLUMN crontab.tb_crontab_log.task_name IS '任务名称'; +COMMENT ON COLUMN crontab.tb_crontab_log.task_group IS '任务分组'; +COMMENT ON COLUMN crontab.tb_crontab_log.bean_name IS 'Bean名称'; +COMMENT ON COLUMN crontab.tb_crontab_log.method_name IS '方法名称'; +COMMENT ON COLUMN crontab.tb_crontab_log.method_params IS '方法参数'; +COMMENT ON COLUMN crontab.tb_crontab_log.execute_status IS '执行状态(0:失败 1:成功)'; +COMMENT ON COLUMN crontab.tb_crontab_log.execute_message IS '执行结果信息'; +COMMENT ON COLUMN crontab.tb_crontab_log.exception_info IS '异常信息'; +COMMENT ON COLUMN crontab.tb_crontab_log.start_time IS '开始时间'; +COMMENT ON COLUMN crontab.tb_crontab_log.end_time IS '结束时间'; +COMMENT ON COLUMN crontab.tb_crontab_log.execute_duration IS '执行时长(毫秒)'; +COMMENT ON COLUMN crontab.tb_crontab_log.create_time IS '创建时间'; +COMMENT ON COLUMN crontab.tb_crontab_log.update_time IS '更新时间'; +COMMENT ON COLUMN crontab.tb_crontab_log.delete_time IS '删除时间'; +COMMENT ON COLUMN crontab.tb_crontab_log.deleted IS '是否删除(0:否 1:是)'; -- ==================================================== -- 定时任务元数据表(存储爬虫任务的元数据配置) -- ==================================================== -DROP TABLE IF EXISTS `tb_crontab_task_meta`; -CREATE TABLE `tb_crontab_task_meta` ( - `id` VARCHAR(64) NOT NULL COMMENT '主键ID', - `meta_id` VARCHAR(64) NOT NULL COMMENT '元数据ID', - `name` VARCHAR(100) NOT NULL COMMENT '任务名称', - `description` VARCHAR(500) DEFAULT NULL COMMENT '任务描述', - `category` VARCHAR(50) NOT NULL COMMENT '任务分类(如:人民日报新闻爬取)', - `bean_name` VARCHAR(100) NOT NULL COMMENT 'Bean名称(执行器类名)', - `method_name` VARCHAR(100) NOT NULL COMMENT '执行方法名', - `script_path` VARCHAR(255) DEFAULT NULL COMMENT 'Python脚本路径(相对于basePath)', - `param_schema` TEXT DEFAULT NULL COMMENT '参数模板(JSON格式,定义参数名、类型、描述、默认值等)', - `auto_publish` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否自动发布', - `sort_order` INT DEFAULT 0 COMMENT '排序号', - `creator` VARCHAR(64) DEFAULT NULL COMMENT '创建者', - `updater` VARCHAR(64) DEFAULT NULL COMMENT '更新者', - `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `delete_time` DATETIME DEFAULT NULL COMMENT '删除时间', - `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除(0:否 1:是)', - PRIMARY KEY (`id`), - UNIQUE KEY `uk_meta_id` (`meta_id`), - KEY `idx_category` (`category`), - KEY `idx_deleted` (`deleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='定时任务元数据表'; \ No newline at end of file +DROP TABLE IF EXISTS crontab.tb_crontab_task_meta CASCADE; +CREATE TABLE crontab.tb_crontab_task_meta ( + id VARCHAR(64) NOT NULL, + meta_id VARCHAR(64) NOT NULL, + name VARCHAR(100) NOT NULL, + description VARCHAR(500) DEFAULT NULL, + category VARCHAR(50) NOT NULL, + bean_name VARCHAR(100) NOT NULL, + method_name VARCHAR(100) NOT NULL, + script_path VARCHAR(255) DEFAULT NULL, + param_schema TEXT DEFAULT NULL, + auto_publish SMALLINT NOT NULL DEFAULT 0, -- 是否自动发布 + sort_order INT DEFAULT 0, + creator VARCHAR(64) DEFAULT NULL, + updater VARCHAR(64) DEFAULT NULL, + create_time TIMESTAMPTZ NOT NULL DEFAULT now(), + update_time TIMESTAMPTZ DEFAULT NULL, + delete_time TIMESTAMPTZ DEFAULT NULL, + deleted SMALLINT NOT NULL DEFAULT 0, -- 是否删除(0:否 1:是) + PRIMARY KEY (id), + UNIQUE (meta_id) +); + +CREATE INDEX IF NOT EXISTS idx_category ON crontab.tb_crontab_task_meta(category); +CREATE INDEX IF NOT EXISTS idx_meta_deleted ON crontab.tb_crontab_task_meta(deleted); + +COMMENT ON TABLE crontab.tb_crontab_task_meta IS '定时任务元数据表'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.id IS '主键ID'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.meta_id IS '元数据ID'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.name IS '任务名称'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.description IS '任务描述'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.category IS '任务分类(如:人民日报新闻爬取)'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.bean_name IS 'Bean名称(执行器类名)'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.method_name IS '执行方法名'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.script_path IS 'Python脚本路径(相对于basePath)'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.param_schema IS '参数模板(JSON格式,定义参数名、类型、描述、默认值等)'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.auto_publish IS '是否自动发布'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.sort_order IS '排序号'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.creator IS '创建者'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.updater IS '更新者'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.create_time IS '创建时间'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.update_time IS '更新时间'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.delete_time IS '删除时间'; +COMMENT ON COLUMN crontab.tb_crontab_task_meta.deleted IS '是否删除(0:否 1:是)'; \ No newline at end of file diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableKnowledge.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableKnowledge.sql index 57aa9ba..a56b25d 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createTableKnowledge.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableKnowledge.sql @@ -73,7 +73,7 @@ CREATE TABLE knowledge.tb_knowledge_document ( delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间 deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (doc_id), - UNIQUE (optsn), + UNIQUE (optsn) ); CREATE INDEX idx_doc_kb ON knowledge.tb_knowledge_document(knowledge_id) WHERE deleted = false; @@ -112,7 +112,7 @@ CREATE TABLE knowledge.tb_knowledge_chunk ( update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间 deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (chunk_id), - UNIQUE (optsn), + UNIQUE (optsn) ); CREATE INDEX idx_chunk_doc ON knowledge.tb_knowledge_chunk(doc_id) WHERE deleted = false; diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableMessage.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableMessage.sql index 123e427..6410308 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createTableMessage.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableMessage.sql @@ -118,7 +118,7 @@ DROP TABLE IF EXISTS message.tb_message_channel CASCADE; CREATE TABLE message.tb_message_channel ( optsn VARCHAR(50) NOT NULL, -- 流水号 channel_id VARCHAR(50) NOT NULL, -- 渠道ID - channel_code VARCHAR(20) NOT NULL, -- 渠道编码:app/sms/email/wechat/dingtalk等 + channel_code VARCHAR(50) NOT NULL, -- 渠道编码:app/sms/email/wechat/dingtalk等 channel_name VARCHAR(100) NOT NULL, -- 渠道名称 channel_desc VARCHAR(255) DEFAULT NULL, -- 渠道描述 config JSON DEFAULT NULL, -- 渠道配置(如API密钥、服务器地址等) diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableUser.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableUser.sql index 32f5c2c..41d04f2 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createTableUser.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableUser.sql @@ -10,7 +10,8 @@ CREATE TABLE sys.tb_sys_user ( usercode VARCHAR(100) DEFAULT NULL, -- 用户code。sso同步数据获取 password VARCHAR(128) NOT NULL, -- 密码(建议存储 bcrypt/argon2 哈希) email VARCHAR(100), -- 电子邮件 - phone VARCHAR(20), -- 电话号码 + phone VARCHAR(500), -- 电话号码 + phone_hash VARCHAR(200), -- 电话hash wechat_id VARCHAR(50), -- 微信ID create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间(使用带时区时间) update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间(由触发器维护) diff --git a/urbanLifelineServ/.pids/auth.pid b/urbanLifelineServ/.pids/auth.pid new file mode 100644 index 0000000..1f3d8a7 --- /dev/null +++ b/urbanLifelineServ/.pids/auth.pid @@ -0,0 +1 @@ +1028 diff --git a/urbanLifelineServ/.pids/gateway.pid b/urbanLifelineServ/.pids/gateway.pid new file mode 100644 index 0000000..baccd03 --- /dev/null +++ b/urbanLifelineServ/.pids/gateway.pid @@ -0,0 +1 @@ +1003 diff --git a/urbanLifelineServ/.pids/system.pid b/urbanLifelineServ/.pids/system.pid new file mode 100644 index 0000000..b96bfec --- /dev/null +++ b/urbanLifelineServ/.pids/system.pid @@ -0,0 +1 @@ +1053 diff --git a/urbanLifelineServ/.vscode/launch.json b/urbanLifelineServ/.vscode/launch.json index a63fd42..731f71c 100644 --- a/urbanLifelineServ/.vscode/launch.json +++ b/urbanLifelineServ/.vscode/launch.json @@ -3,21 +3,162 @@ "configurations": [ { "type": "java", - "name": "SystemApp", + "name": "Gateway (8180)", "request": "launch", - "mainClass": "org.xyzh.SystemApp", + "mainClass": "org.xyzh.gateway.GatewayApplication", + "projectName": "gateway", + "cwd": "${workspaceFolder}/gateway", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8180"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Auth (8181)", + "request": "launch", + "mainClass": "org.xyzh.auth.AuthApp", + "projectName": "auth", + "cwd": "${workspaceFolder}/auth", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8181"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "System (8182)", + "request": "launch", + "mainClass": "org.xyzh.system.SystemApp", "projectName": "system", "cwd": "${workspaceFolder}/system", - "args": [ - "--spring.profiles.active=dev" - ], - "vmArgs": [ - "-Dspring.profiles.active=dev" - ], - "env": { - "SPRING_PROFILES_ACTIVE": "dev" - }, + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8182"], "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Log (8183)", + "request": "launch", + "mainClass": "org.xyzh.log.LogApp", + "projectName": "log", + "cwd": "${workspaceFolder}/log", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8183"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "File (8184)", + "request": "launch", + "mainClass": "org.xyzh.file.FileApp", + "projectName": "file", + "cwd": "${workspaceFolder}/file", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8184"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Message (8185)", + "request": "launch", + "mainClass": "org.xyzh.message.MessageApp", + "projectName": "message", + "cwd": "${workspaceFolder}/message", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8185"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Bidding (8186)", + "request": "launch", + "mainClass": "org.xyzh.bidding.BiddingApp", + "projectName": "bidding", + "cwd": "${workspaceFolder}/bidding", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8186"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Platform (8187)", + "request": "launch", + "mainClass": "org.xyzh.platform.PlatformApp", + "projectName": "platform", + "cwd": "${workspaceFolder}/platform", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8187"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Workcase (8188)", + "request": "launch", + "mainClass": "org.xyzh.workcase.WorkcaseApp", + "projectName": "workcase", + "cwd": "${workspaceFolder}/workcase", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8188"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Crontab (8189)", + "request": "launch", + "mainClass": "org.xyzh.crontab.CrontabApp", + "projectName": "crontab", + "cwd": "${workspaceFolder}/crontab", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8189"], + "console": "integratedTerminal" + }, + { + "type": "java", + "name": "Agent (8190)", + "request": "launch", + "mainClass": "org.xyzh.agent.AgentApp", + "projectName": "agent", + "cwd": "${workspaceFolder}/agent", + "args": ["--spring.profiles.active=dev"], + "vmArgs": ["-Dserver.port=8190"], + "console": "integratedTerminal" + } + ], + "compounds": [ + { + "name": "Core Services (Gateway + Auth + System)", + "configurations": [ + "Gateway (8180)", + "Auth (8181)", + "System (8182)" + ], + "stopAll": true, + "presentation": { + "hidden": false, + "group": "服务组合", + "order": 1 + } + }, + { + "name": "All Services", + "configurations": [ + "Gateway (8180)", + "Auth (8181)", + "System (8182)", + "Log (8183)", + "File (8184)", + "Message (8185)", + "Bidding (8186)", + "Platform (8187)", + "Workcase (8188)", + "Crontab (8189)", + "Agent (8190)" + ], + "stopAll": true, + "presentation": { + "hidden": false, + "group": "服务组合", + "order": 2 + } } ] } \ No newline at end of file diff --git a/urbanLifelineServ/.vscode/settings.json b/urbanLifelineServ/.vscode/settings.json index 5e320b2..d28f3d5 100644 --- a/urbanLifelineServ/.vscode/settings.json +++ b/urbanLifelineServ/.vscode/settings.json @@ -4,12 +4,31 @@ "maven.view": "hierarchical", "tabSize": 4, "java.debug.settings.onBuildFailureProceed": true, - "java.configuration.maven.userSettings": null, + "java.configuration.maven.userSettings": "", "java.import.maven.enabled": true, "java.project.referencedLibraries": [ "**/*.jar" ], "maven.terminal.useJavaHome": true, "java.configuration.runtimes": [], - "Codegeex.RepoIndex": true + "Codegeex.RepoIndex": true, + "terminal.integrated.defaultProfile.windows": "Command Prompt", + "terminal.integrated.profiles.windows": { + "PowerShell": { + "source": "PowerShell", + "args": ["-NoExit", "-Command", "chcp 65001"] + }, + "Command Prompt": { + "path": "cmd.exe", + "args": ["/k", "chcp 65001"] + }, + "Git Bash": { + "path": "F:\\Environment\\Git\\bin\\bash.exe", + "args": ["-i"], + "env": { + "LANG": "zh_CN.UTF-8", + "LC_ALL": "zh_CN.UTF-8" + } + } + }, } \ No newline at end of file diff --git a/urbanLifelineServ/Makefile b/urbanLifelineServ/Makefile new file mode 100644 index 0000000..fcfa494 --- /dev/null +++ b/urbanLifelineServ/Makefile @@ -0,0 +1,247 @@ +# ================================================ +# Urban Lifeline 微服务管理 Makefile +# ================================================ + +# 项目根目录 +PROJECT_ROOT := $(shell pwd) + +# Maven 命令 +MAVEN := mvn +MAVEN_OPTS := -Dmaven.test.skip=true + +# 服务列表 +SERVICES := gateway auth system log file message bidding platform workcase crontab agent + +# 服务端口映射 +PORT_gateway := 8080 +PORT_auth := 8081 +PORT_system := 8082 +PORT_log := 8083 +PORT_file := 8084 +PORT_message := 8085 +PORT_bidding := 8086 +PORT_platform := 8087 +PORT_workcase := 8088 +PORT_crontab := 8089 +PORT_agent := 8090 + +# 服务主类映射 +MAINCLASS_gateway := org.xyzh.gateway.GatewayApplication +MAINCLASS_auth := org.xyzh.auth.AuthApp +MAINCLASS_system := org.xyzh.system.SystemApp +MAINCLASS_log := org.xyzh.log.LogApp +MAINCLASS_file := org.xyzh.file.FileApp +MAINCLASS_message := org.xyzh.message.MessageApp +MAINCLASS_bidding := org.xyzh.bidding.BiddingApp +MAINCLASS_platform := org.xyzh.platform.PlatformApp +MAINCLASS_workcase := org.xyzh.workcase.WorkcaseApp +MAINCLASS_crontab := org.xyzh.crontab.CrontabApp +MAINCLASS_agent := org.xyzh.agent.AgentApp + +# PID 文件目录 +PID_DIR := $(PROJECT_ROOT)/.pids +LOG_DIR := $(PROJECT_ROOT)/.logs + +# 颜色定义 +COLOR_RESET := \033[0m +COLOR_GREEN := \033[0;32m +COLOR_YELLOW := \033[0;33m +COLOR_BLUE := \033[0;34m +COLOR_RED := \033[0;31m + +# ================================================ +# 帮助信息 +# ================================================ +.PHONY: help +help: + @echo "$(COLOR_BLUE)=============================================$(COLOR_RESET)" + @echo "$(COLOR_BLUE) Urban Lifeline 微服务管理工具$(COLOR_RESET)" + @echo "$(COLOR_BLUE)=============================================$(COLOR_RESET)" + @echo "" + @echo "$(COLOR_GREEN)构建命令:$(COLOR_RESET)" + @echo " make build - 构建所有服务" + @echo " make build- - 构建指定服务 (如: make build-system)" + @echo " make clean - 清理所有服务" + @echo "" + @echo "$(COLOR_GREEN)启动命令:$(COLOR_RESET)" + @echo " make start - 启动所有服务" + @echo " make start- - 启动指定服务 (如: make start-system)" + @echo " make start-core - 启动核心服务 (gateway, auth, system)" + @echo "" + @echo "$(COLOR_GREEN)停止命令:$(COLOR_RESET)" + @echo " make stop - 停止所有服务" + @echo " make stop- - 停止指定服务 (如: make stop-system)" + @echo "" + @echo "$(COLOR_GREEN)重启命令:$(COLOR_RESET)" + @echo " make restart - 重启所有服务" + @echo " make restart- - 重启指定服务 (如: make restart-system)" + @echo "" + @echo "$(COLOR_GREEN)状态查看:$(COLOR_RESET)" + @echo " make status - 查看所有服务状态" + @echo " make status- - 查看指定服务状态" + @echo " make logs- - 查看指定服务日志" + @echo "" + @echo "$(COLOR_GREEN)可用服务:$(COLOR_RESET)" + @echo " $(SERVICES)" + @echo "" + +# ================================================ +# 初始化目录 +# ================================================ +.PHONY: init-dirs +init-dirs: + @mkdir -p $(PID_DIR) + @mkdir -p $(LOG_DIR) + +# ================================================ +# 构建相关 +# ================================================ +.PHONY: build +build: init-dirs + @echo "$(COLOR_YELLOW)开始构建所有服务...$(COLOR_RESET)" + @$(MAVEN) clean install $(MAVEN_OPTS) + @echo "$(COLOR_GREEN)✓ 所有服务构建完成$(COLOR_RESET)" + +.PHONY: $(addprefix build-,$(SERVICES)) +$(addprefix build-,$(SERVICES)): build-%: + @echo "$(COLOR_YELLOW)开始构建 $* 服务...$(COLOR_RESET)" + @cd $(PROJECT_ROOT)/$* && $(MAVEN) clean install $(MAVEN_OPTS) + @echo "$(COLOR_GREEN)✓ $* 服务构建完成$(COLOR_RESET)" + +.PHONY: clean +clean: + @echo "$(COLOR_YELLOW)开始清理所有服务...$(COLOR_RESET)" + @$(MAVEN) clean + @rm -rf $(PID_DIR) + @rm -rf $(LOG_DIR) + @echo "$(COLOR_GREEN)✓ 清理完成$(COLOR_RESET)" + +# ================================================ +# 启动服务 +# ================================================ +.PHONY: start +start: init-dirs $(addprefix start-,$(SERVICES)) + @echo "$(COLOR_GREEN)✓ 所有服务启动完成$(COLOR_RESET)" + +.PHONY: start-core +start-core: init-dirs start-gateway start-auth start-system + @echo "$(COLOR_GREEN)✓ 核心服务启动完成$(COLOR_RESET)" + +.PHONY: $(addprefix start-,$(SERVICES)) +$(addprefix start-,$(SERVICES)): start-%: + @if [ -f "$(PID_DIR)/$*.pid" ] && kill -0 $$(cat $(PID_DIR)/$*.pid) 2>/dev/null; then \ + echo "$(COLOR_YELLOW)⚠ $* 服务已在运行中 (PID: $$(cat $(PID_DIR)/$*.pid))$(COLOR_RESET)"; \ + else \ + echo "$(COLOR_BLUE)启动 $* 服务...$(COLOR_RESET)"; \ + nohup $(MAVEN) -pl $* spring-boot:run > $(LOG_DIR)/$*.log 2>&1 & \ + echo $$! > $(PID_DIR)/$*.pid; \ + sleep 2; \ + if kill -0 $$(cat $(PID_DIR)/$*.pid) 2>/dev/null; then \ + echo "$(COLOR_GREEN)✓ $* 服务启动成功 (PID: $$(cat $(PID_DIR)/$*.pid), Port: $(PORT_$*))$(COLOR_RESET)"; \ + else \ + echo "$(COLOR_RED)✗ $* 服务启动失败$(COLOR_RESET)"; \ + rm -f $(PID_DIR)/$*.pid; \ + fi; \ + fi + +# ================================================ +# 停止服务 +# ================================================ +.PHONY: stop +stop: $(addprefix stop-,$(SERVICES)) + @echo "$(COLOR_GREEN)✓ 所有服务停止完成$(COLOR_RESET)" + +.PHONY: $(addprefix stop-,$(SERVICES)) +$(addprefix stop-,$(SERVICES)): stop-%: + @if [ -f "$(PID_DIR)/$*.pid" ]; then \ + PID=$$(cat $(PID_DIR)/$*.pid); \ + if kill -0 $$PID 2>/dev/null; then \ + echo "$(COLOR_YELLOW)停止 $* 服务 (PID: $$PID)...$(COLOR_RESET)"; \ + kill $$PID; \ + sleep 2; \ + if kill -0 $$PID 2>/dev/null; then \ + echo "$(COLOR_RED)强制停止 $* 服务...$(COLOR_RESET)"; \ + kill -9 $$PID; \ + fi; \ + rm -f $(PID_DIR)/$*.pid; \ + echo "$(COLOR_GREEN)✓ $* 服务已停止$(COLOR_RESET)"; \ + else \ + echo "$(COLOR_YELLOW)⚠ $* 服务未运行$(COLOR_RESET)"; \ + rm -f $(PID_DIR)/$*.pid; \ + fi; \ + else \ + echo "$(COLOR_YELLOW)⚠ $* 服务未运行$(COLOR_RESET)"; \ + fi + +# ================================================ +# 重启服务 +# ================================================ +.PHONY: restart +restart: stop start + @echo "$(COLOR_GREEN)✓ 所有服务重启完成$(COLOR_RESET)" + +.PHONY: $(addprefix restart-,$(SERVICES)) +$(addprefix restart-,$(SERVICES)): restart-%: stop-% start-% + @echo "$(COLOR_GREEN)✓ $* 服务重启完成$(COLOR_RESET)" + +# ================================================ +# 查看状态 +# ================================================ +.PHONY: status +status: + @echo "$(COLOR_BLUE)=============================================$(COLOR_RESET)" + @echo "$(COLOR_BLUE) 服务运行状态$(COLOR_RESET)" + @echo "$(COLOR_BLUE)=============================================$(COLOR_RESET)" + @for service in $(SERVICES); do \ + printf "%-15s" "$$service:"; \ + if [ -f "$(PID_DIR)/$$service.pid" ]; then \ + PID=$$(cat $(PID_DIR)/$$service.pid); \ + if kill -0 $$PID 2>/dev/null; then \ + echo "$(COLOR_GREEN)✓ Running (PID: $$PID)$(COLOR_RESET)"; \ + else \ + echo "$(COLOR_RED)✗ Stopped$(COLOR_RESET)"; \ + rm -f $(PID_DIR)/$$service.pid; \ + fi; \ + else \ + echo "$(COLOR_YELLOW)○ Not Started$(COLOR_RESET)"; \ + fi; \ + done + @echo "" + +.PHONY: $(addprefix status-,$(SERVICES)) +$(addprefix status-,$(SERVICES)): status-%: + @if [ -f "$(PID_DIR)/$*.pid" ]; then \ + PID=$$(cat $(PID_DIR)/$*.pid); \ + if kill -0 $$PID 2>/dev/null; then \ + echo "$(COLOR_GREEN)✓ $* 服务运行中 (PID: $$PID, Port: $(PORT_$*))$(COLOR_RESET)"; \ + else \ + echo "$(COLOR_RED)✗ $* 服务已停止$(COLOR_RESET)"; \ + fi; \ + else \ + echo "$(COLOR_YELLOW)○ $* 服务未启动$(COLOR_RESET)"; \ + fi + +# ================================================ +# 查看日志 +# ================================================ +.PHONY: $(addprefix logs-,$(SERVICES)) +$(addprefix logs-,$(SERVICES)): logs-%: + @if [ -f "$(LOG_DIR)/$*.log" ]; then \ + tail -f $(LOG_DIR)/$*.log; \ + else \ + echo "$(COLOR_YELLOW)⚠ $* 服务日志文件不存在$(COLOR_RESET)"; \ + fi + +# ================================================ +# 快捷命令 +# ================================================ +.PHONY: dev +dev: start-core + @echo "$(COLOR_GREEN)✓ 开发环境启动完成 (gateway, auth, system)$(COLOR_RESET)" + +.PHONY: prod +prod: start + @echo "$(COLOR_GREEN)✓ 生产环境启动完成$(COLOR_RESET)" + +# 默认目标 +.DEFAULT_GOAL := help diff --git a/urbanLifelineServ/agent/src/main/resources/application.yml b/urbanLifelineServ/agent/src/main/resources/application.yml new file mode 100644 index 0000000..93adf21 --- /dev/null +++ b/urbanLifelineServ/agent/src/main/resources/application.yml @@ -0,0 +1,77 @@ +# ================== Server ================== +server: + port: 8190 + servlet: + context-path: /urban-lifeline/agent + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: agent-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: 'AI代理服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-agent + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.agent.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/agent/src/main/resources/log4j2.xml b/urbanLifelineServ/agent/src/main/resources/log4j2.xml new file mode 100644 index 0000000..8d14e72 --- /dev/null +++ b/urbanLifelineServ/agent/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/auth/src/main/resources/application.yml b/urbanLifelineServ/auth/src/main/resources/application.yml index 1bc92a7..4fb023c 100644 --- a/urbanLifelineServ/auth/src/main/resources/application.yml +++ b/urbanLifelineServ/auth/src/main/resources/application.yml @@ -1,36 +1,84 @@ +# ================== Server ================== server: - port: 8081 + port: 8181 servlet: context-path: /urban-lifeline/auth +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: false # 认证服务自己不需要认证 + whitelist: + - /** # 认证服务的所有接口都放行 + +# ================== Spring ================== +spring: + application: + name: auth-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== springdoc: api-docs: - # 启用 API 文档 enabled: true - # API 文档路径 path: /v3/api-docs swagger-ui: - # 启用 Swagger UI enabled: true - # Swagger UI 路径 path: /swagger-ui.html - # 尝试请求超时时间(毫秒) try-it-out-enabled: true - # 显示请求执行时间 show-common-extensions: true - # 显示请求头部 show-extensions: true - # 显示模型 show-request-duration: true - # 过滤开关 filter: true - # 标签排序 tags-sorter: alpha - # 操作排序 operations-sorter: alpha - # 分组配置(可选) group-configs: - group: 'default' display-name: '认证服务 API' paths-to-match: '/**' +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-auth + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.auth.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== JWT Configuration ================== +jwt: + secret: urban-lifeline-secret-key-2025-xyzh + expiration: 86400 # 24小时(秒) + refresh-expiration: 604800 # 7天(秒) + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 + diff --git a/urbanLifelineServ/auth/src/main/resources/log4j2.xml b/urbanLifelineServ/auth/src/main/resources/log4j2.xml new file mode 100644 index 0000000..88a059a --- /dev/null +++ b/urbanLifelineServ/auth/src/main/resources/log4j2.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/bidding/src/main/resources/application.yml b/urbanLifelineServ/bidding/src/main/resources/application.yml new file mode 100644 index 0000000..37e82cb --- /dev/null +++ b/urbanLifelineServ/bidding/src/main/resources/application.yml @@ -0,0 +1,77 @@ +# ================== Server ================== +server: + port: 8186 + servlet: + context-path: /urban-lifeline/bidding + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: bidding-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: '招投标服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-bidding + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.bidding.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/bidding/src/main/resources/log4j2.xml b/urbanLifelineServ/bidding/src/main/resources/log4j2.xml new file mode 100644 index 0000000..a2a1279 --- /dev/null +++ b/urbanLifelineServ/bidding/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/annotation/resovler/HttpLoginArgumentResolver.java b/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/annotation/resovler/HttpLoginArgumentResolver.java index e9b01c4..1b94d02 100644 --- a/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/annotation/resovler/HttpLoginArgumentResolver.java +++ b/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/annotation/resovler/HttpLoginArgumentResolver.java @@ -10,8 +10,8 @@ import org.springframework.web.method.support.ModelAndViewContainer; import org.xyzh.common.auth.annotation.HttpLogin; import org.xyzh.common.auth.token.TokenParser; import org.xyzh.common.core.domain.LoginDomain; +import org.xyzh.common.redis.service.RedisService; import org.xyzh.common.utils.NonUtils; -import org.xyzh.redis.service.RedisService; import jakarta.servlet.http.HttpServletRequest; diff --git a/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/config/SecurityConfig.java b/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/config/SecurityConfig.java index 2f94d79..9d1628d 100644 --- a/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/config/SecurityConfig.java +++ b/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/config/SecurityConfig.java @@ -7,16 +7,26 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.xyzh.common.auth.filter.JwtAuthenticationFilter; import org.xyzh.common.auth.token.TokenParser; -import org.xyzh.redis.service.RedisService; +import org.xyzh.common.redis.service.RedisService; @Configuration @EnableMethodSecurity public class SecurityConfig { + /** + * 密码编码器 - 用于用户密码加密(使用 BCrypt) + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + /** * JWT 认证过滤器 - 仅在非 Gateway 模式下启用 * 当 auth.gateway-mode=false 或未配置时使用 diff --git a/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/filter/JwtAuthenticationFilter.java b/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/filter/JwtAuthenticationFilter.java index 631c65d..1ae5b9a 100644 --- a/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/filter/JwtAuthenticationFilter.java +++ b/urbanLifelineServ/common/common-auth/src/main/java/org/xyzh/common/auth/filter/JwtAuthenticationFilter.java @@ -20,7 +20,7 @@ import org.xyzh.common.auth.token.TokenParser; import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.LoginDomain; import org.xyzh.common.dto.sys.TbSysPermissionDTO; -import org.xyzh.redis.service.RedisService; +import org.xyzh.common.redis.service.RedisService; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; diff --git a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java index 0a7501b..99c15e6 100644 --- a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java +++ b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java @@ -29,9 +29,12 @@ public class TbSysUserDTO extends BaseDTO { @Schema(description = "邮箱") private String email; - @Schema(description = "手机") + @Schema(description = "手机(加密)") private String phone; + @Schema(description = "手机号哈希") + private String phone_hash; + @Schema(description = "微信ID") private String wechatId; diff --git a/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/config/FastJson2JsonRedisSerializer.java b/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/config/FastJson2JsonRedisSerializer.java similarity index 97% rename from urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/config/FastJson2JsonRedisSerializer.java rename to urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/config/FastJson2JsonRedisSerializer.java index 67a7aa5..73c6f8f 100644 --- a/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/config/FastJson2JsonRedisSerializer.java +++ b/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/config/FastJson2JsonRedisSerializer.java @@ -1,4 +1,4 @@ -package org.xyzh.redis.config; +package org.xyzh.common.redis.config; import org.xyzh.common.core.constant.Constants; import java.nio.charset.Charset; diff --git a/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/config/RedisConfig.java b/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/config/RedisConfig.java similarity index 97% rename from urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/config/RedisConfig.java rename to urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/config/RedisConfig.java index 8db4d71..b393362 100644 --- a/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/config/RedisConfig.java +++ b/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/config/RedisConfig.java @@ -1,4 +1,4 @@ -package org.xyzh.redis.config; +package org.xyzh.common.redis.config; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; diff --git a/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/service/RedisService.java b/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/service/RedisService.java similarity index 99% rename from urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/service/RedisService.java rename to urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/service/RedisService.java index cc25606..9992088 100644 --- a/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/redis/service/RedisService.java +++ b/urbanLifelineServ/common/common-redis/src/main/java/org/xyzh/common/redis/service/RedisService.java @@ -1,4 +1,4 @@ -package org.xyzh.redis.service; +package org.xyzh.common.redis.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; diff --git a/urbanLifelineServ/common/common-utils/pom.xml b/urbanLifelineServ/common/common-utils/pom.xml index 494c854..8c855aa 100644 --- a/urbanLifelineServ/common/common-utils/pom.xml +++ b/urbanLifelineServ/common/common-utils/pom.xml @@ -30,5 +30,19 @@ org.apache.poi poi-ooxml + + + + org.mybatis + mybatis + provided + + + + + org.springframework.boot + spring-boot-starter + provided + \ No newline at end of file diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/AesEncryptUtil.java b/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/AesEncryptUtil.java new file mode 100644 index 0000000..1c422a9 --- /dev/null +++ b/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/AesEncryptUtil.java @@ -0,0 +1,190 @@ +package org.xyzh.common.utils.crypto; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.Base64; + +/** + * AES-256-GCM 敏感数据加密工具类 + * 用于加密手机号、身份证号等敏感信息 + * + * @author yslg + * @since 2025-12-05 + */ +@Component +public class AesEncryptUtil { + + private static final String ALGORITHM = "AES"; + private static final String TRANSFORMATION = "AES/GCM/NoPadding"; + private static final int KEY_SIZE = 256; // AES-256 + private static final int GCM_IV_LENGTH = 12; // GCM 推荐 IV 长度 + private static final int GCM_TAG_LENGTH = 128; // GCM 认证标签长度 + + private SecretKey secretKey; + + /** + * 从配置文件读取密钥,如果没有则生成新密钥 + */ + public AesEncryptUtil(@Value("${security.aes.secret-key:}") String secretKeyString) { + if (secretKeyString == null || secretKeyString.isEmpty()) { + // 生产环境应该从配置中心或密钥管理系统获取 + this.secretKey = generateKey(); + System.err.println("警告: 未配置 AES 密钥,使用临时生成的密钥。生产环境请配置 security.aes.secret-key"); + } else { + byte[] decodedKey = Base64.getDecoder().decode(secretKeyString); + this.secretKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, ALGORITHM); + } + } + + /** + * 生成 AES-256 密钥 + */ + public static SecretKey generateKey() { + try { + KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM); + keyGen.init(KEY_SIZE, new SecureRandom()); + return keyGen.generateKey(); + } catch (Exception e) { + throw new RuntimeException("生成 AES 密钥失败", e); + } + } + + /** + * 将密钥转换为 Base64 字符串(用于配置) + */ + public static String keyToString(SecretKey key) { + return Base64.getEncoder().encodeToString(key.getEncoded()); + } + + /** + * 加密字符串 + * + * @param plaintext 明文 + * @return Base64 编码的密文(包含 IV) + */ + public String encrypt(String plaintext) { + if (plaintext == null || plaintext.isEmpty()) { + return plaintext; + } + + try { + // 生成随机 IV + byte[] iv = new byte[GCM_IV_LENGTH]; + new SecureRandom().nextBytes(iv); + + // 初始化加密器 + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec); + + // 加密 + byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); + + // 将 IV 和密文组合在一起:[IV(12字节)][密文] + ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + ciphertext.length); + byteBuffer.put(iv); + byteBuffer.put(ciphertext); + + // Base64 编码 + return Base64.getEncoder().encodeToString(byteBuffer.array()); + } catch (Exception e) { + throw new RuntimeException("AES 加密失败", e); + } + } + + /** + * 解密字符串 + * + * @param ciphertext Base64 编码的密文(包含 IV) + * @return 明文 + */ + public String decrypt(String ciphertext) { + if (ciphertext == null || ciphertext.isEmpty()) { + return ciphertext; + } + + try { + // Base64 解码 + byte[] decoded = Base64.getDecoder().decode(ciphertext); + + // 提取 IV 和密文 + ByteBuffer byteBuffer = ByteBuffer.wrap(decoded); + byte[] iv = new byte[GCM_IV_LENGTH]; + byteBuffer.get(iv); + byte[] ciphertextBytes = new byte[byteBuffer.remaining()]; + byteBuffer.get(ciphertextBytes); + + // 初始化解密器 + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); + cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec); + + // 解密 + byte[] plaintext = cipher.doFinal(ciphertextBytes); + return new String(plaintext, StandardCharsets.UTF_8); + } catch (Exception e) { + throw new RuntimeException("AES 解密失败", e); + } + } + + /** + * 加密手机号(保留前3后4位) + * 例如:13812345678 -> 138****5678 + * 实际存储:加密后的完整手机号 + */ + public String encryptPhone(String phone) { + return encrypt(phone); + } + + /** + * 解密手机号 + */ + public String decryptPhone(String encryptedPhone) { + return decrypt(encryptedPhone); + } + + /** + * 加密身份证号(保留前6后4位) + * 例如:110101199001011234 -> 110101********1234 + * 实际存储:加密后的完整身份证号 + */ + public String encryptIdCard(String idCard) { + return encrypt(idCard); + } + + /** + * 解密身份证号 + */ + public String decryptIdCard(String encryptedIdCard) { + return decrypt(encryptedIdCard); + } + + /** + * 脱敏显示手机号 + */ + public static String maskPhone(String phone) { + if (phone == null || phone.length() < 11) { + return phone; + } + return phone.substring(0, 3) + "****" + phone.substring(7); + } + + /** + * 脱敏显示身份证号 + */ + public static String maskIdCard(String idCard) { + if (idCard == null || idCard.length() < 18) { + return idCard; + } + return idCard.substring(0, 6) + "********" + idCard.substring(14); + } +} diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/EncryptedStringTypeHandler.java b/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/EncryptedStringTypeHandler.java new file mode 100644 index 0000000..17b9b4f --- /dev/null +++ b/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/EncryptedStringTypeHandler.java @@ -0,0 +1,76 @@ +package org.xyzh.common.utils.crypto; + +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedTypes; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * MyBatis 加密字段类型处理器 + * 自动对数据库字段进行加密/解密 + * + * 使用方式: + * 在实体类字段上添加注解: + * @TableField(typeHandler = EncryptedStringTypeHandler.class) + * private String phone; + * + * @author yslg + * @since 2025-12-05 + */ +@MappedTypes({String.class}) +public class EncryptedStringTypeHandler extends BaseTypeHandler { + + private static AesEncryptUtil aesEncryptUtil; + + /** + * 设置加密工具(由 Spring 注入) + */ + public static void setAesEncryptUtil(AesEncryptUtil util) { + aesEncryptUtil = util; + } + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { + // 写入数据库时加密 + if (aesEncryptUtil != null && parameter != null) { + ps.setString(i, aesEncryptUtil.encrypt(parameter)); + } else { + ps.setString(i, parameter); + } + } + + @Override + public String getNullableResult(ResultSet rs, String columnName) throws SQLException { + // 从数据库读取时解密 + String encrypted = rs.getString(columnName); + return decrypt(encrypted); + } + + @Override + public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + String encrypted = rs.getString(columnIndex); + return decrypt(encrypted); + } + + @Override + public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + String encrypted = cs.getString(columnIndex); + return decrypt(encrypted); + } + + private String decrypt(String encrypted) { + if (aesEncryptUtil != null && encrypted != null && !encrypted.isEmpty()) { + try { + return aesEncryptUtil.decrypt(encrypted); + } catch (Exception e) { + // 如果解密失败,可能是旧数据,返回原值 + return encrypted; + } + } + return encrypted; + } +} diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/SensitiveDataUtil.java b/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/SensitiveDataUtil.java new file mode 100644 index 0000000..abcaeba --- /dev/null +++ b/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/SensitiveDataUtil.java @@ -0,0 +1,110 @@ +package org.xyzh.common.utils.crypto; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.Base64; + +/** + * 敏感数据处理工具类 + * 支持加密存储 + 哈希查询 + * + * 数据库设计: + * - phone_encrypted: 加密后的完整手机号(用于显示和解密) + * - phone_hash: 手机号的哈希值(用于查询,建立索引) + * + * @author yslg + * @since 2025-12-05 + */ +@Component +public class SensitiveDataUtil { + + @Autowired + private AesEncryptUtil aesEncryptUtil; + + /** + * 生成 SHA-256 哈希值(用于查询索引) + */ + public String hash(String plaintext) { + if (plaintext == null || plaintext.isEmpty()) { + return null; + } + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hashBytes = digest.digest(plaintext.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(hashBytes); + } catch (Exception e) { + throw new RuntimeException("哈希计算失败", e); + } + } + + /** + * 处理手机号:返回加密值和哈希值 + */ + public PhoneData processPhone(String phone) { + if (phone == null || phone.isEmpty()) { + return new PhoneData(null, null); + } + return new PhoneData( + aesEncryptUtil.encryptPhone(phone), + hash(phone) + ); + } + + /** + * 处理身份证号:返回加密值和哈希值 + */ + public IdCardData processIdCard(String idCard) { + if (idCard == null || idCard.isEmpty()) { + return new IdCardData(null, null); + } + return new IdCardData( + aesEncryptUtil.encryptIdCard(idCard), + hash(idCard) + ); + } + + /** + * 手机号数据对象 + */ + public static class PhoneData { + private String encrypted; // 加密后的值(存储在 phone_encrypted) + private String hash; // 哈希值(存储在 phone_hash,用于查询) + + public PhoneData(String encrypted, String hash) { + this.encrypted = encrypted; + this.hash = hash; + } + + public String getEncrypted() { + return encrypted; + } + + public String getHash() { + return hash; + } + } + + /** + * 身份证号数据对象 + */ + public static class IdCardData { + private String encrypted; // 加密后的值 + private String hash; // 哈希值 + + public IdCardData(String encrypted, String hash) { + this.encrypted = encrypted; + this.hash = hash; + } + + public String getEncrypted() { + return encrypted; + } + + public String getHash() { + return hash; + } + } +} diff --git a/urbanLifelineServ/crontab/src/main/resources/application.yml b/urbanLifelineServ/crontab/src/main/resources/application.yml new file mode 100644 index 0000000..bbe7a44 --- /dev/null +++ b/urbanLifelineServ/crontab/src/main/resources/application.yml @@ -0,0 +1,68 @@ +# ================== Server ================== +server: + port: 8189 + servlet: + context-path: /urban-lifeline/crontab + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: false # 定时任务服务通常不需要认证 + +# ================== Spring ================== +spring: + application: + name: crontab-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: '定时任务服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-crontab + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.crontab.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/crontab/src/main/resources/log4j2.xml b/urbanLifelineServ/crontab/src/main/resources/log4j2.xml new file mode 100644 index 0000000..d4a24d1 --- /dev/null +++ b/urbanLifelineServ/crontab/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/file/pom.xml b/urbanLifelineServ/file/pom.xml index dd20e01..5a192a9 100644 --- a/urbanLifelineServ/file/pom.xml +++ b/urbanLifelineServ/file/pom.xml @@ -34,6 +34,18 @@ org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + org.springframework.boot + spring-boot-starter-log4j2 diff --git a/urbanLifelineServ/file/src/main/resources/application.yml b/urbanLifelineServ/file/src/main/resources/application.yml new file mode 100644 index 0000000..a390381 --- /dev/null +++ b/urbanLifelineServ/file/src/main/resources/application.yml @@ -0,0 +1,84 @@ +# ================== Server ================== +server: + port: 8184 + servlet: + context-path: /urban-lifeline/file + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: file-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + + # ================== 文件上传配置 ================== + servlet: + multipart: + enabled: true + max-file-size: 100MB + max-request-size: 100MB + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: '文件服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-file + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.file.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/file/src/main/resources/log4j2.xml b/urbanLifelineServ/file/src/main/resources/log4j2.xml new file mode 100644 index 0000000..638321e --- /dev/null +++ b/urbanLifelineServ/file/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/gateway/pom.xml b/urbanLifelineServ/gateway/pom.xml index ea18b38..f356b57 100644 --- a/urbanLifelineServ/gateway/pom.xml +++ b/urbanLifelineServ/gateway/pom.xml @@ -23,18 +23,63 @@ org.springframework.cloud spring-cloud-starter-gateway + + + org.springframework.boot + spring-boot-starter-logging + + + + org.springframework.cloud + spring-cloud-gateway-server + + + + + + + org.springframework.cloud + spring-cloud-gateway-server-webflux com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery + + + org.springframework.boot + spring-boot-starter-logging + + + com.alibaba.nacos + nacos-logback-adapter-12 + + + com.alibaba.nacos + logback-adapter + + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config + + + org.springframework.boot + spring-boot-starter-logging + + + com.alibaba.nacos + nacos-logback-adapter-12 + + + com.alibaba.nacos + logback-adapter + + @@ -71,12 +116,12 @@ org.springframework.boot spring-boot-starter-actuator - - - - - org.springframework.boot - spring-boot-starter-log4j2 + + + org.springframework.boot + spring-boot-starter-logging + + diff --git a/urbanLifelineServ/gateway/src/main/java/org/xyzh/gateway/GatewayApplication.java b/urbanLifelineServ/gateway/src/main/java/org/xyzh/gateway/GatewayApplication.java index b21c151..5fde7db 100644 --- a/urbanLifelineServ/gateway/src/main/java/org/xyzh/gateway/GatewayApplication.java +++ b/urbanLifelineServ/gateway/src/main/java/org/xyzh/gateway/GatewayApplication.java @@ -2,15 +2,31 @@ package org.xyzh.gateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.xyzh.common.auth.config.SecurityConfig; /** * @description Gateway 网关启动类 * @author yslg * @since 2025-12-02 */ -@SpringBootApplication +@SpringBootApplication(exclude = { + DataSourceAutoConfiguration.class // Gateway 不需要数据源 +}) @EnableDiscoveryClient +@ComponentScan( + basePackages = { + "org.xyzh.gateway", // 当前 gateway 模块 + "org.xyzh.common" // 公共模块(包括 common-auth) + }, + excludeFilters = { + // 排除 Spring MVC 的 SecurityConfig,Gateway 使用 WebFlux Security + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class) + } +) public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); diff --git a/urbanLifelineServ/gateway/src/main/resources/application-dev.yml b/urbanLifelineServ/gateway/src/main/resources/application-dev.yml index c5515b9..9126805 100644 --- a/urbanLifelineServ/gateway/src/main/resources/application-dev.yml +++ b/urbanLifelineServ/gateway/src/main/resources/application-dev.yml @@ -1,14 +1,16 @@ spring: cloud: gateway: - routes: - # 开发环境可以添加更详细的路由配置或测试路由 - - # Nacos 管理界面路由(开发专用) - - id: nacos-console - uri: http://${NACOS_SERVER_ADDR:localhost:8848} - predicates: - - Path=/nacos/** + server: + webflux: + routes: + # 开发环境可以添加更详细的路由配置或测试路由 + + # Nacos 管理界面路由(开发专用) + - id: nacos-console + uri: http://${NACOS_SERVER_ADDR:localhost:8848} + predicates: + - Path=/nacos/** # 开发环境日志 logging: diff --git a/urbanLifelineServ/gateway/src/main/resources/application.yml b/urbanLifelineServ/gateway/src/main/resources/application.yml index dd92629..6239462 100644 --- a/urbanLifelineServ/gateway/src/main/resources/application.yml +++ b/urbanLifelineServ/gateway/src/main/resources/application.yml @@ -1,10 +1,14 @@ server: - port: 8080 + port: 8180 spring: application: name: gateway-service + # Gateway 必须使用 reactive 模式(WebFlux),不能使用 Spring MVC + main: + web-application-type: reactive + # 配置中心 cloud: nacos: @@ -18,71 +22,127 @@ spring: namespace: dev group: DEFAULT_GROUP - # Gateway 路由配置 + # Gateway 路由配置(使用新的 webflux 配置路径) gateway: - # 服务发现路由(自动路由) - discovery: - locator: - enabled: false # 关闭自动路由,使用手动配置 - - # 手动配置路由 - routes: - # ==================== 认证服务路由 ==================== - - id: auth-service - uri: lb://auth-service - predicates: - - Path=/auth/** - filters: - - StripPrefix=1 - - name: RequestRateLimiter - args: - redis-rate-limiter.replenishRate: 100 - redis-rate-limiter.burstCapacity: 200 - - # ==================== 系统服务路由 ==================== - - id: system-service - uri: lb://system-service - predicates: - - Path=/system/** - filters: - - StripPrefix=1 - - # ==================== 日志服务路由 ==================== - - id: log-service - uri: lb://log-service - predicates: - - Path=/log/** - filters: - - StripPrefix=1 - - # ==================== 文件服务路由 ==================== - - id: file-service - uri: lb://file-service - predicates: - - Path=/file/** - filters: - - StripPrefix=1 - - # 全局跨域配置 - globalcors: - cors-configurations: - '[/**]': - allowedOriginPatterns: "*" - allowedMethods: - - GET - - POST - - PUT - - DELETE - - OPTIONS - allowedHeaders: "*" - allowCredentials: true - maxAge: 3600 - + server: + webflux: + # 服务发现路由(自动路由) + discovery: + locator: + enabled: false # 关闭自动路由,使用手动配置 + + # 手动配置路由 + routes: + # ==================== 认证服务路由 ==================== + - id: auth-service + uri: lb://auth-service + predicates: + - Path=/auth/** + filters: + - RewritePath=/auth/(?.*), /urban-lifeline/auth/$\{segment} + - name: RequestRateLimiter + args: + redis-rate-limiter.replenishRate: 100 + redis-rate-limiter.burstCapacity: 200 + + # ==================== 系统服务路由 ==================== + - id: system-service + uri: lb://system-service + predicates: + - Path=/system/** + filters: + - RewritePath=/system/(?.*), /urban-lifeline/system/$\{segment} + + # ==================== 日志服务路由 ==================== + - id: log-service + uri: lb://log-service + predicates: + - Path=/log/** + filters: + - RewritePath=/log/(?.*), /urban-lifeline/log/$\{segment} + + # ==================== 文件服务路由 ==================== + - id: file-service + uri: lb://file-service + predicates: + - Path=/file/** + filters: + - RewritePath=/file/(?.*), /urban-lifeline/file/$\{segment} + + # ==================== 消息服务路由 ==================== + - id: message-service + uri: lb://message-service + predicates: + - Path=/message/** + filters: + - RewritePath=/message/(?.*), /urban-lifeline/message/$\{segment} + + # ==================== 招投标服务路由 ==================== + - id: bidding-service + uri: lb://bidding-service + predicates: + - Path=/bidding/** + filters: + - RewritePath=/bidding/(?.*), /urban-lifeline/bidding/$\{segment} + + # ==================== 平台服务路由 ==================== + - id: platform-service + uri: lb://platform-service + predicates: + - Path=/platform/** + filters: + - RewritePath=/platform/(?.*), /urban-lifeline/platform/$\{segment} + + # ==================== 工单服务路由 ==================== + - id: workcase-service + uri: lb://workcase-service + predicates: + - Path=/workcase/** + filters: + - RewritePath=/workcase/(?.*), /urban-lifeline/workcase/$\{segment} + + # ==================== 定时任务服务路由 ==================== + - id: crontab-service + uri: lb://crontab-service + predicates: + - Path=/crontab/** + filters: + - RewritePath=/crontab/(?.*), /urban-lifeline/crontab/$\{segment} + + # ==================== AI Agent 服务路由 ==================== + - id: agent-service + uri: lb://agent-service + predicates: + - Path=/agent/** + filters: + - RewritePath=/agent/(?.*), /urban-lifeline/agent/$\{segment} + + # 全局跨域配置 + globalcors: + cors-configurations: + '[/**]': + allowedOriginPatterns: "*" + allowedMethods: + - GET + - POST + - PUT + - DELETE + - OPTIONS + allowedHeaders: "*" + allowCredentials: true + maxAge: 3600 + datasource: + # 按你的实际库名改一下,比如 urban-lifeline_system + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline # 换成你的 PG 库名 + username: postgres # PG 用户 + password: postgres # PG 密码 + driver-class-name: org.postgresql.Driver # Redis 配置(用于限流、缓存) data: redis: host: ${REDIS_HOST:localhost} port: ${REDIS_PORT:6379} + password: 123456 database: 0 timeout: 5000ms lettuce: @@ -95,6 +155,7 @@ spring: # 认证配置 auth: enabled: true + gateway-mode: true token-header: Authorization token-prefix: "Bearer " # 认证接口白名单(login/logout/captcha/refresh) @@ -124,10 +185,9 @@ management: health: show-details: always -# 日志配置 +# 日志配置(详细配置见 log4j2.xml) logging: - level: - org.springframework.cloud.gateway: DEBUG - org.xyzh.gateway: DEBUG - pattern: - console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 \ No newline at end of file diff --git a/urbanLifelineServ/gateway/src/main/resources/log4j2.xml b/urbanLifelineServ/gateway/src/main/resources/log4j2.xml new file mode 100644 index 0000000..26ac111 --- /dev/null +++ b/urbanLifelineServ/gateway/src/main/resources/log4j2.xml @@ -0,0 +1,66 @@ + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + logs + gateway + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/log/pom.xml b/urbanLifelineServ/log/pom.xml index 14b8078..44b9653 100644 --- a/urbanLifelineServ/log/pom.xml +++ b/urbanLifelineServ/log/pom.xml @@ -35,6 +35,18 @@ org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + org.springframework.boot + spring-boot-starter-log4j2 diff --git a/urbanLifelineServ/log/src/main/resources/application.yml b/urbanLifelineServ/log/src/main/resources/application.yml index 2527e48..34b1e9d 100644 --- a/urbanLifelineServ/log/src/main/resources/application.yml +++ b/urbanLifelineServ/log/src/main/resources/application.yml @@ -1,36 +1,85 @@ +# ================== Server ================== server: - port: 8083 + port: 8183 servlet: context-path: /urban-lifeline/log +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: log-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== springdoc: api-docs: - # 启用 API 文档 enabled: true - # API 文档路径 path: /v3/api-docs swagger-ui: - # 启用 Swagger UI enabled: true - # Swagger UI 路径 path: /swagger-ui.html - # 尝试请求超时时间(毫秒) try-it-out-enabled: true - # 显示请求执行时间 show-common-extensions: true - # 显示请求头部 show-extensions: true - # 显示模型 show-request-duration: true - # 过滤开关 filter: true - # 标签排序 tags-sorter: alpha - # 操作排序 operations-sorter: alpha - # 分组配置(可选) group-configs: - group: 'default' display-name: '日志服务 API' paths-to-match: '/**' +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-log + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.log.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 + diff --git a/urbanLifelineServ/log/src/main/resources/log4j2.xml b/urbanLifelineServ/log/src/main/resources/log4j2.xml new file mode 100644 index 0000000..ff80139 --- /dev/null +++ b/urbanLifelineServ/log/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/message/src/main/resources/application.yml b/urbanLifelineServ/message/src/main/resources/application.yml new file mode 100644 index 0000000..c8f7f9f --- /dev/null +++ b/urbanLifelineServ/message/src/main/resources/application.yml @@ -0,0 +1,77 @@ +# ================== Server ================== +server: + port: 8185 + servlet: + context-path: /urban-lifeline/message + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: message-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: '消息服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-message + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.message.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/message/src/main/resources/log4j2.xml b/urbanLifelineServ/message/src/main/resources/log4j2.xml new file mode 100644 index 0000000..422b707 --- /dev/null +++ b/urbanLifelineServ/message/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/platform/src/main/resources/application.yml b/urbanLifelineServ/platform/src/main/resources/application.yml new file mode 100644 index 0000000..76900e3 --- /dev/null +++ b/urbanLifelineServ/platform/src/main/resources/application.yml @@ -0,0 +1,77 @@ +# ================== Server ================== +server: + port: 8187 + servlet: + context-path: /urban-lifeline/platform + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: platform-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: '平台服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-platform + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.platform.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/platform/src/main/resources/log4j2.xml b/urbanLifelineServ/platform/src/main/resources/log4j2.xml new file mode 100644 index 0000000..c1013b2 --- /dev/null +++ b/urbanLifelineServ/platform/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/pom.xml b/urbanLifelineServ/pom.xml index 46b0f03..5cee6ec 100644 --- a/urbanLifelineServ/pom.xml +++ b/urbanLifelineServ/pom.xml @@ -58,6 +58,7 @@ 2.0.13 + 3.5.16 3.0.5 3.5.14 @@ -168,6 +169,12 @@ HikariCP ${hikaricp.version} + + org.mybatis + mybatis + ${mybatis.version} + provided + @@ -386,22 +393,6 @@ org.springframework.boot spring-boot-starter-security - - - - org.springframework.boot - spring-boot-starter-web - - - - - org.springdoc - springdoc-openapi-starter-webmvc-ui - - - org.springframework.boot - spring-boot-starter-web - org.springframework.boot @@ -409,15 +400,59 @@ + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + org.apache.dubbo dubbo-spring-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + org.apache.dubbo dubbo-nacos-spring-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + @@ -425,11 +460,6 @@ org.postgresql postgresql - - - org.springframework.boot - spring-boot-starter-log4j2 - com.alibaba.fastjson2 fastjson2 diff --git a/urbanLifelineServ/system/pom.xml b/urbanLifelineServ/system/pom.xml index 335d533..b7dde52 100644 --- a/urbanLifelineServ/system/pom.xml +++ b/urbanLifelineServ/system/pom.xml @@ -29,66 +29,58 @@ org.xyzh.apis api-system - + org.springframework.boot spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-logging + + - - - org.springframework.boot - spring-boot-starter-web - - - - - org.apache.dubbo - dubbo-spring-boot-starter - - - - - org.apache.dubbo - dubbo-nacos-spring-boot-starter - - - + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.nacos + nacos-logback-adapter-12 + + + com.alibaba.nacos + logback-adapter + + + org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis.spring.boot.version} - + com.baomidou mybatis-plus-boot-starter ${mybatis.plus.version} - org.mybatis mybatis-spring - + org.mybatis mybatis-spring ${mybatis.spring.version} - - - - org.springframework.boot - spring-boot-starter-security - \ No newline at end of file diff --git a/urbanLifelineServ/system/src/main/resources/application-dev.yml b/urbanLifelineServ/system/src/main/resources/application-dev.yml index d369110..3d7566c 100644 --- a/urbanLifelineServ/system/src/main/resources/application-dev.yml +++ b/urbanLifelineServ/system/src/main/resources/application-dev.yml @@ -40,9 +40,9 @@ spring: # ================== DataSource ================== datasource: # 按你的实际库名改一下,比如 urban-lifeline_system - url: jdbc:postgresql://127.0.0.1:5432/urban-lifeline # 换成你的 PG 库名 + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline # 换成你的 PG 库名 username: postgres # PG 用户 - password: "123456" # PG 密码 + password: postgres # PG 密码 driver-class-name: org.postgresql.Driver # ================== Redis ================== diff --git a/urbanLifelineServ/system/src/main/resources/application.yml b/urbanLifelineServ/system/src/main/resources/application.yml index d369110..3892e25 100644 --- a/urbanLifelineServ/system/src/main/resources/application.yml +++ b/urbanLifelineServ/system/src/main/resources/application.yml @@ -1,6 +1,6 @@ # ================== Server ================== server: - port: 8082 + port: 8182 servlet: context-path: /urban-lifeline/system # ================== Auth ==================== @@ -34,15 +34,19 @@ urban-lifeline: # - /public/** # - /api/public/** +security: + aes: + secret-key: 1234567890qwer + # ================== Spring ================== spring: # ================== DataSource ================== datasource: # 按你的实际库名改一下,比如 urban-lifeline_system - url: jdbc:postgresql://127.0.0.1:5432/urban-lifeline # 换成你的 PG 库名 + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline # 换成你的 PG 库名 username: postgres # PG 用户 - password: "123456" # PG 密码 + password: postgres # PG 密码 driver-class-name: org.postgresql.Driver # ================== Redis ================== @@ -51,7 +55,7 @@ spring: host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 port: 6379 database: 0 - # password: "" # 如果有密码就填上,没密码可以去掉这一行 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 # ================== SpringDoc ================== springdoc: api-docs: @@ -97,3 +101,10 @@ dubbo: mybatis-plus: mapper-locations: classpath:mapper/*.xml type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/system/src/main/resources/log4j2.xml b/urbanLifelineServ/system/src/main/resources/log4j2.xml new file mode 100644 index 0000000..50f2d7d --- /dev/null +++ b/urbanLifelineServ/system/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urbanLifelineServ/workcase/pom.xml b/urbanLifelineServ/workcase/pom.xml index 8345861..4d902d2 100644 --- a/urbanLifelineServ/workcase/pom.xml +++ b/urbanLifelineServ/workcase/pom.xml @@ -10,7 +10,7 @@ org.xyzh - case + workcase 1.0.0 diff --git a/urbanLifelineServ/workcase/src/main/resources/application.yml b/urbanLifelineServ/workcase/src/main/resources/application.yml new file mode 100644 index 0000000..6a4355b --- /dev/null +++ b/urbanLifelineServ/workcase/src/main/resources/application.yml @@ -0,0 +1,77 @@ +# ================== Server ================== +server: + port: 8188 + servlet: + context-path: /urban-lifeline/workcase + +# ================== Auth ==================== +urban-lifeline: + auth: + enabled: true + whitelist: + - /swagger-ui/** + - /swagger-ui.html + - /v3/api-docs/** + - /webjars/** + - /favicon.ico + - /error + - /actuator/health + - /actuator/info + +# ================== Spring ================== +spring: + application: + name: workcase-service + + # ================== DataSource ================== + datasource: + url: jdbc:postgresql://127.0.0.1:5432/urban_lifeline + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + + # ================== Redis ================== + data: + redis: + host: 127.0.0.1 # 如果是 docker 跑的 redis,按实际 host / 端口改 + port: 6379 + database: 0 + password: 123456 # 如果有密码就填上,没密码可以去掉这一行 + +# ================== SpringDoc ================== +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui.html + group-configs: + - group: 'default' + display-name: '工单服务 API' + paths-to-match: '/**' + +# ================== Dubbo + Nacos ================== +dubbo: + application: + name: urban-lifeline-workcase + qos-enable: false + protocol: + name: dubbo + port: -1 + registry: + address: nacos://127.0.0.1:8848 + scan: + base-packages: org.xyzh.workcase.service.impl + +# ================== MyBatis ================== +mybatis-plus: + mapper-locations: classpath:mapper/**/*.xml + type-aliases-package: org.xyzh.common.dto, org.xyzh.api + +# ================== Logging ================== +logging: + config: classpath:log4j2.xml + charset: + console: UTF-8 + file: UTF-8 diff --git a/urbanLifelineServ/workcase/src/main/resources/log4j2.xml b/urbanLifelineServ/workcase/src/main/resources/log4j2.xml new file mode 100644 index 0000000..2b1f3af --- /dev/null +++ b/urbanLifelineServ/workcase/src/main/resources/log4j2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +