-- ============================================================================= -- 保洁自动建单 / 报修自动流转(增量,可重放) -- 口径: -- 1) 离寓判定以 gy_jcxx 在寓事实为准:finish_ly='0' AND sjlysj IS NULL; -- gy_rooms.in_person_count 由该口径重算,不再依赖 +1/-1。 -- 2) 同房同一时刻只允许一条活跃保洁任务(PENDING/PROCESSING): -- active_room 生成列 + 唯一索引,服务层先判后插,库层兜底并发。 -- 3) source 增加 AUTO(全员离寓自动建单);TABLET=平板上报 / MANUAL=后台补录。 -- 幂等:列/索引均做 information_schema 判断,可重复执行。 -- ============================================================================= SET NAMES utf8mb4; -- ----------------------------------------------------------------------------- -- 1. 保洁任务:活跃占位列 + 唯一索引(同房仅一条待处理/保洁中) -- ----------------------------------------------------------------------------- CALL apt_add_column_if_missing('gy_clean_task', 'active_room', "active_room VARCHAR(64) GENERATED ALWAYS AS (CASE WHEN state IN ('PENDING','PROCESSING') AND deleted = 0 THEN room_id END) STORED COMMENT '活跃任务房号占位:同房同时只允许一条待处理/保洁中'"); SET @apt_idx_active = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'gy_clean_task' AND INDEX_NAME = 'uk_cleantask_gyid_active_room'); SET @apt_sql_active = IF(@apt_idx_active = 0, 'ALTER TABLE gy_clean_task ADD UNIQUE KEY uk_cleantask_gyid_active_room (gyid, active_room)', 'SELECT 1'); PREPARE stmt_cleantask_active FROM @apt_sql_active; EXECUTE stmt_cleantask_active; DEALLOCATE PREPARE stmt_cleantask_active; -- ----------------------------------------------------------------------------- -- 2. 查询索引:按房号找活跃任务 / 按房号统计在寓人数 -- ----------------------------------------------------------------------------- SET @apt_idx_room = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'gy_clean_task' AND INDEX_NAME = 'idx_cleantask_gyid_room_state'); SET @apt_sql_room = IF(@apt_idx_room = 0, 'ALTER TABLE gy_clean_task ADD KEY idx_cleantask_gyid_room_state (gyid, room_id, state, deleted)', 'SELECT 1'); PREPARE stmt_cleantask_room FROM @apt_sql_room; EXECUTE stmt_cleantask_room; DEALLOCATE PREPARE stmt_cleantask_room; SET @apt_idx_stay = (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'gy_jcxx' AND INDEX_NAME = 'idx_jcxx_gyid_room_leave'); SET @apt_sql_stay = IF(@apt_idx_stay = 0, 'ALTER TABLE gy_jcxx ADD KEY idx_jcxx_gyid_room_leave (gyid, fjh, finish_ly)', 'SELECT 1'); PREPARE stmt_jcxx_room FROM @apt_sql_stay; EXECUTE stmt_jcxx_room; DEALLOCATE PREPARE stmt_jcxx_room; -- ----------------------------------------------------------------------------- -- 3. source 取值口径补充 AUTO -- ----------------------------------------------------------------------------- ALTER TABLE gy_clean_task MODIFY COLUMN source VARCHAR(20) NOT NULL DEFAULT 'TABLET' COMMENT 'TABLET=平板上报 / MANUAL=后台补录 / AUTO=全员离寓自动建单'; -- ----------------------------------------------------------------------------- -- 4. 校验 -- ----------------------------------------------------------------------------- SELECT '=== 53. active_room 生成列(应 1:STORED GENERATED)===' AS section; SELECT COLUMN_NAME, COLUMN_TYPE, EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'gy_clean_task' AND COLUMN_NAME = 'active_room'; SELECT '=== 54. 同房唯一活跃任务索引(应 1)===' AS section; SELECT INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS cols FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'gy_clean_task' AND INDEX_NAME IN ('uk_cleantask_gyid_active_room','idx_cleantask_gyid_room_state') GROUP BY INDEX_NAME; SELECT '=== 55. 在寓判定索引(应 1)===' AS section; SELECT INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS cols FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'gy_jcxx' AND INDEX_NAME = 'idx_jcxx_gyid_room_leave' GROUP BY INDEX_NAME; SELECT '=== 56. 当前活跃保洁任务(每个房间应 <= 1)===' AS section; SELECT gyid, room_id, COUNT(*) AS active_cnt FROM gy_clean_task WHERE state IN ('PENDING','PROCESSING') AND deleted = 0 GROUP BY gyid, room_id HAVING active_cnt > 1;