diff --git a/sql/mysql/project/01-create-tables.sql b/sql/mysql/project/01-create-tables.sql new file mode 100644 index 00000000..2f4952b5 --- /dev/null +++ b/sql/mysql/project/01-create-tables.sql @@ -0,0 +1,38 @@ +-- ============================================= +-- 租户-项目两级架构 - 建表脚本 +-- ============================================= + +-- 1. 项目表 +CREATE TABLE IF NOT EXISTS system_project ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '项目编号', + tenant_id BIGINT NOT NULL COMMENT '所属租户编号', + name VARCHAR(100) NOT NULL COMMENT '项目名称', + code VARCHAR(50) NOT NULL COMMENT '项目编码(如楼盘编号)', + status TINYINT DEFAULT 0 COMMENT '状态(0=正常, 1=禁用)', + contact_name VARCHAR(30) COMMENT '项目联系人', + contact_mobile VARCHAR(30) COMMENT '联系手机', + address VARCHAR(500) COMMENT '项目地址', + remark VARCHAR(500) COMMENT '备注', + creator VARCHAR(64) DEFAULT '' COMMENT '创建者', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updater VARCHAR(64) DEFAULT '' COMMENT '更新者', + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + deleted BIT DEFAULT 0 COMMENT '是否删除', + UNIQUE KEY uk_tenant_code (tenant_id, code, deleted), + INDEX idx_tenant (tenant_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目表'; + +-- 2. 用户-项目关联表 +CREATE TABLE IF NOT EXISTS system_user_project ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '编号', + user_id BIGINT NOT NULL COMMENT '用户编号', + project_id BIGINT NOT NULL COMMENT '项目编号', + tenant_id BIGINT NOT NULL COMMENT '租户编号', + creator VARCHAR(64) DEFAULT '' COMMENT '创建者', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updater VARCHAR(64) DEFAULT '' COMMENT '更新者', + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + deleted BIT DEFAULT 0 COMMENT '是否删除', + UNIQUE KEY uk_user_project (user_id, project_id, deleted), + INDEX idx_project (project_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户-项目关联表'; diff --git a/sql/mysql/project/02-default-data.sql b/sql/mysql/project/02-default-data.sql new file mode 100644 index 00000000..5f19c6a7 --- /dev/null +++ b/sql/mysql/project/02-default-data.sql @@ -0,0 +1,21 @@ +-- ============================================= +-- 租户-项目两级架构 - 默认数据迁移 +-- 为每个现有租户创建默认项目,为所有用户关联默认项目 +-- ============================================= + +-- Step 1: 为每个现有租户创建默认项目 +INSERT INTO system_project (tenant_id, name, code, status, remark, creator, updater, deleted) +SELECT id, name, 'DEFAULT', 0, '系统自动生成默认项目', 'system', 'system', 0 +FROM system_tenant WHERE deleted = 0; + +-- Step 2: 为所有用户关联默认项目 +INSERT INTO system_user_project (user_id, project_id, tenant_id, creator, updater, deleted) +SELECT u.id, p.id, u.tenant_id, 'system', 'system', 0 +FROM system_users u +JOIN system_project p ON p.tenant_id = u.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +WHERE u.deleted = 0; + +-- 验证 +SELECT '默认项目数量' AS metric, COUNT(*) AS value FROM system_project WHERE code = 'DEFAULT' AND deleted = 0 +UNION ALL +SELECT '用户-项目关联数量', COUNT(*) FROM system_user_project WHERE deleted = 0; diff --git a/sql/mysql/project/03-alter-business-tables.sql b/sql/mysql/project/03-alter-business-tables.sql new file mode 100644 index 00000000..794dddb1 --- /dev/null +++ b/sql/mysql/project/03-alter-business-tables.sql @@ -0,0 +1,215 @@ +-- ============================================= +-- 租户-项目两级架构 - 业务表增加 project_id 字段 +-- 执行顺序:ADD NULL → UPDATE 回填 → MODIFY NOT NULL → ADD INDEX +-- 前置条件:02-default-data.sql 已执行,system_project 中已有默认项目数据 +-- ============================================= + +-- ----------------------------------------------- +-- 1. iot_device +-- ----------------------------------------------- +ALTER TABLE iot_device ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE iot_device d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE iot_device MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE iot_device ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 2. ops_order +-- ----------------------------------------------- +ALTER TABLE ops_order ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_order d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_order MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_order ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 3. ops_order_event +-- ----------------------------------------------- +ALTER TABLE ops_order_event ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_order_event d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_order_event MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_order_event ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 4. ops_order_dispatch +-- ----------------------------------------------- +ALTER TABLE ops_order_dispatch ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_order_dispatch d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_order_dispatch MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_order_dispatch ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 5. ops_order_queue +-- ----------------------------------------------- +ALTER TABLE ops_order_queue ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_order_queue d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_order_queue MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_order_queue ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 6. ops_bus_area +-- ----------------------------------------------- +ALTER TABLE ops_bus_area ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_bus_area d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_bus_area MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_bus_area ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 7. ops_area_device_relation +-- ----------------------------------------------- +ALTER TABLE ops_area_device_relation ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_area_device_relation d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_area_device_relation MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_area_device_relation ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 8. ops_order_security_ext +-- ----------------------------------------------- +ALTER TABLE ops_order_security_ext ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_order_security_ext d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_order_security_ext MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_order_security_ext ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 9. ops_area_security_user +-- ----------------------------------------------- +ALTER TABLE ops_area_security_user ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_area_security_user d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_area_security_user MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_area_security_user ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 10. ops_order_clean_ext +-- ----------------------------------------------- +ALTER TABLE ops_order_clean_ext ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_order_clean_ext d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_order_clean_ext MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_order_clean_ext ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 11. ops_cleaner_status +-- ----------------------------------------------- +ALTER TABLE ops_cleaner_status ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_cleaner_status d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_cleaner_status MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_cleaner_status ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 12. ops_cleaner_performance_monthly +-- ----------------------------------------------- +ALTER TABLE ops_cleaner_performance_monthly ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_cleaner_performance_monthly d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_cleaner_performance_monthly MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_cleaner_performance_monthly ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 13. ops_device_trajectory +-- ----------------------------------------------- +ALTER TABLE ops_device_trajectory ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_device_trajectory d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_device_trajectory MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_device_trajectory ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 14. ops_inspection_record +-- ----------------------------------------------- +ALTER TABLE ops_inspection_record ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_inspection_record d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_inspection_record MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_inspection_record ADD INDEX idx_project_id (project_id); + +-- ----------------------------------------------- +-- 15. ops_inspection_record_item +-- ----------------------------------------------- +ALTER TABLE ops_inspection_record_item ADD COLUMN project_id BIGINT NULL COMMENT '项目编号'; + +UPDATE ops_inspection_record_item d +JOIN system_project p ON p.tenant_id = d.tenant_id AND p.code = 'DEFAULT' AND p.deleted = 0 +SET d.project_id = p.id +WHERE d.project_id IS NULL; + +ALTER TABLE ops_inspection_record_item MODIFY COLUMN project_id BIGINT NOT NULL COMMENT '项目编号'; + +ALTER TABLE ops_inspection_record_item ADD INDEX idx_project_id (project_id); diff --git a/sql/mysql/project/04-index-audit.sql b/sql/mysql/project/04-index-audit.sql new file mode 100644 index 00000000..bf1ed65f --- /dev/null +++ b/sql/mysql/project/04-index-audit.sql @@ -0,0 +1,86 @@ +-- ============================================= +-- 租户-项目两级架构 - 唯一索引审计脚本 +-- 检查各业务表现有唯一键,评估是否需要将 project_id 纳入唯一约束 +-- 执行顺序:在 03-alter-business-tables.sql 之后执行 +-- ============================================= + +-- ----------------------------------------------- +-- 查看各表当前的索引情况(审计用,执行前先 SHOW INDEX 确认) +-- ----------------------------------------------- +SHOW INDEX FROM iot_device; +SHOW INDEX FROM ops_order; +SHOW INDEX FROM ops_order_event; +SHOW INDEX FROM ops_order_dispatch; +SHOW INDEX FROM ops_order_queue; +SHOW INDEX FROM ops_bus_area; +SHOW INDEX FROM ops_area_device_relation; +SHOW INDEX FROM ops_order_security_ext; +SHOW INDEX FROM ops_area_security_user; +SHOW INDEX FROM ops_order_clean_ext; +SHOW INDEX FROM ops_cleaner_status; +SHOW INDEX FROM ops_cleaner_performance_monthly; +SHOW INDEX FROM ops_device_trajectory; +SHOW INDEX FROM ops_inspection_record; +SHOW INDEX FROM ops_inspection_record_item; + +-- ----------------------------------------------- +-- 唯一键改造建议(根据实际业务语义决定是否执行) +-- 说明:若某张表的唯一键仅含 tenant_id,则需要将 project_id 也纳入, +-- 以确保在同一租户下不同项目之间的数据互不干扰。 +-- ----------------------------------------------- + +-- ops_bus_area:区域编码在项目内唯一(原唯一键可能仅含 tenant_id + code) +-- 示例:DROP INDEX uk_tenant_code ON ops_bus_area; +-- 示例:ALTER TABLE ops_bus_area ADD UNIQUE KEY uk_project_code (tenant_id, project_id, code, deleted); + +-- ops_area_device_relation:设备-区域关联在项目内唯一 +-- 示例:DROP INDEX uk_area_device ON ops_area_device_relation; +-- 示例:ALTER TABLE ops_area_device_relation ADD UNIQUE KEY uk_project_area_device (project_id, area_id, device_id, deleted); + +-- ops_area_security_user:安保用户-区域关联在项目内唯一 +-- 示例:DROP INDEX uk_area_user ON ops_area_security_user; +-- 示例:ALTER TABLE ops_area_security_user ADD UNIQUE KEY uk_project_area_user (project_id, area_id, user_id, deleted); + +-- ops_cleaner_status:保洁员状态在项目内唯一(每个项目内每个用户仅一条状态记录) +-- 示例:DROP INDEX uk_tenant_user ON ops_cleaner_status; +-- 示例:ALTER TABLE ops_cleaner_status ADD UNIQUE KEY uk_project_user (project_id, user_id, deleted); + +-- ops_cleaner_performance_monthly:月度绩效在项目内唯一(project + user + year_month) +-- 示例:DROP INDEX uk_tenant_user_month ON ops_cleaner_performance_monthly; +-- 示例:ALTER TABLE ops_cleaner_performance_monthly ADD UNIQUE KEY uk_project_user_month (project_id, user_id, stat_year, stat_month, deleted); + +-- iot_device:设备标识符在项目内唯一(device_key / product_key + device_name) +-- 示例:根据实际唯一键定义决定是否改造。 + +-- ----------------------------------------------- +-- 验证:各表 project_id 回填情况 +-- ----------------------------------------------- +SELECT 'iot_device' AS tbl, COUNT(*) AS total, SUM(project_id IS NULL) AS null_count FROM iot_device +UNION ALL +SELECT 'ops_order', COUNT(*), SUM(project_id IS NULL) FROM ops_order +UNION ALL +SELECT 'ops_order_event', COUNT(*), SUM(project_id IS NULL) FROM ops_order_event +UNION ALL +SELECT 'ops_order_dispatch', COUNT(*), SUM(project_id IS NULL) FROM ops_order_dispatch +UNION ALL +SELECT 'ops_order_queue', COUNT(*), SUM(project_id IS NULL) FROM ops_order_queue +UNION ALL +SELECT 'ops_bus_area', COUNT(*), SUM(project_id IS NULL) FROM ops_bus_area +UNION ALL +SELECT 'ops_area_device_relation', COUNT(*), SUM(project_id IS NULL) FROM ops_area_device_relation +UNION ALL +SELECT 'ops_order_security_ext', COUNT(*), SUM(project_id IS NULL) FROM ops_order_security_ext +UNION ALL +SELECT 'ops_area_security_user', COUNT(*), SUM(project_id IS NULL) FROM ops_area_security_user +UNION ALL +SELECT 'ops_order_clean_ext', COUNT(*), SUM(project_id IS NULL) FROM ops_order_clean_ext +UNION ALL +SELECT 'ops_cleaner_status', COUNT(*), SUM(project_id IS NULL) FROM ops_cleaner_status +UNION ALL +SELECT 'ops_cleaner_performance_monthly', COUNT(*), SUM(project_id IS NULL) FROM ops_cleaner_performance_monthly +UNION ALL +SELECT 'ops_device_trajectory', COUNT(*), SUM(project_id IS NULL) FROM ops_device_trajectory +UNION ALL +SELECT 'ops_inspection_record', COUNT(*), SUM(project_id IS NULL) FROM ops_inspection_record +UNION ALL +SELECT 'ops_inspection_record_item', COUNT(*), SUM(project_id IS NULL) FROM ops_inspection_record_item; diff --git a/sql/mysql/project/99-rollback.sql b/sql/mysql/project/99-rollback.sql new file mode 100644 index 00000000..78409b7e --- /dev/null +++ b/sql/mysql/project/99-rollback.sql @@ -0,0 +1,46 @@ +-- ============================================= +-- 租户-项目两级架构 - 回滚脚本 +-- 执行顺序与正向脚本相反:业务表 → 默认数据 → 建表 +-- ============================================= + +-- ----------------------------------------------- +-- Step 1: 回滚业务表(删除 project_id 字段及索引) +-- ----------------------------------------------- + +ALTER TABLE iot_device DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_order DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_order_event DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_order_dispatch DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_order_queue DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_bus_area DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_area_device_relation DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_order_security_ext DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_area_security_user DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_order_clean_ext DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_cleaner_status DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_cleaner_performance_monthly DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_device_trajectory DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_inspection_record DROP INDEX idx_project_id, DROP COLUMN project_id; +ALTER TABLE ops_inspection_record_item DROP INDEX idx_project_id, DROP COLUMN project_id; + +-- ----------------------------------------------- +-- Step 2: 回滚默认数据(删除用户-项目关联 和 默认项目) +-- ----------------------------------------------- + +-- 删除系统自动生成的用户-项目关联 +DELETE FROM system_user_project WHERE creator = 'system' AND deleted = 0; + +-- 删除系统自动生成的默认项目 +DELETE FROM system_project WHERE code = 'DEFAULT' AND creator = 'system' AND deleted = 0; + +-- ----------------------------------------------- +-- Step 3: 删除核心表 +-- ----------------------------------------------- + +DROP TABLE IF EXISTS system_user_project; +DROP TABLE IF EXISTS system_project; + +-- ----------------------------------------------- +-- 验证 +-- ----------------------------------------------- +SELECT '回滚完成' AS status; diff --git a/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/config/ViewshTenantAutoConfiguration.java b/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/config/ViewshTenantAutoConfiguration.java index 2bf48fe3..674606b4 100644 --- a/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/config/ViewshTenantAutoConfiguration.java +++ b/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/config/ViewshTenantAutoConfiguration.java @@ -17,6 +17,7 @@ import com.viewsh.framework.tenant.core.job.TenantJobAspect; import com.viewsh.framework.tenant.core.mq.rabbitmq.TenantRabbitMQInitializer; import com.viewsh.framework.tenant.core.mq.redis.TenantRedisMessageInterceptor; import com.viewsh.framework.tenant.core.mq.rocketmq.TenantRocketMQInitializer; +import com.viewsh.framework.tenant.core.redis.ProjectRedisCacheManager; import com.viewsh.framework.tenant.core.redis.TenantRedisCacheManager; import com.viewsh.framework.tenant.core.security.TenantSecurityWebFilter; import com.viewsh.framework.tenant.core.service.ProjectFrameworkService; @@ -266,8 +267,9 @@ public class ViewshTenantAutoConfiguration { RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory()); RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory, BatchStrategies.scan(viewshCacheProperties.getRedisScanBatchSize())); - // 创建 TenantRedisCacheManager 对象 - return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches()); + // 创建 ProjectRedisCacheManager 对象(在租户隔离基础上叠加项目隔离) + return new ProjectRedisCacheManager(cacheWriter, redisCacheConfiguration, + tenantProperties.getIgnoreCaches(), tenantProperties.getIgnoreProjectCaches()); } } diff --git a/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/core/redis/ProjectRedisCacheManager.java b/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/core/redis/ProjectRedisCacheManager.java new file mode 100644 index 00000000..e0d0b953 --- /dev/null +++ b/viewsh-framework/viewsh-spring-boot-starter-biz-tenant/src/main/java/com/viewsh/framework/tenant/core/redis/ProjectRedisCacheManager.java @@ -0,0 +1,51 @@ +package com.viewsh.framework.tenant.core.redis; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.viewsh.framework.tenant.core.context.ProjectContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.Cache; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheWriter; + +import java.util.Set; + +/** + * 多项目的 {@link org.springframework.data.redis.cache.RedisCacheManager} 实现类 + * + * 在租户隔离的基础上,追加项目隔离后缀,格式为 name + ":" + tenantId + ":" + projectId + * + * @author lzh + */ +@Slf4j +public class ProjectRedisCacheManager extends TenantRedisCacheManager { + + private static final String SPLIT = "#"; + + private final Set ignoreProjectCaches; + + public ProjectRedisCacheManager(RedisCacheWriter cacheWriter, + RedisCacheConfiguration defaultCacheConfiguration, + Set ignoreTenantCaches, + Set ignoreProjectCaches) { + super(cacheWriter, defaultCacheConfiguration, ignoreTenantCaches); + this.ignoreProjectCaches = ignoreProjectCaches; + } + + @Override + public Cache getCache(String name) { + // 获取原始 cache name(去掉 # 后缀部分,# 后面是超时配置) + String[] names = StrUtil.splitToArray(name, SPLIT); + // 如果开启项目隔离,则在 name 上追加 projectId 后缀 + // 父类 TenantRedisCacheManager.getCache 会继续追加 tenantId, + // 最终 key 格式:name[:projectId]:tenantId + if (!ProjectContextHolder.isIgnore() + && ProjectContextHolder.getProjectId() != null + && !CollUtil.contains(ignoreProjectCaches, names[0])) { + name = name + ":" + ProjectContextHolder.getProjectId(); + } + // 继续基于父方法(父类追加租户后缀) + return super.getCache(name); + } + +} diff --git a/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/biz/dto/IotDeviceRespDTO.java b/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/biz/dto/IotDeviceRespDTO.java index 10e83ae5..a350987f 100644 --- a/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/biz/dto/IotDeviceRespDTO.java +++ b/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/biz/dto/IotDeviceRespDTO.java @@ -26,6 +26,10 @@ public class IotDeviceRespDTO { * 租户编号 */ private Long tenantId; + /** + * 项目编号 + */ + private Long projectId; // ========== 产品相关字段 ========== diff --git a/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/mq/message/IotDeviceMessage.java b/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/mq/message/IotDeviceMessage.java index e87b988f..f986bd12 100644 --- a/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/mq/message/IotDeviceMessage.java +++ b/viewsh-module-iot/viewsh-module-iot-core/src/main/java/com/viewsh/module/iot/core/mq/message/IotDeviceMessage.java @@ -54,6 +54,10 @@ public class IotDeviceMessage { * 租户编号 */ private Long tenantId; + /** + * 项目编号 + */ + private Long projectId; /** * 服务编号,该消息由哪个 server 发送 diff --git a/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/service/device/message/IotDeviceMessageServiceImpl.java b/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/service/device/message/IotDeviceMessageServiceImpl.java index 65d97a9a..f544f83e 100644 --- a/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/service/device/message/IotDeviceMessageServiceImpl.java +++ b/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/service/device/message/IotDeviceMessageServiceImpl.java @@ -1,138 +1,139 @@ -package com.viewsh.module.iot.gateway.service.device.message; - -import cn.hutool.core.util.StrUtil; -import com.viewsh.framework.common.util.collection.CollectionUtils; -import com.viewsh.module.iot.core.biz.dto.IotDeviceRespDTO; -import com.viewsh.module.iot.core.mq.message.IotDeviceMessage; -import com.viewsh.module.iot.core.mq.producer.IotDeviceMessageProducer; -import com.viewsh.module.iot.core.util.IotDeviceMessageUtils; -import com.viewsh.module.iot.gateway.codec.IotDeviceMessageCodec; -import com.viewsh.module.iot.gateway.service.device.IotDeviceService; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Map; - -import static com.viewsh.framework.common.exception.util.ServiceExceptionUtil.exception; -import static com.viewsh.module.iot.gateway.enums.ErrorCodeConstants.DEVICE_NOT_EXISTS; - -/** - * IoT 设备消息 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Slf4j -public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { - - /** - * 编解码器 - */ - private final Map codes; - - @Resource - private IotDeviceService deviceService; - - @Resource - private IotDeviceMessageProducer deviceMessageProducer; - - public IotDeviceMessageServiceImpl(List codes) { - this.codes = CollectionUtils.convertMap(codes, IotDeviceMessageCodec::type); - } - - @Override - public byte[] encodeDeviceMessage(IotDeviceMessage message, - String productKey, String deviceName) { - // 1.1 获取设备信息 - IotDeviceRespDTO device = deviceService.getDeviceFromCache(productKey, deviceName); - if (device == null) { - throw exception(DEVICE_NOT_EXISTS, productKey, deviceName); - } - // 1.2 获取编解码器 - IotDeviceMessageCodec codec = codes.get(device.getCodecType()); - if (codec == null) { - throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", device.getCodecType())); - } - - // 2. 编码消息 - return codec.encode(message); - } - - @Override - public byte[] encodeDeviceMessage(IotDeviceMessage message, - String codecType) { - // 1. 获取编解码器 - IotDeviceMessageCodec codec = codes.get(codecType); - if (codec == null) { - throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", codecType)); - } - - // 2. 编码消息 - return codec.encode(message); - } - - @Override - public IotDeviceMessage decodeDeviceMessage(byte[] bytes, - String productKey, String deviceName) { - // 1.1 获取设备信息 - IotDeviceRespDTO device = deviceService.getDeviceFromCache(productKey, deviceName); - if (device == null) { - throw exception(DEVICE_NOT_EXISTS, productKey, deviceName); - } - // 1.2 获取编解码器 - IotDeviceMessageCodec codec = codes.get(device.getCodecType()); - if (codec == null) { - throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", device.getCodecType())); - } - - // 2. 解码消息 - return codec.decode(bytes); - } - - @Override - public IotDeviceMessage decodeDeviceMessage(byte[] bytes, String codecType) { - // 1. 获取编解码器 - IotDeviceMessageCodec codec = codes.get(codecType); - if (codec == null) { - throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", codecType)); - } - - // 2. 解码消息 - return codec.decode(bytes); - } - - @Override - public void sendDeviceMessage(IotDeviceMessage message, - String productKey, String deviceName, String serverId) { - // 1. 获取设备信息 - IotDeviceRespDTO device = deviceService.getDeviceFromCache(productKey, deviceName); - if (device == null) { - throw exception(DEVICE_NOT_EXISTS, productKey, deviceName); - } - - // 2. 发送消息 - appendDeviceMessage(message, device, serverId); - deviceMessageProducer.sendDeviceMessage(message); - } - - /** - * 补充消息的后端字段 - * - * @param message 消息 - * @param device 设备信息 - * @param serverId 设备连接的 serverId - */ - private void appendDeviceMessage(IotDeviceMessage message, - IotDeviceRespDTO device, String serverId) { - message.setId(IotDeviceMessageUtils.generateMessageId()).setReportTime(LocalDateTime.now()) - .setDeviceId(device.getId()).setTenantId(device.getTenantId()).setServerId(serverId); - // 特殊:如果设备没有指定 requestId,则使用 messageId - if (StrUtil.isEmpty(message.getRequestId())) { - message.setRequestId(message.getId()); - } - } - -} +package com.viewsh.module.iot.gateway.service.device.message; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.framework.common.util.collection.CollectionUtils; +import com.viewsh.module.iot.core.biz.dto.IotDeviceRespDTO; +import com.viewsh.module.iot.core.mq.message.IotDeviceMessage; +import com.viewsh.module.iot.core.mq.producer.IotDeviceMessageProducer; +import com.viewsh.module.iot.core.util.IotDeviceMessageUtils; +import com.viewsh.module.iot.gateway.codec.IotDeviceMessageCodec; +import com.viewsh.module.iot.gateway.service.device.IotDeviceService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import static com.viewsh.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.viewsh.module.iot.gateway.enums.ErrorCodeConstants.DEVICE_NOT_EXISTS; + +/** + * IoT 设备消息 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { + + /** + * 编解码器 + */ + private final Map codes; + + @Resource + private IotDeviceService deviceService; + + @Resource + private IotDeviceMessageProducer deviceMessageProducer; + + public IotDeviceMessageServiceImpl(List codes) { + this.codes = CollectionUtils.convertMap(codes, IotDeviceMessageCodec::type); + } + + @Override + public byte[] encodeDeviceMessage(IotDeviceMessage message, + String productKey, String deviceName) { + // 1.1 获取设备信息 + IotDeviceRespDTO device = deviceService.getDeviceFromCache(productKey, deviceName); + if (device == null) { + throw exception(DEVICE_NOT_EXISTS, productKey, deviceName); + } + // 1.2 获取编解码器 + IotDeviceMessageCodec codec = codes.get(device.getCodecType()); + if (codec == null) { + throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", device.getCodecType())); + } + + // 2. 编码消息 + return codec.encode(message); + } + + @Override + public byte[] encodeDeviceMessage(IotDeviceMessage message, + String codecType) { + // 1. 获取编解码器 + IotDeviceMessageCodec codec = codes.get(codecType); + if (codec == null) { + throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", codecType)); + } + + // 2. 编码消息 + return codec.encode(message); + } + + @Override + public IotDeviceMessage decodeDeviceMessage(byte[] bytes, + String productKey, String deviceName) { + // 1.1 获取设备信息 + IotDeviceRespDTO device = deviceService.getDeviceFromCache(productKey, deviceName); + if (device == null) { + throw exception(DEVICE_NOT_EXISTS, productKey, deviceName); + } + // 1.2 获取编解码器 + IotDeviceMessageCodec codec = codes.get(device.getCodecType()); + if (codec == null) { + throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", device.getCodecType())); + } + + // 2. 解码消息 + return codec.decode(bytes); + } + + @Override + public IotDeviceMessage decodeDeviceMessage(byte[] bytes, String codecType) { + // 1. 获取编解码器 + IotDeviceMessageCodec codec = codes.get(codecType); + if (codec == null) { + throw new IllegalArgumentException(StrUtil.format("编解码器({}) 不存在", codecType)); + } + + // 2. 解码消息 + return codec.decode(bytes); + } + + @Override + public void sendDeviceMessage(IotDeviceMessage message, + String productKey, String deviceName, String serverId) { + // 1. 获取设备信息 + IotDeviceRespDTO device = deviceService.getDeviceFromCache(productKey, deviceName); + if (device == null) { + throw exception(DEVICE_NOT_EXISTS, productKey, deviceName); + } + + // 2. 发送消息 + appendDeviceMessage(message, device, serverId); + deviceMessageProducer.sendDeviceMessage(message); + } + + /** + * 补充消息的后端字段 + * + * @param message 消息 + * @param device 设备信息 + * @param serverId 设备连接的 serverId + */ + private void appendDeviceMessage(IotDeviceMessage message, + IotDeviceRespDTO device, String serverId) { + message.setId(IotDeviceMessageUtils.generateMessageId()).setReportTime(LocalDateTime.now()) + .setDeviceId(device.getId()).setTenantId(device.getTenantId()) + .setProjectId(device.getProjectId()).setServerId(serverId); + // 特殊:如果设备没有指定 requestId,则使用 messageId + if (StrUtil.isEmpty(message.getRequestId())) { + message.setRequestId(message.getId()); + } + } + +} diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/dal/dataobject/device/IotDeviceDO.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/dal/dataobject/device/IotDeviceDO.java index 2eca5bc7..3b762ba1 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/dal/dataobject/device/IotDeviceDO.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/dal/dataobject/device/IotDeviceDO.java @@ -1,7 +1,7 @@ package com.viewsh.module.iot.dal.dataobject.device; import com.viewsh.framework.mybatis.core.type.LongSetTypeHandler; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.viewsh.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; import com.viewsh.module.iot.dal.dataobject.product.IotProductDO; import com.viewsh.module.iot.core.enums.IotDeviceStateEnum; @@ -26,7 +26,7 @@ import java.util.Set; @Builder @NoArgsConstructor @AllArgsConstructor -public class IotDeviceDO extends TenantBaseDO { +public class IotDeviceDO extends ProjectBaseDO { /** * 设备编号 - 全部设备 diff --git a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotCleanRuleMessageHandler.java b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotCleanRuleMessageHandler.java index c4175f1a..d335053a 100644 --- a/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotCleanRuleMessageHandler.java +++ b/viewsh-module-iot/viewsh-module-iot-server/src/main/java/com/viewsh/module/iot/mq/consumer/rule/IotCleanRuleMessageHandler.java @@ -1,5 +1,6 @@ package com.viewsh.module.iot.mq.consumer.rule; +import com.viewsh.framework.tenant.core.util.ProjectUtils; import com.viewsh.framework.tenant.core.util.TenantUtils; import com.viewsh.module.iot.core.messagebus.core.IotMessageBus; import com.viewsh.module.iot.core.messagebus.core.IotMessageSubscriber; @@ -50,12 +51,14 @@ public class IotCleanRuleMessageHandler implements IotMessageSubscriber { - try { - cleanRuleProcessorManager.processMessage(message); - } catch (Exception e) { - // 规则处理异常不影响其他消息处理 - log.error("[onMessage][消息({}) 保洁规则处理异常]", message.getRequestId(), e); - } + ProjectUtils.execute(message.getProjectId(), () -> { + try { + cleanRuleProcessorManager.processMessage(message); + } catch (Exception e) { + // 规则处理异常不影响其他消息处理 + log.error("[onMessage][消息({}) 保洁规则处理异常]", message.getRequestId(), e); + } + }); }); } diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerPerformanceMonthlyDO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerPerformanceMonthlyDO.java index ecc6648c..70c58c7c 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerPerformanceMonthlyDO.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerPerformanceMonthlyDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.environment.dal.dataobject.cleaner; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -21,7 +21,7 @@ import java.math.BigDecimal; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsCleanerPerformanceMonthlyDO extends TenantBaseDO { +public class OpsCleanerPerformanceMonthlyDO extends ProjectBaseDO { /** * 汇总ID diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerStatusDO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerStatusDO.java index 1565084c..e9204946 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerStatusDO.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/cleaner/OpsCleanerStatusDO.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.viewsh.module.ops.enums.CleanerStatusEnum; import lombok.*; @@ -22,7 +22,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsCleanerStatusDO extends TenantBaseDO { +public class OpsCleanerStatusDO extends ProjectBaseDO { /** * 主键ID diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordDO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordDO.java index c91021ce..87710fe6 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordDO.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.environment.dal.dataobject.inspection; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -21,7 +21,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsInspectionRecordDO extends TenantBaseDO { +public class OpsInspectionRecordDO extends ProjectBaseDO { /** * 巡检记录ID diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordItemDO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordItemDO.java index 27f920a0..02466388 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordItemDO.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/inspection/OpsInspectionRecordItemDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.environment.dal.dataobject.inspection; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -21,7 +21,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsInspectionRecordItemDO extends TenantBaseDO { +public class OpsInspectionRecordItemDO extends ProjectBaseDO { /** * 明细ID diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/workorder/OpsOrderCleanExtDO.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/workorder/OpsOrderCleanExtDO.java index a41c3873..7de9e848 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/workorder/OpsOrderCleanExtDO.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/dal/dataobject/workorder/OpsOrderCleanExtDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.environment.dal.dataobject.workorder; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -19,7 +19,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsOrderCleanExtDO extends TenantBaseDO { +public class OpsOrderCleanExtDO extends ProjectBaseDO { /** * 主键 diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsAreaDeviceRelationDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsAreaDeviceRelationDO.java index 3c478297..504f079e 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsAreaDeviceRelationDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsAreaDeviceRelationDO.java @@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import lombok.*; import java.util.Map; @@ -27,7 +27,7 @@ import java.util.Map; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsAreaDeviceRelationDO extends TenantBaseDO { +public class OpsAreaDeviceRelationDO extends ProjectBaseDO { /** * 主键 diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsBusAreaDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsBusAreaDO.java index 17b02609..a3a5c8e3 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsBusAreaDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/area/OpsBusAreaDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.dal.dataobject.area; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -19,7 +19,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsBusAreaDO extends TenantBaseDO { +public class OpsBusAreaDO extends ProjectBaseDO { /** * 区域ID,主键 diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/queue/OpsOrderQueueDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/queue/OpsOrderQueueDO.java index 3b9ee005..94c0d1d1 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/queue/OpsOrderQueueDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/queue/OpsOrderQueueDO.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.viewsh.module.ops.enums.OrderQueueStatusEnum; import com.viewsh.module.ops.enums.PriorityEnum; import lombok.*; @@ -24,7 +24,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsOrderQueueDO extends TenantBaseDO { +public class OpsOrderQueueDO extends ProjectBaseDO { /** * 队列ID(主键) diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/trajectory/OpsDeviceTrajectoryDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/trajectory/OpsDeviceTrajectoryDO.java index f5c65dbf..393faebe 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/trajectory/OpsDeviceTrajectoryDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/trajectory/OpsDeviceTrajectoryDO.java @@ -3,7 +3,7 @@ package com.viewsh.module.ops.dal.dataobject.trajectory; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import lombok.*; import java.time.LocalDateTime; @@ -24,7 +24,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsDeviceTrajectoryDO extends TenantBaseDO { +public class OpsDeviceTrajectoryDO extends ProjectBaseDO { /** * 主键 diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDO.java index 20936afc..4370b191 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.dal.dataobject.workorder; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -21,7 +21,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsOrderDO extends TenantBaseDO { +public class OpsOrderDO extends ProjectBaseDO { /** * 工单ID diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDispatchDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDispatchDO.java index 59976644..702310af 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDispatchDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderDispatchDO.java @@ -1,7 +1,7 @@ package com.viewsh.module.ops.dal.dataobject.workorder; import com.baomidou.mybatisplus.annotation.TableField; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -24,7 +24,7 @@ import java.util.Map; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsOrderDispatchDO extends TenantBaseDO { +public class OpsOrderDispatchDO extends ProjectBaseDO { /** * 派单ID diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderEventDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderEventDO.java index 8935f436..c312fff1 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderEventDO.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/workorder/OpsOrderEventDO.java @@ -1,7 +1,7 @@ package com.viewsh.module.ops.dal.dataobject.workorder; import com.baomidou.mybatisplus.annotation.IdType; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -20,7 +20,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsOrderEventDO extends TenantBaseDO { +public class OpsOrderEventDO extends ProjectBaseDO { /** * 事件ID(使用��花算法生成) diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/service/dispatch/UserDispatchStatusServiceImpl.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/service/dispatch/UserDispatchStatusServiceImpl.java index 8bcc65a6..eed60e46 100644 --- a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/service/dispatch/UserDispatchStatusServiceImpl.java +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/service/dispatch/UserDispatchStatusServiceImpl.java @@ -31,6 +31,7 @@ import java.util.stream.Collectors; public class UserDispatchStatusServiceImpl implements UserDispatchStatusService { private static final long TTL_SECONDS = 24 * 3600; // 24h + private static final String KEY_PREFIX = "ops:user:dispatch:"; @Resource private StringRedisTemplate stringRedisTemplate; diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/area/OpsAreaSecurityUserDO.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/area/OpsAreaSecurityUserDO.java index 85afc039..8852688b 100644 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/area/OpsAreaSecurityUserDO.java +++ b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/area/OpsAreaSecurityUserDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.security.dal.dataobject.area; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -17,7 +17,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsAreaSecurityUserDO extends TenantBaseDO { +public class OpsAreaSecurityUserDO extends ProjectBaseDO { /** * 主键 diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/workorder/OpsOrderSecurityExtDO.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/workorder/OpsOrderSecurityExtDO.java index ff9141b9..a54a22b5 100644 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/workorder/OpsOrderSecurityExtDO.java +++ b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/dal/dataobject/workorder/OpsOrderSecurityExtDO.java @@ -1,6 +1,6 @@ package com.viewsh.module.ops.security.dal.dataobject.workorder; -import com.viewsh.framework.tenant.core.db.TenantBaseDO; +import com.viewsh.framework.tenant.core.db.ProjectBaseDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -19,7 +19,7 @@ import java.time.LocalDateTime; @Builder @NoArgsConstructor @AllArgsConstructor -public class OpsOrderSecurityExtDO extends TenantBaseDO { +public class OpsOrderSecurityExtDO extends ProjectBaseDO { /** * 主键