-- 积分任务中心:一次性/每日任务、七牛截图、人工审核和积分发放。 CREATE TABLE IF NOT EXISTS `app_point_task` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID', `task_name` varchar(80) NOT NULL COMMENT '任务名称', `task_type` varchar(32) NOT NULL DEFAULT 'OTHER' COMMENT 'GROUP_JOIN/ARTICLE_SHARE/OTHER', `cycle_type` varchar(16) NOT NULL COMMENT 'ONCE一次性 DAILY每日一次', `cover_url` varchar(500) DEFAULT NULL COMMENT '任务封面', `description` varchar(1000) DEFAULT NULL COMMENT '任务说明', `operation_guide` text COMMENT '操作步骤', `example_images` varchar(2000) DEFAULT NULL COMMENT '示例截图,逗号分隔', `reward_points` int NOT NULL COMMENT '奖励积分', `start_time` datetime DEFAULT NULL COMMENT '开始时间', `end_time` datetime DEFAULT NULL COMMENT '结束时间', `allow_resubmit` tinyint NOT NULL DEFAULT 1 COMMENT '驳回后允许重提 0否 1是', `status` char(1) NOT NULL DEFAULT '0' COMMENT '0启用 1停用', `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序', `create_by` varchar(64) DEFAULT '', `create_time` datetime NOT NULL, `update_by` varchar(64) DEFAULT '', `update_time` datetime NOT NULL, PRIMARY KEY (`id`), KEY `idx_point_task_status_time` (`status`, `start_time`, `end_time`, `sort_order`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分任务表'; CREATE TABLE IF NOT EXISTS `app_point_task_submission` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '提交ID', `submission_no` varchar(40) NOT NULL COMMENT '提交单号', `task_id` bigint NOT NULL COMMENT '任务ID', `user_id` bigint NOT NULL COMMENT '用户ID', `cycle_key` varchar(16) NOT NULL COMMENT 'ONCE或yyyy-MM-dd', `reward_points` int NOT NULL COMMENT '提交时奖励积分快照', `remark` varchar(300) DEFAULT NULL COMMENT '用户说明', `status` tinyint NOT NULL DEFAULT 0 COMMENT '0待审核 1已通过 2已驳回 3已撤销', `attempt_count` int NOT NULL DEFAULT 1 COMMENT '提交次数', `reject_reason` varchar(300) DEFAULT NULL COMMENT '驳回或撤销原因', `review_by` varchar(64) DEFAULT NULL COMMENT '审核人', `review_time` datetime DEFAULT NULL COMMENT '审核时间', `reward_record_id` bigint DEFAULT NULL COMMENT '奖励积分流水ID', `first_submit_time` datetime NOT NULL COMMENT '首次提交时间', `last_submit_time` datetime NOT NULL COMMENT '最近提交时间', `create_by` varchar(64) DEFAULT '', `create_time` datetime NOT NULL, `update_by` varchar(64) DEFAULT '', `update_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_point_task_submission_no` (`submission_no`), UNIQUE KEY `uk_point_task_user_cycle` (`task_id`, `user_id`, `cycle_key`), KEY `idx_point_task_submission_status` (`status`, `last_submit_time`), KEY `idx_point_task_submission_user` (`user_id`, `last_submit_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分任务提交表'; CREATE TABLE IF NOT EXISTS `app_point_task_attachment` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '附件ID', `submission_id` bigint DEFAULT NULL COMMENT '提交ID,上传阶段为空', `user_id` bigint NOT NULL COMMENT '用户ID', `object_key` varchar(500) NOT NULL COMMENT '七牛对象Key', `original_name` varchar(255) DEFAULT NULL COMMENT '原文件名', `file_size` bigint DEFAULT NULL COMMENT '文件大小', `file_type` varchar(64) DEFAULT NULL COMMENT 'MIME类型', `upload_status` varchar(16) NOT NULL DEFAULT 'TEMP' COMMENT 'TEMP/BOUND', `submit_batch` int NOT NULL DEFAULT 0 COMMENT '第几次提交', `is_current` tinyint NOT NULL DEFAULT 0 COMMENT '是否当前审核附件', `create_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_point_task_object_key` (`object_key`), KEY `idx_point_task_attachment_submission` (`submission_id`, `submit_batch`, `is_current`), KEY `idx_point_task_attachment_temp` (`upload_status`, `create_time`), KEY `idx_point_task_attachment_user_quota` (`user_id`, `upload_status`, `create_time`), KEY `idx_point_task_attachment_user_daily` (`user_id`, `create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分任务截图附件表'; -- 已有积分任务表时补充用户上传配额查询索引。 SET @attachment_quota_index_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_point_task_attachment' AND INDEX_NAME = 'idx_point_task_attachment_user_quota' ); SET @attachment_quota_index_sql := IF(@attachment_quota_index_exists = 0, 'ALTER TABLE `app_point_task_attachment` ADD KEY `idx_point_task_attachment_user_quota` (`user_id`, `upload_status`, `create_time`)', 'SELECT 1'); PREPARE attachment_quota_index_stmt FROM @attachment_quota_index_sql; EXECUTE attachment_quota_index_stmt; DEALLOCATE PREPARE attachment_quota_index_stmt; SET @attachment_daily_index_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_point_task_attachment' AND INDEX_NAME = 'idx_point_task_attachment_user_daily' ); SET @attachment_daily_index_sql := IF(@attachment_daily_index_exists = 0, 'ALTER TABLE `app_point_task_attachment` ADD KEY `idx_point_task_attachment_user_daily` (`user_id`, `create_time`)', 'SELECT 1'); PREPARE attachment_daily_index_stmt FROM @attachment_daily_index_sql; EXECUTE attachment_daily_index_stmt; DEALLOCATE PREPARE attachment_daily_index_stmt; CREATE TABLE IF NOT EXISTS `app_point_task_audit_log` ( `id` bigint NOT NULL AUTO_INCREMENT, `submission_id` bigint NOT NULL, `before_status` tinyint DEFAULT NULL, `after_status` tinyint NOT NULL, `operator_name` varchar(64) NOT NULL, `remark` varchar(500) DEFAULT NULL, `create_time` datetime NOT NULL, PRIMARY KEY (`id`), KEY `idx_point_task_audit_submission` (`submission_id`, `create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分任务审核日志表'; -- 积分流水业务幂等字段。 SET @biz_type_exists := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_integral_record' AND COLUMN_NAME = 'biz_type' ); SET @biz_type_sql := IF(@biz_type_exists = 0, 'ALTER TABLE `app_integral_record` ADD COLUMN `biz_type` varchar(32) DEFAULT NULL COMMENT ''业务类型'' AFTER `resource_id`', 'SELECT 1'); PREPARE biz_type_stmt FROM @biz_type_sql; EXECUTE biz_type_stmt; DEALLOCATE PREPARE biz_type_stmt; SET @biz_id_exists := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_integral_record' AND COLUMN_NAME = 'biz_id' ); SET @biz_id_sql := IF(@biz_id_exists = 0, 'ALTER TABLE `app_integral_record` ADD COLUMN `biz_id` bigint DEFAULT NULL COMMENT ''业务记录ID'' AFTER `biz_type`', 'SELECT 1'); PREPARE biz_id_stmt FROM @biz_id_sql; EXECUTE biz_id_stmt; DEALLOCATE PREPARE biz_id_stmt; SET @biz_index_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'app_integral_record' AND INDEX_NAME = 'uk_integral_biz' ); SET @biz_index_sql := IF(@biz_index_exists = 0, 'ALTER TABLE `app_integral_record` ADD UNIQUE KEY `uk_integral_biz` (`biz_type`, `biz_id`)', 'SELECT 1'); PREPARE biz_index_stmt FROM @biz_index_sql; EXECUTE biz_index_stmt; DEALLOCATE PREPARE biz_index_stmt; -- 后台菜单。 SET @point_task_parent_id := COALESCE( (SELECT parent_id FROM sys_menu WHERE perms = 'app:resource:list' LIMIT 1), (SELECT parent_id FROM sys_menu WHERE perms = 'app:article:list' LIMIT 1), 0 ); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '积分任务', @point_task_parent_id, 30, 'pointTask', 'app/pointTask/index', '', 1, 0, 'C', '0', '0', 'app:pointTask:list', 'guide', 'admin', NOW(), '', NULL, '积分任务配置' WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTask:list'); SET @point_task_menu_id := (SELECT menu_id FROM sys_menu WHERE perms = 'app:pointTask:list' LIMIT 1); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '任务查询', @point_task_menu_id, 1, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTask:query', '#', 'admin', NOW(), '', NULL, '' WHERE @point_task_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTask:query'); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '任务新增', @point_task_menu_id, 2, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTask:add', '#', 'admin', NOW(), '', NULL, '' WHERE @point_task_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTask:add'); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '任务修改', @point_task_menu_id, 3, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTask:edit', '#', 'admin', NOW(), '', NULL, '' WHERE @point_task_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTask:edit'); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '任务删除', @point_task_menu_id, 4, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTask:remove', '#', 'admin', NOW(), '', NULL, '' WHERE @point_task_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTask:remove'); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '任务审核', @point_task_parent_id, 31, 'pointTaskReview', 'app/pointTaskReview/index', '', 1, 0, 'C', '0', '0', 'app:pointTaskReview:list', 'audit', 'admin', NOW(), '', NULL, '积分任务审核' WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTaskReview:list'); SET @point_review_menu_id := (SELECT menu_id FROM sys_menu WHERE perms = 'app:pointTaskReview:list' LIMIT 1); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '审核查询', @point_review_menu_id, 1, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTaskReview:query', '#', 'admin', NOW(), '', NULL, '' WHERE @point_review_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTaskReview:query'); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '任务审核操作', @point_review_menu_id, 2, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTaskReview:edit', '#', 'admin', NOW(), '', NULL, '' WHERE @point_review_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTaskReview:edit'); INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) SELECT '撤销任务奖励', @point_review_menu_id, 3, '', '', '', 1, 0, 'F', '0', '0', 'app:pointTaskReview:revoke', '#', 'admin', NOW(), '', NULL, '' WHERE @point_review_menu_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'app:pointTaskReview:revoke');