428 lines
20 KiB
SQL
428 lines
20 KiB
SQL
-- Aslan Gift Challenge: non-lucky paid-gift ranking, daily tasks and reward settlement.
|
|
--
|
|
-- Performance review (DDL only; run through the normal deployment migration process):
|
|
-- 1. The gift hot path inserts one row through uq_aslan_gc_ledger_source_event, then updates one
|
|
-- overall PK row, one daily PK row and at most three daily-task rows. Every lookup is bounded
|
|
-- by activity/user/date keys and is O(log N); ranking never GROUP BYs the append-only ledger.
|
|
-- 2. Overall and daily Top-N queries bind activity_id (and stat_date for DAILY) before reading
|
|
-- score order from covering indexes. The same score/reached-time/user-id order supports a
|
|
-- deterministic rank query without sorting the entire activity in memory.
|
|
-- 3. Campaign lookup uses idx_aslan_gc_activity_window. start_time is the range column and
|
|
-- end_time is an index-covered residual filter; enabled campaigns per sys_origin are expected
|
|
-- to remain few and overlapping enabled windows are rejected by the application transaction.
|
|
-- 4. Period headers make an empty DAILY ranking settle exactly once and gate late writes after a
|
|
-- snapshot starts. Due headers and task-delivery recovery use status/time indexes; reward
|
|
-- reconciliation reads only one frozen owner and its configured group through unique keys.
|
|
-- 5. No UPDATE or DELETE below uses an unindexed predicate. This migration creates empty campaign
|
|
-- tables and idempotent RBAC rows only; it does not scan or backfill gift_give_running_water.
|
|
-- 6. Before production rollout, run EXPLAIN for display-activity, Top-N, my-rank, due-settlement
|
|
-- and recovery queries against production-like cardinality. Any gift-history backfill must use
|
|
-- a checked Mongo index and an id cursor; OFFSET/full collection scans are explicitly excluded.
|
|
-- 7. Enabling a campaign inserts at most 366 DAILY headers in one batched primary/unique-key write.
|
|
-- claim_request_id adds one nullable audit index updated only on the first successful task claim.
|
|
-- 8. Enabling also freezes at most 5000 reward rows in batches of 500. Reads always bind
|
|
-- activity_id + resource_group_id and follow idx_aslan_gc_reward_snapshot_group; pre-start
|
|
-- rebuild/delete binds activity_id and uses the same leftmost index prefix, so no table scan is
|
|
-- introduced when a shared reward group is edited later.
|
|
|
|
SET NAMES utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_activity (
|
|
id BIGINT NOT NULL,
|
|
activity_code VARCHAR(64) NOT NULL,
|
|
activity_name VARCHAR(128) NOT NULL,
|
|
activity_desc VARCHAR(1000) NULL,
|
|
sys_origin VARCHAR(32) NOT NULL,
|
|
time_zone VARCHAR(64) NOT NULL DEFAULT 'Asia/Riyadh',
|
|
start_time DATETIME(3) NOT NULL,
|
|
end_time DATETIME(3) NOT NULL,
|
|
daily_settlement_delay_minutes INT NOT NULL DEFAULT 30,
|
|
overall_settlement_delay_minutes INT NOT NULL DEFAULT 30,
|
|
overall_settlement_time DATETIME(3) NOT NULL,
|
|
display_top_n SMALLINT NOT NULL DEFAULT 100,
|
|
enabled TINYINT(1) NOT NULL DEFAULT 0,
|
|
overall_settlement_status VARCHAR(32) NOT NULL DEFAULT 'NOT_STARTED',
|
|
version INT NOT NULL DEFAULT 0,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_activity_code (activity_code),
|
|
KEY idx_aslan_gc_activity_window (sys_origin, enabled, start_time, end_time),
|
|
KEY idx_aslan_gc_activity_settle (
|
|
overall_settlement_status, overall_settlement_time, end_time, id
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Aslan paid non-lucky gift challenge campaign';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_task_config (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
task_code VARCHAR(64) NOT NULL,
|
|
task_type VARCHAR(32) NOT NULL COMMENT 'ENTER_PAGE or SEND_GIFT_GOLD',
|
|
task_title VARCHAR(128) NOT NULL,
|
|
task_desc VARCHAR(500) NULL,
|
|
target_value DECIMAL(24,2) NOT NULL,
|
|
resource_group_id BIGINT NULL,
|
|
enabled TINYINT(1) NOT NULL DEFAULT 1,
|
|
sort_order SMALLINT NOT NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_task_code (activity_id, task_code),
|
|
UNIQUE KEY uq_aslan_gc_task_sort (activity_id, sort_order),
|
|
KEY idx_aslan_gc_task_enabled (activity_id, enabled, sort_order)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Exactly three activity-scoped daily task definitions';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_rank_reward (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
period_type VARCHAR(16) NOT NULL COMMENT 'DAILY or OVERALL',
|
|
start_rank SMALLINT NOT NULL,
|
|
end_rank SMALLINT NOT NULL,
|
|
resource_group_id BIGINT NOT NULL,
|
|
reward_name VARCHAR(128) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_rank_range (activity_id, period_type, start_rank, end_rank),
|
|
KEY idx_aslan_gc_rank_start (activity_id, period_type, start_rank, end_rank)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Configurable DAILY and OVERALL rank reward ranges';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_reward_snapshot (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
resource_group_id BIGINT NOT NULL,
|
|
reward_config_id BIGINT NOT NULL,
|
|
reward_type VARCHAR(32) NOT NULL,
|
|
detail_type VARCHAR(64) NULL,
|
|
content VARCHAR(500) NULL,
|
|
quantity INT NULL,
|
|
sort_order INT NULL,
|
|
remark VARCHAR(500) NULL,
|
|
cover TEXT NULL,
|
|
source_url TEXT NULL,
|
|
display_name VARCHAR(500) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_reward_snapshot (
|
|
activity_id, resource_group_id, reward_config_id
|
|
),
|
|
KEY idx_aslan_gc_reward_snapshot_group (
|
|
activity_id, resource_group_id, sort_order, reward_config_id
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Immutable per-activity reward item templates captured before start';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_gift_ledger (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
source_event_track_id BIGINT NOT NULL,
|
|
user_id BIGINT NOT NULL,
|
|
gift_id BIGINT NOT NULL,
|
|
gift_tab VARCHAR(32) NULL,
|
|
amount DECIMAL(24,2) NOT NULL,
|
|
event_time DATETIME(3) NOT NULL,
|
|
stat_date DATE NOT NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_ledger_source_event (activity_id, source_event_track_id),
|
|
KEY idx_aslan_gc_ledger_user (activity_id, user_id, event_time),
|
|
KEY idx_aslan_gc_ledger_date (activity_id, stat_date, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Idempotent eligible paid-gift fact ledger';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_user_score (
|
|
activity_id BIGINT NOT NULL,
|
|
user_id BIGINT NOT NULL,
|
|
score DECIMAL(24,2) NOT NULL DEFAULT 0,
|
|
score_reached_time DATETIME(3) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (activity_id, user_id),
|
|
KEY idx_aslan_gc_user_rank (
|
|
activity_id, score DESC, score_reached_time ASC, user_id ASC
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Activity-wide user score aggregate';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_user_daily_score (
|
|
activity_id BIGINT NOT NULL,
|
|
stat_date DATE NOT NULL,
|
|
user_id BIGINT NOT NULL,
|
|
score DECIMAL(24,2) NOT NULL DEFAULT 0,
|
|
score_reached_time DATETIME(3) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (activity_id, stat_date, user_id),
|
|
KEY idx_aslan_gc_daily_rank (
|
|
activity_id, stat_date, score DESC, score_reached_time ASC, user_id ASC
|
|
)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Activity-timezone daily user score aggregate';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_user_task_daily (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
stat_date DATE NOT NULL,
|
|
user_id BIGINT NOT NULL,
|
|
task_config_id BIGINT NOT NULL,
|
|
task_code VARCHAR(64) NOT NULL,
|
|
task_type VARCHAR(32) NOT NULL,
|
|
task_title VARCHAR(128) NOT NULL,
|
|
sort_order SMALLINT NOT NULL,
|
|
target_value DECIMAL(24,2) NOT NULL,
|
|
progress_value DECIMAL(24,2) NOT NULL DEFAULT 0,
|
|
completed_time DATETIME(3) NULL,
|
|
resource_group_id BIGINT NULL,
|
|
business_no VARCHAR(160) NOT NULL,
|
|
claim_request_id VARCHAR(128) NULL COMMENT 'First successful H5 claim request audit id',
|
|
delivery_status VARCHAR(32) NOT NULL DEFAULT 'NOT_CLAIMED'
|
|
COMMENT 'NOT_CLAIMED, PENDING, PROCESSING, SUCCESS or UNKNOWN',
|
|
retry_count INT NOT NULL DEFAULT 0,
|
|
failure_reason VARCHAR(500) NULL,
|
|
claimed_time DATETIME(3) NULL,
|
|
deliver_time DATETIME(3) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_task_daily (activity_id, stat_date, user_id, task_code),
|
|
UNIQUE KEY uq_aslan_gc_task_business (business_no),
|
|
KEY idx_aslan_gc_task_user (activity_id, user_id, stat_date, sort_order),
|
|
KEY idx_aslan_gc_task_claim_request (claim_request_id),
|
|
KEY idx_aslan_gc_task_recover (delivery_status, update_time, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Daily task target/reward snapshot, progress and claim state';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_period_settlement (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
period_type VARCHAR(16) NOT NULL COMMENT 'DAILY or OVERALL',
|
|
period_key VARCHAR(16) NOT NULL COMMENT 'yyyy-MM-dd for DAILY, OVERALL otherwise',
|
|
stat_date DATE NULL,
|
|
snapshot_due_time DATETIME(3) NOT NULL,
|
|
status VARCHAR(32) NOT NULL DEFAULT 'NOT_STARTED'
|
|
COMMENT 'NOT_STARTED, PROCESSING, COMPLETED or RECONCILIATION_REQUIRED',
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_period (activity_id, period_type, period_key),
|
|
KEY idx_aslan_gc_period_due (status, snapshot_due_time, id),
|
|
KEY idx_aslan_gc_period_activity (activity_id, period_type, status, period_key)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Per-period snapshot gate including empty DAILY rankings';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_settlement (
|
|
id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
period_type VARCHAR(16) NOT NULL COMMENT 'DAILY or OVERALL',
|
|
period_key VARCHAR(16) NOT NULL COMMENT 'yyyy-MM-dd for DAILY, OVERALL otherwise',
|
|
stat_date DATE NULL,
|
|
user_id BIGINT NOT NULL,
|
|
rank_no SMALLINT NOT NULL,
|
|
score DECIMAL(24,2) NOT NULL,
|
|
rank_reward_id BIGINT NOT NULL,
|
|
resource_group_id BIGINT NOT NULL,
|
|
business_no VARCHAR(160) NOT NULL,
|
|
delivery_status VARCHAR(32) NOT NULL COMMENT 'PENDING, PROCESSING, SUCCESS or UNKNOWN',
|
|
retry_count INT NOT NULL DEFAULT 0,
|
|
failure_reason VARCHAR(500) NULL,
|
|
deliver_time DATETIME(3) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_settlement_user (
|
|
activity_id, period_type, period_key, user_id
|
|
),
|
|
UNIQUE KEY uq_aslan_gc_settlement_rank (
|
|
activity_id, period_type, period_key, rank_no
|
|
),
|
|
UNIQUE KEY uq_aslan_gc_settlement_business (business_no),
|
|
KEY idx_aslan_gc_settlement_status (
|
|
activity_id, period_type, period_key, delivery_status, rank_no
|
|
),
|
|
KEY idx_aslan_gc_settlement_recover (delivery_status, update_time, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Frozen DAILY/OVERALL rank snapshots and delivery state';
|
|
|
|
CREATE TABLE IF NOT EXISTS aslan_gift_challenge_delivery_item (
|
|
id BIGINT NOT NULL,
|
|
owner_type VARCHAR(20) NOT NULL COMMENT 'TASK or SETTLEMENT',
|
|
owner_id BIGINT NOT NULL,
|
|
activity_id BIGINT NOT NULL,
|
|
user_id BIGINT NOT NULL,
|
|
reward_config_id BIGINT NOT NULL,
|
|
resource_group_id BIGINT NOT NULL,
|
|
reward_type VARCHAR(32) NOT NULL,
|
|
detail_type VARCHAR(64) NULL,
|
|
content VARCHAR(500) NULL,
|
|
quantity INT NULL,
|
|
sort_order INT NULL,
|
|
remark VARCHAR(500) NULL,
|
|
delivery_status VARCHAR(32) NOT NULL COMMENT 'PENDING, PROCESSING, SUCCESS or UNKNOWN',
|
|
retry_count INT NOT NULL DEFAULT 0,
|
|
failure_reason VARCHAR(500) NULL,
|
|
deliver_time DATETIME(3) NULL,
|
|
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_aslan_gc_delivery_config (owner_type, owner_id, reward_config_id),
|
|
KEY idx_aslan_gc_delivery_owner (owner_type, owner_id, delivery_status),
|
|
KEY idx_aslan_gc_delivery_activity (activity_id, delivery_status, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Per reward-config transactional delivery outbox';
|
|
|
|
-- RBAC is idempotent. The page is inherited only by roles that already own Operations.
|
|
INSERT INTO sys_resource (id, resource_name, mapping, method, auth_type, perm, update_time)
|
|
VALUES
|
|
('activity:gift-challenge:list', '礼物挑战活动列表', '/activity/gift-challenge/list', 'GET', 3, 'activity:gift-challenge:list', NOW()),
|
|
('activity:gift-challenge:detail', '礼物挑战活动详情', '/activity/gift-challenge/detail/**', 'GET', 3, 'activity:gift-challenge:detail', NOW()),
|
|
('activity:gift-challenge:save', '保存礼物挑战活动', '/activity/gift-challenge/save', 'POST', 3, 'activity:gift-challenge:save', NOW()),
|
|
('activity:gift-challenge:enable', '启停礼物挑战活动', '/activity/gift-challenge/enable/**', 'PUT', 3, 'activity:gift-challenge:enable', NOW()),
|
|
('activity:gift-challenge:tasks:get', '礼物挑战任务列表', '/activity/gift-challenge/tasks/**', 'GET', 3, 'activity:gift-challenge:tasks:get', NOW()),
|
|
('activity:gift-challenge:tasks:save', '保存礼物挑战任务', '/activity/gift-challenge/tasks/**', 'PUT', 3, 'activity:gift-challenge:tasks:save', NOW()),
|
|
('activity:gift-challenge:rank:get', '礼物挑战排名奖励', '/activity/gift-challenge/rank-rewards/**', 'GET', 3, 'activity:gift-challenge:rank:get', NOW()),
|
|
('activity:gift-challenge:rank:save', '保存礼物挑战排名奖励', '/activity/gift-challenge/rank-rewards/**', 'PUT', 3, 'activity:gift-challenge:rank:save', NOW()),
|
|
('activity:gift-challenge:ranking', '查看礼物挑战榜单', '/activity/gift-challenge/ranking/**', 'GET', 3, 'activity:gift-challenge:ranking', NOW()),
|
|
('activity:gift-challenge:settlement:get', '礼物挑战结算记录', '/activity/gift-challenge/settlement-records/**', 'GET', 3, 'activity:gift-challenge:settlement:get', NOW()),
|
|
('activity:gift-challenge:settlement:run', '执行礼物挑战结算', '/activity/gift-challenge/settlement/**', 'POST', 3, 'activity:gift-challenge:settlement:run', NOW()),
|
|
('activity:gift-challenge:delivery:resolve', '核账处理礼物挑战未知奖励', '/activity/gift-challenge/delivery-item/resolve/**', 'POST', 3, 'activity:gift-challenge:delivery:resolve', NOW())
|
|
ON DUPLICATE KEY UPDATE
|
|
resource_name = VALUES(resource_name),
|
|
mapping = VALUES(mapping),
|
|
method = VALUES(method),
|
|
auth_type = VALUES(auth_type),
|
|
perm = VALUES(perm),
|
|
update_time = NOW();
|
|
|
|
INSERT INTO sys_menu (
|
|
parent_id, menu_name, path, router, menu_type, icon, alias, sort, status,
|
|
create_user, update_user, create_time, update_time
|
|
)
|
|
SELECT
|
|
parent.id,
|
|
'礼物挑战活动',
|
|
'activity/gift-challenge/index',
|
|
'activity/gift-challenge',
|
|
2,
|
|
'gift',
|
|
'ActivityGiftChallenge',
|
|
89,
|
|
0,
|
|
'0',
|
|
'0',
|
|
NOW(),
|
|
NOW()
|
|
FROM sys_menu parent
|
|
LEFT JOIN sys_menu existing ON existing.alias = 'ActivityGiftChallenge'
|
|
WHERE (parent.alias = 'OperationManager' OR parent.menu_name = '运营管理')
|
|
AND parent.menu_type = 1
|
|
AND existing.id IS NULL
|
|
LIMIT 1;
|
|
|
|
UPDATE sys_menu campaign_menu
|
|
JOIN (
|
|
SELECT id
|
|
FROM sys_menu
|
|
WHERE (alias = 'OperationManager' OR menu_name = '运营管理')
|
|
AND menu_type = 1
|
|
LIMIT 1
|
|
) parent ON 1 = 1
|
|
SET
|
|
campaign_menu.parent_id = parent.id,
|
|
campaign_menu.menu_name = '礼物挑战活动',
|
|
campaign_menu.path = 'activity/gift-challenge/index',
|
|
campaign_menu.router = 'activity/gift-challenge',
|
|
campaign_menu.menu_type = 2,
|
|
campaign_menu.icon = 'gift',
|
|
campaign_menu.sort = 89,
|
|
campaign_menu.status = 0,
|
|
campaign_menu.update_user = '0',
|
|
campaign_menu.update_time = NOW()
|
|
WHERE campaign_menu.alias = 'ActivityGiftChallenge';
|
|
|
|
INSERT INTO sys_menu_resource (menu_id, resource_id)
|
|
SELECT menu.id, resource.id
|
|
FROM sys_menu menu
|
|
JOIN sys_resource resource ON resource.id LIKE 'activity:gift-challenge:%'
|
|
LEFT JOIN sys_menu_resource existing
|
|
ON existing.menu_id = menu.id AND existing.resource_id = resource.id
|
|
WHERE menu.alias = 'ActivityGiftChallenge'
|
|
AND existing.id IS NULL;
|
|
|
|
INSERT INTO sys_role_menu (role_id, menu_id)
|
|
SELECT DISTINCT source_role.role_id, campaign_menu.id
|
|
FROM sys_role_menu source_role
|
|
JOIN sys_menu source_menu ON source_menu.id = source_role.menu_id
|
|
JOIN sys_menu campaign_menu ON campaign_menu.alias = 'ActivityGiftChallenge'
|
|
LEFT JOIN sys_role_menu existing
|
|
ON existing.role_id = source_role.role_id AND existing.menu_id = campaign_menu.id
|
|
WHERE (source_menu.alias = 'OperationManager' OR source_menu.menu_name = '运营管理')
|
|
AND source_menu.menu_type = 1
|
|
AND existing.id IS NULL;
|
|
|
|
-- Buttons are real menu_type=3 rows because controller-side hasButtonsAlias checks sys_menu.alias,
|
|
-- not sys_resource.perm. Existing page owners inherit all four buttons idempotently.
|
|
INSERT INTO sys_menu (
|
|
parent_id, menu_name, path, router, menu_type, icon, alias, sort, status,
|
|
create_user, update_user, create_time, update_time
|
|
)
|
|
SELECT
|
|
page.id,
|
|
button.menu_name,
|
|
'',
|
|
'',
|
|
3,
|
|
'',
|
|
button.alias,
|
|
button.sort_no,
|
|
0,
|
|
'0',
|
|
'0',
|
|
NOW(),
|
|
NOW()
|
|
FROM sys_menu page
|
|
JOIN (
|
|
SELECT '编辑礼物挑战配置' AS menu_name, 'activity:gift-challenge:edit' AS alias, 1 AS sort_no
|
|
UNION ALL
|
|
SELECT '启停礼物挑战活动', 'activity:gift-challenge:enable', 2
|
|
UNION ALL
|
|
SELECT '执行礼物挑战结算', 'activity:gift-challenge:settle', 3
|
|
UNION ALL
|
|
SELECT '核账礼物挑战未知奖励', 'activity:gift-challenge:reconcile', 4
|
|
) button ON 1 = 1
|
|
LEFT JOIN sys_menu existing ON existing.alias = button.alias
|
|
WHERE page.alias = 'ActivityGiftChallenge'
|
|
AND existing.id IS NULL;
|
|
|
|
UPDATE sys_menu button
|
|
JOIN sys_menu page ON page.alias = 'ActivityGiftChallenge'
|
|
SET
|
|
button.parent_id = page.id,
|
|
button.menu_type = 3,
|
|
button.status = 0,
|
|
button.update_user = '0',
|
|
button.update_time = NOW()
|
|
WHERE button.alias IN (
|
|
'activity:gift-challenge:edit',
|
|
'activity:gift-challenge:enable',
|
|
'activity:gift-challenge:settle',
|
|
'activity:gift-challenge:reconcile'
|
|
);
|
|
|
|
INSERT INTO sys_role_menu (role_id, menu_id)
|
|
SELECT DISTINCT page_role.role_id, button.id
|
|
FROM sys_role_menu page_role
|
|
JOIN sys_menu page ON page.id = page_role.menu_id AND page.alias = 'ActivityGiftChallenge'
|
|
JOIN sys_menu button ON button.parent_id = page.id AND button.menu_type = 3
|
|
LEFT JOIN sys_role_menu existing
|
|
ON existing.role_id = page_role.role_id AND existing.menu_id = button.id
|
|
WHERE button.alias IN (
|
|
'activity:gift-challenge:edit',
|
|
'activity:gift-challenge:enable',
|
|
'activity:gift-challenge:settle',
|
|
'activity:gift-challenge:reconcile'
|
|
)
|
|
AND existing.id IS NULL;
|