Files
meijiaka-zy/scripts/admin-ops.sql
T

406 lines
13 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================
-- 美家卡智影 - 后台运维 SQL 脚本
-- 适用场景:暂无管理后台,直接操作数据库
-- 注意:所有操作应在事务中执行,操作前请备份数据
-- ============================================================
-- -----------------------------------------------------------
-- 一、新增用户(支持同时赠送初始积分)
-- -----------------------------------------------------------
-- 用法:修改下方变量后执行
DO $$
DECLARE
v_mobile TEXT := '13559213930'; -- ← 修改:手机号
v_nickname TEXT := '俊宏'; -- ← 修改:昵称(可为空)
v_source TEXT := 'manual'; -- ← 修改:注册来源:manual / invite / promotion
v_invited_by UUID := NULL; -- ← 修改:邀请人 user_id(没有则留 NULL
v_gift_points INT := 2000; -- ← 修改:赠送初始积分(0 表示不赠送)
v_gift_days INT := 365; -- ← 修改:赠送积分有效期(天)
v_user_id UUID;
v_batch_id BIGINT;
v_now TIMESTAMPTZ := NOW();
BEGIN
-- 1. 插入用户
INSERT INTO mjk_users (
id, mobile, password_hash, status, nickname,
avatar_url, source, invited_by,
last_login_at, last_login_ip, deleted_at, extra,
created_at, updated_at
) VALUES (
gen_random_uuid(),
v_mobile,
NULL, -- 密码哈希(未设置密码)
'active',
v_nickname,
NULL,
v_source,
v_invited_by,
NULL, NULL, NULL,
'{}'::JSONB,
v_now, v_now
)
RETURNING id INTO v_user_id;
-- 2. 初始化积分汇总(余额为 0)
INSERT INTO mjk_user_points (
user_id, balance, total_recharged, total_consumed, total_expired,
created_at, updated_at
) VALUES (
v_user_id, 0, 0, 0, 0,
v_now, v_now
);
-- 3. 如有赠送积分,创建批次 + 流水 + 更新余额
IF v_gift_points > 0 THEN
-- 3.1 插入积分批次
INSERT INTO mjk_point_batches (
user_id, amount, remaining, expired_at, source,
created_at, updated_at
) VALUES (
v_user_id,
v_gift_points,
v_gift_points,
v_now + (v_gift_days || ' days')::INTERVAL,
'gift',
v_now, v_now
)
RETURNING id INTO v_batch_id;
-- 3.2 插入积分流水
INSERT INTO mjk_point_transactions (
user_id, type, amount,
balance_before, balance_after,
source_type, source_id, batch_id,
duration, category, description,
created_at, updated_at
) VALUES (
v_user_id,
'recharge',
v_gift_points,
0, -- 变动前余额
v_gift_points, -- 变动后余额
'manual_gift',
v_batch_id::TEXT,
v_batch_id,
NULL,
'充值',
'新用户注册赠送积分',
v_now, v_now
);
-- 3.3 更新用户积分汇总
UPDATE mjk_user_points
SET balance = v_gift_points,
total_recharged = v_gift_points,
updated_at = v_now
WHERE user_id = v_user_id;
END IF;
RAISE NOTICE '用户创建成功,user_id = %', v_user_id;
END $$;
-- -----------------------------------------------------------
-- 二、积分赠送(给已有用户赠送积分)
-- -----------------------------------------------------------
-- 用法:修改下方变量后执行
DO $$
DECLARE
v_mobile TEXT := '18750556093'; -- ← 修改:目标用户手机号
v_gift_points INT := 5000; -- ← 修改:赠送积分数量
v_gift_days INT := 180; -- ← 修改:有效期(天)
v_reason TEXT := '运营活动赠送'; -- ← 修改:赠送原因(写入流水描述)
v_user_id UUID;
v_batch_id BIGINT;
v_balance_before INT;
v_now TIMESTAMPTZ := NOW();
BEGIN
-- 1. 查找用户
SELECT id INTO v_user_id
FROM mjk_users
WHERE mobile = v_mobile
AND status = 'active'
AND deleted_at IS NULL;
IF v_user_id IS NULL THEN
RAISE EXCEPTION '用户不存在或已注销:mobile = %', v_mobile;
END IF;
-- 2. 获取当前余额
SELECT balance INTO v_balance_before
FROM mjk_user_points
WHERE user_id = v_user_id;
IF v_balance_before IS NULL THEN
-- 如果没有积分记录,先初始化
INSERT INTO mjk_user_points (
user_id, balance, total_recharged, total_consumed, total_expired,
created_at, updated_at
) VALUES (
v_user_id, 0, 0, 0, 0,
v_now, v_now
);
v_balance_before := 0;
END IF;
-- 3. 插入积分批次
INSERT INTO mjk_point_batches (
user_id, amount, remaining, expired_at, source,
created_at, updated_at
) VALUES (
v_user_id,
v_gift_points,
v_gift_points,
v_now + (v_gift_days || ' days')::INTERVAL,
'gift',
v_now, v_now
)
RETURNING id INTO v_batch_id;
-- 4. 插入积分流水
INSERT INTO mjk_point_transactions (
user_id, type, amount,
balance_before, balance_after,
source_type, source_id, batch_id,
duration, category, description,
created_at, updated_at
) VALUES (
v_user_id,
'recharge',
v_gift_points,
v_balance_before,
v_balance_before + v_gift_points,
'manual_gift',
v_batch_id::TEXT,
v_batch_id,
NULL,
'充值',
v_reason,
v_now, v_now
);
-- 5. 更新用户积分汇总
UPDATE mjk_user_points
SET balance = balance + v_gift_points,
total_recharged = total_recharged + v_gift_points,
updated_at = v_now
WHERE user_id = v_user_id;
RAISE NOTICE '已向用户 % 赠送 % 积分,当前余额 = %',
v_mobile, v_gift_points, v_balance_before + v_gift_points;
END $$;
-- -----------------------------------------------------------
-- 三、积分补偿(给用户补偿积分,source = compensation
-- -----------------------------------------------------------
-- 用法:修改下方变量后执行
DO $$
DECLARE
v_mobile TEXT := '13800138000'; -- ← 修改:目标用户手机号
v_comp_points INT := 200; -- ← 修改:补偿积分数量
v_comp_days INT := 365; -- ← 修改:有效期(天,建议给长一点)
v_reason TEXT := '系统故障补偿'; -- ← 修改:补偿原因
v_user_id UUID;
v_batch_id BIGINT;
v_balance_before INT;
v_now TIMESTAMPTZ := NOW();
BEGIN
-- 1. 查找用户
SELECT id INTO v_user_id
FROM mjk_users
WHERE mobile = v_mobile
AND status = 'active'
AND deleted_at IS NULL;
IF v_user_id IS NULL THEN
RAISE EXCEPTION '用户不存在或已注销:mobile = %', v_mobile;
END IF;
-- 2. 获取当前余额
SELECT balance INTO v_balance_before
FROM mjk_user_points
WHERE user_id = v_user_id;
IF v_balance_before IS NULL THEN
INSERT INTO mjk_user_points (
user_id, balance, total_recharged, total_consumed, total_expired,
created_at, updated_at
) VALUES (
v_user_id, 0, 0, 0, 0,
v_now, v_now
);
v_balance_before := 0;
END IF;
-- 3. 插入积分批次(source = compensation
INSERT INTO mjk_point_batches (
user_id, amount, remaining, expired_at, source,
created_at, updated_at
) VALUES (
v_user_id,
v_comp_points,
v_comp_points,
v_now + (v_comp_days || ' days')::INTERVAL,
'compensation',
v_now, v_now
)
RETURNING id INTO v_batch_id;
-- 4. 插入积分流水
INSERT INTO mjk_point_transactions (
user_id, type, amount,
balance_before, balance_after,
source_type, source_id, batch_id,
duration, category, description,
created_at, updated_at
) VALUES (
v_user_id,
'recharge',
v_comp_points,
v_balance_before,
v_balance_before + v_comp_points,
'manual_compensation',
v_batch_id::TEXT,
v_batch_id,
NULL,
'补偿',
v_reason,
v_now, v_now
);
-- 5. 更新用户积分汇总
UPDATE mjk_user_points
SET balance = balance + v_comp_points,
total_recharged = total_recharged + v_comp_points,
updated_at = v_now
WHERE user_id = v_user_id;
RAISE NOTICE '已向用户 % 补偿 % 积分,当前余额 = %',
v_mobile, v_comp_points, v_balance_before + v_comp_points;
END $$;
-- -----------------------------------------------------------
-- 四、批量积分补偿(给多个用户同时补偿)
-- -----------------------------------------------------------
-- 用法:将要补偿的手机号填入临时表,然后执行
-- 步骤 1:创建临时补偿名单(手机号 + 补偿数量 + 原因)
-- DROP TABLE IF EXISTS _temp_compensation_list;
CREATE TEMP TABLE IF NOT EXISTS _temp_compensation_list (
mobile TEXT PRIMARY KEY,
comp_points INT NOT NULL,
reason TEXT NOT NULL DEFAULT '批量补偿'
);
-- 步骤 2:插入要补偿的用户(每次执行前清空并重新插入)
TRUNCATE _temp_compensation_list;
INSERT INTO _temp_compensation_list (mobile, comp_points, reason) VALUES
('13800138000', 100, '活动补偿'),
('13800138001', 200, '活动补偿'),
('13800138002', 100, '活动补偿');
-- 步骤 3:执行批量补偿
DO $$
DECLARE
v_rec RECORD;
v_user_id UUID;
v_batch_id BIGINT;
v_balance_before INT;
v_now TIMESTAMPTZ := NOW();
v_comp_days INT := 365;
v_success_cnt INT := 0;
v_fail_cnt INT := 0;
BEGIN
FOR v_rec IN SELECT * FROM _temp_compensation_list LOOP
BEGIN
-- 查找用户
SELECT id INTO v_user_id
FROM mjk_users
WHERE mobile = v_rec.mobile
AND status = 'active'
AND deleted_at IS NULL;
IF v_user_id IS NULL THEN
RAISE WARNING '用户不存在:%', v_rec.mobile;
v_fail_cnt := v_fail_cnt + 1;
CONTINUE;
END IF;
-- 获取当前余额
SELECT balance INTO v_balance_before
FROM mjk_user_points
WHERE user_id = v_user_id;
IF v_balance_before IS NULL THEN
INSERT INTO mjk_user_points (
user_id, balance, total_recharged, total_consumed, total_expired,
created_at, updated_at
) VALUES (
v_user_id, 0, 0, 0, 0,
v_now, v_now
);
v_balance_before := 0;
END IF;
-- 插入批次
INSERT INTO mjk_point_batches (
user_id, amount, remaining, expired_at, source,
created_at, updated_at
) VALUES (
v_user_id,
v_rec.comp_points,
v_rec.comp_points,
v_now + (v_comp_days || ' days')::INTERVAL,
'compensation',
v_now, v_now
)
RETURNING id INTO v_batch_id;
-- 插入流水
INSERT INTO mjk_point_transactions (
user_id, type, amount,
balance_before, balance_after,
source_type, source_id, batch_id,
duration, category, description,
created_at, updated_at
) VALUES (
v_user_id,
'recharge',
v_rec.comp_points,
v_balance_before,
v_balance_before + v_rec.comp_points,
'batch_compensation',
v_batch_id::TEXT,
v_batch_id,
NULL,
'补偿',
v_rec.reason,
v_now, v_now
);
-- 更新汇总
UPDATE mjk_user_points
SET balance = balance + v_rec.comp_points,
total_recharged = total_recharged + v_rec.comp_points,
updated_at = v_now
WHERE user_id = v_user_id;
v_success_cnt := v_success_cnt + 1;
EXCEPTION WHEN OTHERS THEN
RAISE WARNING '补偿失败 %: %', v_rec.mobile, SQLERRM;
v_fail_cnt := v_fail_cnt + 1;
END;
END LOOP;
RAISE NOTICE '批量补偿完成:成功 % 人,失败 % 人', v_success_cnt, v_fail_cnt;
END $$;
-- 清理临时表
-- DROP TABLE IF EXISTS _temp_compensation_list;