-- ============================================================
-- 智能客服系统 - 完整数据库迁移
-- 数据库：MySQL 5.7+
-- 作者：OpenClaw Team
-- 日期：2026-03-01
-- ============================================================

-- 创建数据库
CREATE DATABASE IF NOT EXISTS `openclaw` 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;

USE `openclaw`;

-- ============================================================
-- 租户管理表
-- ============================================================
CREATE TABLE IF NOT EXISTS `tenants` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(200) NOT NULL COMMENT '租户名称',
  `slug` VARCHAR(100) UNIQUE NOT NULL COMMENT '租户唯一标识',
  `email` VARCHAR(255) NOT NULL COMMENT '管理员邮箱',
  `phone` VARCHAR(50) DEFAULT NULL COMMENT '联系电话',
  `logo` VARCHAR(500) DEFAULT NULL COMMENT 'Logo URL',
  `website` VARCHAR(500) DEFAULT NULL COMMENT '官方网站',
  `description` TEXT DEFAULT NULL COMMENT '租户描述',
  `status` ENUM('pending', 'active', 'suspended', 'archived') DEFAULT 'pending',
  `plan` ENUM('free', 'basic', 'pro', 'enterprise') DEFAULT 'free',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  UNIQUE KEY `uk_slug` (`slug`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='租户表';

-- ============================================================
-- 用户表
-- ============================================================
CREATE TABLE IF NOT EXISTS `users` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '所属租户 ID',
  `username` VARCHAR(100) NOT NULL COMMENT '用户名',
  `email` VARCHAR(255) NOT NULL COMMENT '邮箱',
  `password_hash` VARCHAR(255) NOT NULL COMMENT '密码哈希',
  `full_name` VARCHAR(100) DEFAULT NULL COMMENT '全名',
  `avatar` VARCHAR(500) DEFAULT NULL COMMENT '头像 URL',
  `phone` VARCHAR(50) DEFAULT NULL COMMENT '手机号',
  `role` ENUM('owner', 'admin', 'member', 'guest') DEFAULT 'member',
  `status` ENUM('active', 'inactive', 'suspended', 'deleted') DEFAULT 'active',
  `last_login_at` TIMESTAMP DEFAULT NULL,
  `last_login_ip` VARCHAR(50) DEFAULT NULL COMMENT '最后登录 IP',
  `remember_token` VARCHAR(100) DEFAULT NULL COMMENT '长期登录 Token',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  UNIQUE KEY `uk_username` (`username`),
  UNIQUE KEY `uk_email` (`email`),
  KEY `idx_tenant_status` (`tenant_id`, `status`) USING BTREE,
  CONSTRAINT `fk_users_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

-- ============================================================
-- 角色表
-- ============================================================
CREATE TABLE IF NOT EXISTS `roles` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `tenant_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '租户 ID（NULL 为全局角色）',
  `name` VARCHAR(100) NOT NULL COMMENT '角色名称',
  `code` VARCHAR(100) NOT NULL COMMENT '角色代码',
  `description` TEXT DEFAULT NULL COMMENT '角色描述',
  `is_global` BOOLEAN DEFAULT FALSE COMMENT '是否为全局角色',
  `is_system` BOOLEAN DEFAULT FALSE COMMENT '是否为系统内置角色',
  `status` ENUM('active', 'inactive', 'archived') DEFAULT 'active',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  UNIQUE KEY `uk_code` (`code`),
  KEY `idx_tenant` (`tenant_id`),
  CONSTRAINT `fk_roles_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';

-- 初始化系统内置角色
INSERT INTO `roles` (`name`, `code`, `description`, `is_global`, `is_system`, `status`) VALUES
('系统管理员', 'system_admin', '拥有系统全部权限', TRUE, TRUE, 'active'),
('超级管理员', 'super_admin', '租户超级管理员', FALSE, TRUE, 'active'),
('普通用户', 'user', '普通用户角色', FALSE, TRUE, 'active'),
('访客', 'guest', '访客角色（只读）', FALSE, TRUE, 'active');

-- ============================================================
-- 资源/权限表
-- ============================================================
CREATE TABLE IF NOT EXISTS `resources` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `tenant_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '租户 ID',
  `parent_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父资源 ID',
  `name` VARCHAR(200) NOT NULL COMMENT '资源名称',
  `code` VARCHAR(200) NOT NULL COMMENT '资源代码（唯一）',
  `type` ENUM('api', 'page', 'button', 'data') NOT NULL COMMENT '资源类型',
  `group` VARCHAR(100) DEFAULT NULL COMMENT '资源分组',
  `path` VARCHAR(500) DEFAULT NULL COMMENT 'API/页面路径',
  `method` VARCHAR(10) DEFAULT NULL COMMENT 'API 请求方法',
  `description` TEXT DEFAULT NULL COMMENT '资源描述',
  `icon` VARCHAR(100) DEFAULT NULL COMMENT '图标',
  `sort_order` INT DEFAULT 0 COMMENT '排序',
  `level` INT DEFAULT 0 COMMENT '层级深度',
  `lft` INT DEFAULT NULL COMMENT '左值（用于树查询）',
  `rgt` INT DEFAULT NULL COMMENT '右值（用于树查询）',
  `is_system` BOOLEAN DEFAULT FALSE COMMENT '是否为系统资源',
  `status` ENUM('active', 'inactive', 'archived') DEFAULT 'active',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  UNIQUE KEY `uk_code` (`code`),
  KEY `idx_tenant_parent` (`tenant_id`, `parent_id`),
  KEY `idx_group` (`group`),
  KEY `idx_type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='资源/权限表';

-- 初始化系统资源（示例）
INSERT INTO `resources` (`name`, `code`, `type`, `group`, `path`, `method`, `description`, `is_system`, `status`) VALUES
('租户管理', 'tenant:manage', 'api', 'tenant', '/api/v1/tenants', '', '租户列表查询', TRUE, 'active'),
('租户创建', 'tenant:create', 'api', 'tenant', '/api/v1/tenants', 'POST', '创建租户', TRUE, 'active'),
('租户更新', 'tenant:update', 'api', 'tenant', '/api/v1/tenants/*', 'PUT', '更新租户', TRUE, 'active'),
('租户删除', 'tenant:delete', 'api', 'tenant', '/api/v1/tenants/*', 'DELETE', '删除租户', TRUE, 'active'),
('用户管理', 'user:manage', 'api', 'user', '/api/v1/users', '', '用户列表查询', TRUE, 'active'),
('用户创建', 'user:create', 'api', 'user', '/api/v1/users', 'POST', '创建用户', TRUE, 'active'),
('角色管理', 'role:manage', 'api', 'role', '/api/v1/roles', '', '角色管理', TRUE, 'active'),
('资源管理', 'resource:manage', 'api', 'resource', '/api/v1/resources', '', '资源管理', TRUE, 'active'),
('工单管理', 'ticket:manage', 'api', 'ticket', '/api/v1/tickets', '', '工单管理', TRUE, 'active'),
('会话管理', 'conversation:manage', 'api', 'conversation', '/api/v1/conversations', '', '会话管理', TRUE, 'active'),
('知识库管理', 'knowledge:manage', 'api', 'knowledge', '/api/v1/knowledge', '', '知识库管理', TRUE, 'active');

-- ============================================================
-- 角色资源关联表
-- ============================================================
CREATE TABLE IF NOT EXISTS `role_resources` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `role_id` BIGINT UNSIGNED NOT NULL,
  `resource_id` BIGINT UNSIGNED NOT NULL,
  `actions` VARCHAR(255) DEFAULT NULL COMMENT '允许的操作 (JSON)',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY `uk_role_resource` (`role_id`, `resource_id`),
  KEY `idx_resource` (`resource_id`),
  CONSTRAINT `fk_role_resources_role` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_role_resources_resource` FOREIGN KEY (`resource_id`) REFERENCES `resources`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色资源关联表';

-- ============================================================
-- 用户角色关联表
-- ============================================================
CREATE TABLE IF NOT EXISTS `user_roles` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `user_id` BIGINT UNSIGNED NOT NULL,
  `role_id` BIGINT UNSIGNED NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY `uk_user_role` (`user_id`, `role_id`),
  KEY `idx_role` (`role_id`),
  CONSTRAINT `fk_user_roles_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_user_roles_role` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表';

-- ============================================================
-- 会话表
-- ============================================================
CREATE TABLE IF NOT EXISTS `conversations` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户 ID',
  `user_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '用户 ID',
  `title` VARCHAR(500) DEFAULT NULL COMMENT '会话标题',
  `topic` VARCHAR(200) DEFAULT NULL COMMENT '会话主题',
  `status` ENUM('active', 'closed', 'archived') DEFAULT 'active',
  `metadata` JSON DEFAULT NULL COMMENT '元数据',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  KEY `idx_tenant` (`tenant_id`),
  KEY `idx_user` (`user_id`),
  CONSTRAINT `fk_conversations_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='会话表';

-- ============================================================
-- 消息表
-- ============================================================
CREATE TABLE IF NOT EXISTS `messages` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `conversation_id` BIGINT UNSIGNED NOT NULL COMMENT '会话 ID',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户 ID',
  `user_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '用户 ID',
  `role` ENUM('user', 'assistant', 'system') NOT NULL COMMENT '消息角色',
  `content` TEXT NOT NULL COMMENT '消息内容',
  `content_type` ENUM('text', 'image', 'file') DEFAULT 'text',
  `content_url` VARCHAR(1000) DEFAULT NULL COMMENT '内容 URL',
  `metadata` JSON DEFAULT NULL COMMENT '消息元数据',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  KEY `idx_conversation` (`conversation_id`),
  KEY `idx_tenant` (`tenant_id`),
  CONSTRAINT `fk_messages_conversation` FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_messages_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='消息表';

-- ============================================================
-- 工单表
-- ============================================================
CREATE TABLE IF NOT EXISTS `tickets` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `ticket_number` VARCHAR(50) UNIQUE NOT NULL COMMENT '工单编号',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户 ID',
  `user_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '用户 ID',
  `title` VARCHAR(500) NOT NULL COMMENT '工单标题',
  `description` TEXT NOT NULL COMMENT '工单描述',
  `category` VARCHAR(100) DEFAULT NULL COMMENT '工单分类',
  `priority` ENUM('low', 'medium', 'high', 'urgent') DEFAULT 'medium',
  `status` ENUM('open', 'pending', 'in_progress', 'resolved', 'closed') DEFAULT 'open',
  `assigned_to` BIGINT UNSIGNED DEFAULT NULL COMMENT '指配给',
  `due_date` DATETIME DEFAULT NULL COMMENT '截止日期',
  `resolution` TEXT DEFAULT NULL COMMENT '解决方案',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  KEY `idx_tenant` (`tenant_id`),
  KEY `idx_status` (`status`),
  KEY `idx_assigned` (`assigned_to`),
  CONSTRAINT `fk_tickets_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工单表';

-- ============================================================
-- 知识库分类表
-- ============================================================
CREATE TABLE IF NOT EXISTS `knowledge_bases` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户 ID',
  `name` VARCHAR(200) NOT NULL COMMENT '知识库名称',
  `slug` VARCHAR(100) NOT NULL COMMENT '知识库唯一标识',
  `description` TEXT DEFAULT NULL COMMENT '知识库描述',
  `icon` VARCHAR(100) DEFAULT NULL COMMENT '图标',
  `sort_order` INT DEFAULT 0 COMMENT '排序',
  `status` ENUM('draft', 'published', 'archived') DEFAULT 'draft',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  UNIQUE KEY `uk_slug` (`slug`),
  KEY `idx_tenant` (`tenant_id`),
  CONSTRAINT `fk_kb_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='知识库分类';

-- ============================================================
-- 知识库项表
-- ============================================================
CREATE TABLE IF NOT EXISTS `knowledge_items` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `knowledge_base_id` BIGINT UNSIGNED NOT NULL COMMENT '知识库 ID',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户 ID',
  `title` VARCHAR(500) NOT NULL COMMENT '标题',
  `slug` VARCHAR(200) NOT NULL COMMENT '唯一标识',
  `content` LONGTEXT NOT NULL COMMENT '内容（Markdown）',
  `summary` TEXT DEFAULT NULL COMMENT '摘要',
  `tags` JSON DEFAULT NULL COMMENT '标签',
  `metadata` JSON DEFAULT NULL COMMENT '元数据',
  `author_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '作者 ID',
  `status` ENUM('draft', 'review', 'published', 'archived') DEFAULT 'draft',
  `views` INT DEFAULT 0 COMMENT '浏览次数',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` TIMESTAMP DEFAULT NULL,
  
  KEY `idx_kb` (`knowledge_base_id`),
  KEY `idx_tenant` (`tenant_id`),
  KEY `idx_status` (`status`),
  KEY `idx_tags` (`tags`),
  CONSTRAINT `fk_ki_kb` FOREIGN KEY (`knowledge_base_id`) REFERENCES `knowledge_bases`(`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_ki_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `tenants`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='知识库项';

-- ============================================================
-- 全表索引优化
-- ============================================================

-- 用户角色查询优化
CREATE INDEX `idx_users_roles_composite` ON `user_roles` (`user_id`, `created_at`);

-- 消息时间查询优化
CREATE INDEX `idx_messages_created` ON `messages` (`created_at`);

-- 会话活跃状态优化
CREATE INDEX `idx_conversations_active` ON `conversations` (`status`, `created_at`);

-- 工单状态查询优化
CREATE INDEX `idx_tickets_status_priority` ON `tickets` (`status`, `priority`, `created_at`);

-- 知识库全文索引（可选）
ALTER TABLE `knowledge_items` ADD FULLTEXT INDEX `idx_content_fulltext` (`content`);
ALTER TABLE `knowledge_items` ADD FULLTEXT INDEX `idx_title_content` (`title`, `content`);

-- ============================================================
-- 完成迁移
-- ============================================================

-- 输出迁移信息
SELECT '✅ 数据库迁移完成！' AS status;
