ALTER TABLE `digital_employee_sync_record` ADD COLUMN `contract_version` VARCHAR(128) DEFAULT NULL COMMENT '客户端同步契约版本' AFTER `operation`, ADD COLUMN `entity_summary` JSON DEFAULT NULL COMMENT '客户端实体摘要' AFTER `contract_version`, ADD COLUMN `business_view` JSON DEFAULT NULL COMMENT '客户端业务视图投影' AFTER `entity_summary`; CREATE TABLE IF NOT EXISTS `digital_employee_admin_action` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键', `_tenant_id` BIGINT DEFAULT NULL COMMENT '租户 ID', `user_id` BIGINT DEFAULT NULL COMMENT '创建用户 ID', `client_key` VARCHAR(128) DEFAULT NULL COMMENT '客户端 Key', `device_id` VARCHAR(128) DEFAULT NULL COMMENT '设备 ID', `entity_type` VARCHAR(64) DEFAULT NULL COMMENT '实体类型', `entity_id` VARCHAR(128) DEFAULT NULL COMMENT '实体 ID', `action` VARCHAR(64) DEFAULT NULL COMMENT '管理端动作', `status` VARCHAR(32) DEFAULT NULL COMMENT '状态 pending/applied/rejected/failed', `reason_codes` JSON DEFAULT NULL COMMENT '原因码', `request_payload` JSON DEFAULT NULL COMMENT '请求附加参数', `processed_at` DATETIME DEFAULT NULL COMMENT '客户端处理时间', `modified` DATETIME DEFAULT NULL COMMENT '更新时间', `created` DATETIME DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`), KEY `idx_de_admin_action_pending` (`_tenant_id`, `client_key`, `device_id`, `status`, `created`), KEY `idx_de_admin_action_entity` (`_tenant_id`, `entity_type`, `entity_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数字员工管理端远程动作意图'; CREATE TABLE IF NOT EXISTS `digital_employee_business_fact` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `_tenant_id` BIGINT NOT NULL COMMENT '租户ID', `user_id` BIGINT DEFAULT NULL COMMENT '用户ID', `sync_record_id` BIGINT NOT NULL COMMENT '同步记录ID', `client_key` VARCHAR(255) DEFAULT NULL COMMENT '客户端Key', `device_id` VARCHAR(255) DEFAULT NULL COMMENT '设备ID', `outbox_id` VARCHAR(255) DEFAULT NULL COMMENT '客户端outbox ID', `entity_type` VARCHAR(64) NOT NULL COMMENT '实体类型', `entity_id` VARCHAR(255) NOT NULL COMMENT '实体ID', `operation` VARCHAR(64) DEFAULT NULL COMMENT '操作', `title` VARCHAR(512) DEFAULT NULL COMMENT '标题', `status` VARCHAR(128) DEFAULT NULL COMMENT '业务状态', `summary` VARCHAR(1024) DEFAULT NULL COMMENT '摘要', `plan_id` VARCHAR(255) DEFAULT NULL COMMENT '计划ID', `task_id` VARCHAR(255) DEFAULT NULL COMMENT '任务ID', `run_id` VARCHAR(255) DEFAULT NULL COMMENT '运行ID', `kind` VARCHAR(255) DEFAULT NULL COMMENT '类型', `category` VARCHAR(128) DEFAULT NULL COMMENT '分类', `occurred_at` VARCHAR(64) DEFAULT NULL COMMENT '发生时间', `started_at` VARCHAR(64) DEFAULT NULL COMMENT '开始时间', `finished_at` VARCHAR(64) DEFAULT NULL COMMENT '结束时间', `duration_ms` BIGINT DEFAULT NULL COMMENT '耗时毫秒', `sync_status` VARCHAR(128) DEFAULT NULL COMMENT '同步状态', `business_view` JSON DEFAULT NULL COMMENT '业务视图快照', `payload` JSON DEFAULT NULL COMMENT '安全payload快照', `synced_at` DATETIME DEFAULT NULL COMMENT '同步时间', `modified` DATETIME NOT NULL COMMENT '修改时间', `created` DATETIME NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_de_business_fact_record` (`_tenant_id`, `sync_record_id`), KEY `idx_de_business_fact_entity` (`_tenant_id`, `entity_type`, `entity_id`), KEY `idx_de_business_fact_plan` (`_tenant_id`, `plan_id`, `entity_type`), KEY `idx_de_business_fact_client` (`_tenant_id`, `client_key`, `device_id`, `synced_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数字员工业务事实物化表'; CREATE TABLE IF NOT EXISTS `digital_employee_artifact_lifecycle` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `_tenant_id` BIGINT NOT NULL COMMENT '租户ID', `sync_record_id` BIGINT NOT NULL COMMENT '同步记录ID', `client_key` VARCHAR(255) DEFAULT NULL COMMENT '客户端Key', `device_id` VARCHAR(255) DEFAULT NULL COMMENT '设备ID', `artifact_id` VARCHAR(255) NOT NULL COMMENT '产物ID', `plan_id` VARCHAR(255) DEFAULT NULL COMMENT '计划ID', `task_id` VARCHAR(255) DEFAULT NULL COMMENT '任务ID', `run_id` VARCHAR(255) DEFAULT NULL COMMENT '运行ID', `status` VARCHAR(128) DEFAULT NULL COMMENT '状态', `retention_status` VARCHAR(128) DEFAULT NULL COMMENT '保留状态', `cleanup_status` VARCHAR(128) DEFAULT NULL COMMENT '清理状态', `deleted_at` VARCHAR(64) DEFAULT NULL COMMENT '删除时间', `version_key` VARCHAR(255) DEFAULT NULL COMMENT '版本Key', `source` VARCHAR(255) DEFAULT NULL COMMENT '来源', `business_view` JSON DEFAULT NULL COMMENT '业务视图快照', `synced_at` DATETIME DEFAULT NULL COMMENT '同步时间', `modified` DATETIME NOT NULL COMMENT '修改时间', `created` DATETIME NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_de_artifact_lifecycle_record` (`_tenant_id`, `sync_record_id`), KEY `idx_de_artifact_lifecycle_artifact` (`_tenant_id`, `artifact_id`), KEY `idx_de_artifact_lifecycle_plan` (`_tenant_id`, `plan_id`, `task_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数字员工产物生命周期物化表'; CREATE TABLE IF NOT EXISTS `digital_employee_daily_report_fact` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `_tenant_id` BIGINT NOT NULL COMMENT '租户ID', `sync_record_id` BIGINT NOT NULL COMMENT '同步记录ID', `client_key` VARCHAR(255) DEFAULT NULL COMMENT '客户端Key', `device_id` VARCHAR(255) DEFAULT NULL COMMENT '设备ID', `report_id` VARCHAR(255) NOT NULL COMMENT '日报ID', `plan_id` VARCHAR(255) DEFAULT NULL COMMENT '计划ID', `status` VARCHAR(128) DEFAULT NULL COMMENT '状态', `delivery_status` VARCHAR(128) DEFAULT NULL COMMENT '交付状态', `approval_status` VARCHAR(128) DEFAULT NULL COMMENT '审批状态', `confirmed_at` VARCHAR(64) DEFAULT NULL COMMENT '确认时间', `report_date` VARCHAR(64) DEFAULT NULL COMMENT '日报日期', `business_view` JSON DEFAULT NULL COMMENT '业务视图快照', `synced_at` DATETIME DEFAULT NULL COMMENT '同步时间', `modified` DATETIME NOT NULL COMMENT '修改时间', `created` DATETIME NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_de_daily_report_fact_record` (`_tenant_id`, `sync_record_id`), KEY `idx_de_daily_report_fact_report` (`_tenant_id`, `report_id`), KEY `idx_de_daily_report_fact_client` (`_tenant_id`, `client_key`, `device_id`, `synced_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数字员工日报事实物化表'; -- Add digital employee admin operations workbench menu and resource. -- Idempotent for existing tenants: creates menu/resource rows, binds menu to resource, -- and grants super_admin default access. Other roles can be granted this menu -- from the menu permission management UI. INSERT INTO sys_resource (`parent_id`, `code`, `name`, `description`, `source`, `type`, `sort_index`, `status`, `_tenant_id`, `creator_id`, `creator`, `yn`) SELECT parent.id, 'content_digital_employee_ops', '数字员工运营台', '数字员工运营台', 1, 1, 91, 1, parent.`_tenant_id`, 0, 'system', 1 FROM sys_resource parent WHERE parent.`code` = 'content_manage' AND parent.`yn` = 1 AND NOT EXISTS ( SELECT 1 FROM sys_resource r WHERE r.`_tenant_id` = parent.`_tenant_id` AND r.`code` = 'content_digital_employee_ops' AND r.`yn` = 1 ); INSERT INTO sys_resource (`parent_id`, `code`, `name`, `description`, `source`, `type`, `sort_index`, `status`, `_tenant_id`, `creator_id`, `creator`, `yn`) SELECT parent.id, 'content_digital_employee_ops_query_list', '查询列表', '查询数字员工运营台', 1, 2, 1, 1, parent.`_tenant_id`, 0, 'system', 1 FROM sys_resource parent WHERE parent.`code` = 'content_digital_employee_ops' AND parent.`yn` = 1 AND NOT EXISTS ( SELECT 1 FROM sys_resource r WHERE r.`_tenant_id` = parent.`_tenant_id` AND r.`code` = 'content_digital_employee_ops_query_list' AND r.`yn` = 1 ); INSERT INTO sys_menu (`parent_id`, `code`, `name`, `description`, `source`, `path`, `open_type`, `icon`, `sort_index`, `status`, `_tenant_id`, `creator_id`, `creator`, `yn`) SELECT parent.id, 'content_digital_employee_ops', '数字员工运营台', '数字员工运营台', 1, '/system/content/content-digital-employee-ops', 1, '', 91, 1, parent.`_tenant_id`, 0, 'system', 1 FROM sys_menu parent WHERE parent.`code` = 'content_manage' AND parent.`yn` = 1 AND NOT EXISTS ( SELECT 1 FROM sys_menu m WHERE m.`_tenant_id` = parent.`_tenant_id` AND m.`code` = 'content_digital_employee_ops' AND m.`yn` = 1 ); INSERT INTO sys_menu_resource (`menu_id`, `resource_id`, `resource_bind_type`, `_tenant_id`, `creator_id`, `creator`, `yn`) SELECT m.id, r.id, 1, m.`_tenant_id`, 0, 'system', 1 FROM sys_menu m JOIN sys_resource r ON r.`_tenant_id` = m.`_tenant_id` AND r.`code` = 'content_digital_employee_ops' AND r.`yn` = 1 WHERE m.`code` = 'content_digital_employee_ops' AND m.`yn` = 1 AND NOT EXISTS ( SELECT 1 FROM sys_menu_resource mr WHERE mr.`_tenant_id` = m.`_tenant_id` AND mr.`menu_id` = m.id AND mr.`resource_id` = r.id AND mr.`yn` = 1 ); UPDATE sys_menu_resource mr JOIN sys_menu m ON m.id = mr.menu_id AND m.`_tenant_id` = mr.`_tenant_id` AND m.`code` = 'content_digital_employee_ops' AND m.`yn` = 1 JOIN sys_resource r ON r.id = mr.resource_id AND r.`_tenant_id` = mr.`_tenant_id` AND r.`code` = 'content_digital_employee_ops' AND r.`yn` = 1 SET mr.`resource_bind_type` = 1, mr.`modified` = CURRENT_TIMESTAMP WHERE mr.`yn` = 1; INSERT INTO sys_role_menu (`role_id`, `menu_id`, `menu_bind_type`, `resource_tree_json`, `_tenant_id`, `creator_id`, `creator`, `yn`) SELECT role.id, menu.id, 1, JSON_ARRAY(JSON_OBJECT('id', resource.id, 'code', resource.`code`, 'resourceBindType', 1)), menu.`_tenant_id`, 0, 'system', 1 FROM sys_role role JOIN sys_menu menu ON menu.`_tenant_id` = role.`_tenant_id` AND menu.`code` = 'content_digital_employee_ops' AND menu.`yn` = 1 JOIN sys_resource resource ON resource.`_tenant_id` = role.`_tenant_id` AND resource.`code` = 'content_digital_employee_ops' AND resource.`yn` = 1 WHERE role.`code` = 'super_admin' AND role.`yn` = 1 AND NOT EXISTS ( SELECT 1 FROM sys_role_menu rm WHERE rm.`_tenant_id` = role.`_tenant_id` AND rm.`role_id` = role.id AND rm.`menu_id` = menu.id AND rm.`yn` = 1 ); UPDATE sys_role_menu rm JOIN sys_role role ON role.id = rm.role_id AND role.`_tenant_id` = rm.`_tenant_id` AND role.`code` = 'super_admin' AND role.`yn` = 1 JOIN sys_menu menu ON menu.id = rm.menu_id AND menu.`_tenant_id` = rm.`_tenant_id` AND menu.`code` = 'content_digital_employee_ops' AND menu.`yn` = 1 JOIN sys_resource resource ON resource.`_tenant_id` = rm.`_tenant_id` AND resource.`code` = 'content_digital_employee_ops' AND resource.`yn` = 1 SET rm.`menu_bind_type` = 1, rm.`resource_tree_json` = JSON_ARRAY(JSON_OBJECT('id', resource.id, 'code', resource.`code`, 'resourceBindType', 1)), rm.`modified` = CURRENT_TIMESTAMP WHERE rm.`yn` = 1;