This commit is contained in:
2026-02-04 17:35:46 +08:00
parent 7344aaae77
commit 0ee4577b31
82 changed files with 20458 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
-- 5. 用户银行卡表
create table if not exists ml_user_bank_cards (
id uuid default gen_random_uuid() primary key,
user_id uuid not null,
bank_name varchar(100) not null, -- 银行名称
card_no_last4 varchar(4) not null, -- 卡号后4位
card_type varchar(20) default 'debit', -- 卡类型: debit(储蓄卡), credit(信用卡)
holder_name varchar(100) not null, -- 持卡人姓名
phone varchar(20), -- 预留手机号
is_default boolean default false,
created_at timestamptz default now()
);
-- 6. 用户红包/现金券表
create table if not exists ml_user_red_packets (
id uuid default gen_random_uuid() primary key,
user_id uuid not null,
amount decimal(10,2) not null, -- 金额
name varchar(100) not null, -- 红包名称
status int default 0, -- 0: 未使用, 1: 已使用, 2: 已过期
expire_at timestamptz, -- 过期时间
used_at timestamptz, -- 使用时间 (转入余额的时间)
created_at timestamptz default now()
);
comment on table ml_user_bank_cards is '用户绑定银行卡';
comment on table ml_user_red_packets is '用户红包现金券';
-- 插入测试数据
DO $$
DECLARE
target_user_id uuid := 'b653fded-7d5e-4950-aa0d-725595543e3c';
BEGIN
-- 银行卡
INSERT INTO ml_user_bank_cards (user_id, bank_name, card_no_last4, holder_name, is_default)
VALUES
(target_user_id, '招商银行', '8888', '测试用户', true),
(target_user_id, '中国建设银行', '1234', '测试用户', false);
-- 红包
INSERT INTO ml_user_red_packets (user_id, amount, name, status, expire_at)
VALUES
(target_user_id, 10.00, '新人专享红包', 0, now() + interval '7 days'),
(target_user_id, 5.00, '每日签到红包', 0, now() + interval '1 days'),
(target_user_id, 50.00, '过期大红包', 2, now() - interval '1 days');
END $$;

View File

@@ -0,0 +1,102 @@
-- 自动生成品牌关联商品数据 (每品牌12个)
-- 将此脚本在 Supabase SQL Editor 中运行
DO $$
DECLARE
v_brand RECORD;
v_merchant_id UUID;
v_category_id UUID;
v_product_id UUID;
v_i INTEGER;
v_counter INTEGER := 0;
v_img_seed TEXT;
BEGIN
-- 1. 获取一个有效的商户ID (用于作为这些商品的卖家)
-- 假设系统中至少有一个店铺
SELECT merchant_id INTO v_merchant_id FROM public.ml_shops WHERE status = 1 LIMIT 1;
-- 如果没有店铺,尝试找一个 merchant角色的用户
IF v_merchant_id IS NULL THEN
SELECT id INTO v_merchant_id FROM public.ak_users WHERE role = 'merchant' LIMIT 1;
END IF;
IF v_merchant_id IS NULL THEN
RAISE NOTICE '未找到有效的商户(merchant_id),无法生成商品数据。请先创建店铺或商户用户。';
RETURN;
END IF;
RAISE NOTICE '使用商户ID: % 进行商品生成', v_merchant_id;
-- 2. 遍历所有有效品牌
FOR v_brand IN SELECT * FROM public.ml_brands WHERE is_active = TRUE LOOP
RAISE NOTICE '正在处理品牌: %', v_brand.name;
-- 为每个品牌生成12个商品
FOR v_i IN 1..12 LOOP
-- 随机获取一个商品分类
SELECT id INTO v_category_id FROM public.ml_categories WHERE is_active = TRUE ORDER BY random() LIMIT 1;
v_img_seed := md5(random()::text);
-- 插入商品主表
INSERT INTO public.ml_products (
merchant_id,
category_id,
brand_id,
product_code,
name,
subtitle,
base_price,
market_price,
status,
total_stock,
available_stock,
main_image_url,
description,
is_new,
is_hot
) VALUES (
v_merchant_id,
v_category_id,
v_brand.id,
UPPER('BR' || substr(md5(v_brand.id::text || v_i::text || now()::text), 1, 6)), -- 生成唯一编码
v_brand.name || ' - 明星单品系列 ' || LPAD(v_i::text, 2, '0'),
'品牌官方正品 极速发货 品质保证',
(random() * 500 + 50)::decimal(10,2), -- 价格 50-550
(random() * 800 + 100)::decimal(10,2), -- 市场价
1, -- 上架状态
999,
999,
-- 使用随机图片服务
'https://picsum.photos/400/400?random=' || substr(v_img_seed, 1, 5),
'<h3>商品详情</h3><p>这是一段自动生成的' || v_brand.name || '商品描述信息。此商品采用优质原料,经过严格质检。</p>',
(random() > 0.7), -- 30%概率为新品
(random() > 0.8) -- 20%概率为热销
) RETURNING id INTO v_product_id;
-- 插入商品默认SKU (确保有库存且有价格,否则前端可能无法下单)
INSERT INTO public.ml_product_skus (
product_id,
sku_code,
price,
stock,
specifications,
status
) VALUES (
v_product_id,
UPPER('SKU' || substr(md5(v_product_id::text), 1, 6)),
(random() * 500 + 50)::decimal(10,2),
999,
'{"规格": "标准版"}',
1
);
v_counter := v_counter + 1;
END LOOP;
END LOOP;
RAISE NOTICE '完成!总共生成了 % 个商品。', v_counter;
END $$;

View File

@@ -0,0 +1,131 @@
-- 1. 创建优惠券模板数据 (Templates)
-- 修正版:适配实际表结构 ml_coupon_templates(coupon_type, discount_type, discount_value...)
DO $$
DECLARE
v_merchant_id UUID;
v_shop_id UUID;
v_product_id UUID;
v_template_shop_id UUID;
v_template_product_id UUID;
v_template_platform_id UUID;
v_user_id UUID := 'b653fded-7d5e-4950-aa0d-725595543e3c'; -- 默认测试用户ID
BEGIN
-- 获取一个商户和店铺
SELECT id, merchant_id INTO v_shop_id, v_merchant_id FROM public.ml_shops LIMIT 1;
-- 获取一个商品
SELECT id INTO v_product_id FROM public.ml_products WHERE merchant_id = v_merchant_id LIMIT 1;
-- A. 创建店铺满减券模板 (满100减10)
-- coupon_type: 1(满减), discount_type: 1(固定金额), discount_value: 10
INSERT INTO public.ml_coupon_templates (
merchant_id,
name,
coupon_type,
discount_type,
discount_value,
min_order_amount,
total_quantity,
start_time,
end_time,
status,
applicable_products
) VALUES (
v_merchant_id,
'店铺新人礼 - 满100减10',
1, -- 满减
1, -- 固定金额
10.00, -- 减10元
100.00, -- 满100
9999,
now(),
now() + interval '1 year',
1,
'[]'::jsonb
) RETURNING id INTO v_template_shop_id;
-- B. 创建商品专属折扣券模板 (无门槛9折)
-- coupon_type: 2(折扣), discount_type: 2(百分比), discount_value: 0.9 (代表9折消费端需适配逻辑)
INSERT INTO public.ml_coupon_templates (
merchant_id,
name,
coupon_type,
discount_type,
discount_value,
min_order_amount,
total_quantity,
start_time,
end_time,
status,
applicable_products
) VALUES (
v_merchant_id,
'爆品专属9折券',
2, -- 折扣
2, -- 百分比
0.90, -- 9折
0, -- 无门槛
9999,
now(),
now() + interval '1 year',
1,
jsonb_build_array(v_product_id) -- 指定商品ID
) RETURNING id INTO v_template_product_id;
-- C. 创建平台通用红包模板 (无门槛5元)
-- merchant_id: NULL, coupon_type: 1(满减/直减), discount_type: 1(固定), discount_value: 5
INSERT INTO public.ml_coupon_templates (
merchant_id,
name,
coupon_type,
discount_type,
discount_value,
min_order_amount,
total_quantity,
start_time,
end_time,
status,
applicable_products
) VALUES (
NULL,
'新人注册红包',
1,
1,
5.00,
0,
9999,
now(),
now() + interval '1 year',
1,
'[]'::jsonb
) RETURNING id INTO v_template_platform_id;
RAISE NOTICE 'Created Templates: Shop=%, Product=%, Platform=%', v_template_shop_id, v_template_product_id, v_template_platform_id;
-- 2. 为测试直接“领取”几张优惠券 (Populate User Coupons)
-- 领取店铺券 (未使用)
INSERT INTO public.ml_user_coupons (
user_id, template_id, coupon_code, status, received_at, expire_at
) VALUES (
v_user_id, v_template_shop_id, 'SH' || substring(md5(clock_timestamp()::text) from 1 for 8), 1, now(), now() + interval '7 days'
);
-- 领取红包 (未使用)
INSERT INTO public.ml_user_coupons (
user_id, template_id, coupon_code, status, received_at, expire_at
) VALUES (
v_user_id, v_template_platform_id, 'HB' || substring(md5(clock_timestamp()::text) from 1 for 8), 1, now(), now() + interval '30 days'
);
-- 领取一张已过期的券 (用于测试展示)
INSERT INTO public.ml_user_coupons (
user_id, template_id, coupon_code, status, received_at, expire_at
) VALUES (
v_user_id, v_template_shop_id, 'EX' || substring(md5(clock_timestamp()::text) from 1 for 8), 3, now() - interval '10 days', now() - interval '3 days'
);
RAISE NOTICE 'Successfully inserted test coupons for user %', v_user_id;
END $$;

View File

@@ -0,0 +1,90 @@
-- Script to seed mock orders for user test@mall.com
-- Updated to include real product names and images.
-- Run this to create NEW orders with correct data.
DO $$
DECLARE
v_user_email TEXT := 'test@mall.com';
v_user_id UUID;
v_merchant_id UUID;
v_product_id UUID;
v_sku_id UUID;
v_product_price DECIMAL;
v_product_name TEXT;
v_product_image TEXT;
v_order_id UUID;
BEGIN
-- 1. Get User
SELECT id INTO v_user_id FROM public.ak_users WHERE email = v_user_email LIMIT 1;
IF v_user_id IS NULL THEN RAISE NOTICE 'User not found'; RETURN; END IF;
-- 2. Get Merchant & Product
SELECT id, merchant_id, base_price, name, main_image_url
INTO v_product_id, v_merchant_id, v_product_price, v_product_name, v_product_image
FROM public.ml_products WHERE status = 1 LIMIT 1;
-- 3. Get SKU
SELECT id INTO v_sku_id FROM public.ml_product_skus WHERE product_id = v_product_id LIMIT 1;
-------------------------------------------------------
-- 1. Pending Payment (Status 1)
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, created_at
) VALUES (
'ORD_PENDING_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price, v_product_price + 10,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
1, 1, 1, NOW()
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount, image_url)
VALUES (v_order_id, v_product_id, v_sku_id, v_product_name, v_product_price, 1, v_product_price, v_product_image);
-------------------------------------------------------
-- 2. Pending Shipment (Status 2) - Paid
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, paid_at, created_at
) VALUES (
'ORD_SHIP_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price * 2, v_product_price * 2 + 10,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
2, 2, 1, NOW(), NOW() - INTERVAL '1 hour'
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount, image_url)
VALUES (v_order_id, v_product_id, v_sku_id, v_product_name, v_product_price, 2, v_product_price * 2, v_product_image);
-------------------------------------------------------
-- 3. Pending Receipt (Status 3) - Shipped
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, paid_at, shipped_at, created_at
) VALUES (
'ORD_RCV_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price, v_product_price + 10,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
3, 2, 2, NOW() - INTERVAL '2 days', NOW() - INTERVAL '1 day', NOW() - INTERVAL '3 days'
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount, image_url)
VALUES (v_order_id, v_product_id, v_sku_id, v_product_name, v_product_price, 1, v_product_price, v_product_image);
-------------------------------------------------------
-- 4. Completed (Status 4)
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, paid_at, shipped_at, delivered_at, completed_at, created_at
) VALUES (
'ORD_DONE_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price, v_product_price,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
4, 2, 4, NOW() - INTERVAL '10 days', NOW() - INTERVAL '9 days', NOW() - INTERVAL '8 days', NOW() - INTERVAL '8 days', NOW() - INTERVAL '11 days'
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount, image_url)
VALUES (v_order_id, v_product_id, v_sku_id, v_product_name, v_product_price, 1, v_product_price, v_product_image);
RAISE NOTICE 'Seeded orders for test user with product data.';
END $$;

View File

@@ -0,0 +1,86 @@
-- Script to seed mock orders for user test@mall.com
-- This guarantees data for: Pending Payment, Pending Shipment, Pending Receipt, Completed, Cancelled.
DO $$
DECLARE
v_user_email TEXT := 'test@mall.com';
v_user_id UUID;
v_merchant_id UUID;
v_product_id UUID;
v_sku_id UUID;
v_product_price DECIMAL;
v_order_id UUID;
BEGIN
-- 1. Get User
SELECT id INTO v_user_id FROM public.ak_users WHERE email = v_user_email LIMIT 1;
IF v_user_id IS NULL THEN RAISE NOTICE 'User not found'; RETURN; END IF;
-- 2. Get Merchant & Product
SELECT id, merchant_id, base_price INTO v_product_id, v_merchant_id, v_product_price
FROM public.ml_products WHERE status = 1 LIMIT 1;
-- 3. Get SKU
SELECT id INTO v_sku_id FROM public.ml_product_skus WHERE product_id = v_product_id LIMIT 1;
-------------------------------------------------------
-- 1. Pending Payment (Status 1)
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, created_at
) VALUES (
'ORD_PENDING_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price, v_product_price + 10,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
1, 1, 1, NOW()
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount)
VALUES (v_order_id, v_product_id, v_sku_id, 'Pending Order Product', v_product_price, 1, v_product_price);
-------------------------------------------------------
-- 2. Pending Shipment (Status 2) - Paid
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, paid_at, created_at
) VALUES (
'ORD_SHIP_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price * 2, v_product_price * 2 + 10,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
2, 2, 1, NOW(), NOW() - INTERVAL '1 hour'
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount)
VALUES (v_order_id, v_product_id, v_sku_id, 'To Ship Product', v_product_price, 2, v_product_price * 2);
-------------------------------------------------------
-- 3. Pending Receipt (Status 3) - Shipped
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, paid_at, shipped_at, created_at
) VALUES (
'ORD_RCV_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price, v_product_price + 10,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
3, 2, 2, NOW() - INTERVAL '2 days', NOW() - INTERVAL '1 day', NOW() - INTERVAL '3 days'
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount)
VALUES (v_order_id, v_product_id, v_sku_id, 'Shipped Product', v_product_price, 1, v_product_price);
-------------------------------------------------------
-- 4. Completed (Status 4)
-------------------------------------------------------
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id, product_amount, total_amount, shipping_address,
order_status, payment_status, shipping_status, paid_at, shipped_at, delivered_at, completed_at, created_at
) VALUES (
'ORD_DONE_' || substr(md5(random()::text), 1, 6), v_user_id, v_merchant_id, v_product_price, v_product_price,
'{"name": "Test User", "phone": "13800000000", "address": "Beijing China"}'::jsonb,
4, 2, 4, NOW() - INTERVAL '10 days', NOW() - INTERVAL '9 days', NOW() - INTERVAL '8 days', NOW() - INTERVAL '8 days', NOW() - INTERVAL '11 days'
) RETURNING id INTO v_order_id;
INSERT INTO public.ml_order_items (order_id, product_id, sku_id, product_name, price, quantity, total_amount)
VALUES (v_order_id, v_product_id, v_sku_id, 'Completed Product', v_product_price, 1, v_product_price);
RAISE NOTICE 'Seeded orders for test user.';
END $$;

View File

@@ -0,0 +1,143 @@
-- Script to seed mock reviews for user test@mall.com
-- This script ensures necessary dependencies (Orders, Order Items) exist before adding reviews.
DO $$
DECLARE
v_user_email TEXT := 'test@mall.com';
v_user_id UUID;
v_merchant_id UUID;
v_product_id UUID;
v_sku_id UUID;
v_order_id UUID;
v_order_item_id UUID;
v_sku_code TEXT;
BEGIN
-- 1. Get User ID from ak_users (ensure test user exists)
SELECT id INTO v_user_id FROM public.ak_users WHERE email = v_user_email LIMIT 1;
IF v_user_id IS NULL THEN
RAISE NOTICE 'User % not found. Skipping review generation.', v_user_email;
RETURN;
END IF;
-- 2. Find a valid Product and Merchant to attach reviews to
-- We select the first active product
SELECT id, merchant_id INTO v_product_id, v_merchant_id
FROM public.ml_products
WHERE status = 1
LIMIT 1;
IF v_product_id IS NULL THEN
RAISE NOTICE 'No active products found in database. Cannot create reviews.';
RETURN;
END IF;
-- Get a valid SKU for this product (optional, but good for data integrity)
SELECT id, sku_code INTO v_sku_id, v_sku_code
FROM public.ml_product_skus
WHERE product_id = v_product_id
LIMIT 1;
RAISE NOTICE 'Found User: %, Product: %, Merchant: %', v_user_id, v_product_id, v_merchant_id;
-------------------------------------------------------
-- Review 1: 5-Star Review with Images
-------------------------------------------------------
-- Create a completed order for Review 1
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id,
product_amount, total_amount,
shipping_address,
order_status, payment_status, shipping_status,
paid_at, shipped_at, delivered_at, completed_at,
created_at
) VALUES (
'MOCK_REV_' || substr(md5(random()::text), 1, 10), -- Random Order No
v_user_id,
v_merchant_id,
199.00, 199.00,
'{"name": "测试用户", "phone": "13800138000", "address": "虚拟测试地址"}'::jsonb,
4, 2, 4, -- Completed, Paid, Delivered
NOW() - INTERVAL '5 days',
NOW() - INTERVAL '4 days',
NOW() - INTERVAL '3 days',
NOW() - INTERVAL '3 days',
NOW() - INTERVAL '5 days'
) RETURNING id INTO v_order_id;
-- Create Order Item for Review 1
INSERT INTO public.ml_order_items (
order_id, product_id, sku_id,
product_name, sku_name, price, quantity, total_amount
) VALUES (
v_order_id, v_product_id, v_sku_id,
'测试商品 (Mock Product)', '默认规格', 199.00, 1, 199.00
) RETURNING id INTO v_order_item_id;
-- Insert Review 1
INSERT INTO public.ml_product_reviews (
user_id, order_id, order_item_id, product_id, merchant_id,
rating, content, images, is_anonymous, status, created_at
) VALUES (
v_user_id, v_order_id, v_order_item_id, v_product_id, v_merchant_id,
5,
'非常满意的购物体验!商品质量超乎想象,包装也很精美。发货速度快,客服态度好,下次还会再来购买!',
'["https://picsum.photos/200/200", "https://picsum.photos/200/201", "https://picsum.photos/200/202"]'::jsonb,
FALSE,
1,
NOW() - INTERVAL '2 days'
);
-------------------------------------------------------
-- Review 2: 4-Star Anonymous Review
-------------------------------------------------------
-- Create a completed order for Review 2
INSERT INTO public.ml_orders (
order_no, user_id, merchant_id,
product_amount, total_amount,
shipping_address,
order_status, payment_status, shipping_status,
paid_at, shipped_at, delivered_at, completed_at,
created_at
) VALUES (
'MOCK_REV_' || substr(md5(random()::text), 1, 10),
v_user_id,
v_merchant_id,
99.00, 99.00,
'{"name": "测试用户", "phone": "13800138000", "address": "虚拟测试地址"}'::jsonb,
4, 2, 4,
NOW() - INTERVAL '10 days',
NOW() - INTERVAL '9 days',
NOW() - INTERVAL '8 days',
NOW() - INTERVAL '8 days',
NOW() - INTERVAL '10 days'
) RETURNING id INTO v_order_id;
-- Create Order Item for Review 2
INSERT INTO public.ml_order_items (
order_id, product_id, sku_id,
product_name, sku_name, price, quantity, total_amount
) VALUES (
v_order_id, v_product_id, v_sku_id,
'测试商品 (Mock Product)', '默认规格', 99.00, 1, 99.00
) RETURNING id INTO v_order_item_id;
-- Insert Review 2
INSERT INTO public.ml_product_reviews (
user_id, order_id, order_item_id, product_id, merchant_id,
rating, content, images, is_anonymous, status, created_at
) VALUES (
v_user_id, v_order_id, v_order_item_id, v_product_id, v_merchant_id,
4,
'整体还不错,性价比很高。就是物流稍微慢了一点点,不过不影响使用。好评!',
'[]'::jsonb,
TRUE, -- Anonymous
1,
NOW() - INTERVAL '7 days'
);
RAISE NOTICE 'Successfully added 2 mock reviews for user %', v_user_email;
END $$;

View File

@@ -0,0 +1,28 @@
-- Create Refund Table
CREATE TABLE public.ml_refunds (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
refund_no VARCHAR(50) UNIQUE NOT NULL,
user_id UUID NOT NULL REFERENCES public.ak_users(id),
order_id UUID NOT NULL REFERENCES public.ml_orders(id),
refund_type INTEGER NOT NULL, -- 1: Money Only, 2: Return & Refund
refund_reason VARCHAR(200) NOT NULL,
refund_amount DECIMAL(12,2) NOT NULL,
description TEXT,
images JSONB DEFAULT '[]',
status INTEGER DEFAULT 1, -- 1: Pending, 2: Approved, 3: Rejected, 4: Completed, 5: Cancelled
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
COMMENT ON TABLE public.ml_refunds IS '售后退款申请表';
-- Add RLS Policies (Optional but good practice)
ALTER TABLE public.ml_refunds ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view their own refunds"
ON public.ml_refunds FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can insert their own refunds"
ON public.ml_refunds FOR INSERT
WITH CHECK (auth.uid() = user_id);

View File

@@ -0,0 +1,54 @@
-- Create Product Reviews Table
CREATE TABLE IF NOT EXISTS public.ml_product_reviews (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id),
product_id UUID NOT NULL REFERENCES public.ml_products(id),
order_id UUID NOT NULL REFERENCES public.ml_orders(id),
order_item_id UUID, -- Optional: link to specific line item
rating INTEGER CHECK (rating >= 1 AND rating <= 5),
content TEXT,
images JSONB DEFAULT '[]', -- Array of image URLs
is_anonymous BOOLEAN DEFAULT false,
reply TEXT, -- Merchant reply
reply_time TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create policies for product reviews
ALTER TABLE public.ml_product_reviews ENABLE ROW LEVEL SAFETY;
CREATE POLICY "Users can create reviews for their own orders"
ON public.ml_product_reviews FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can view all reviews"
ON public.ml_product_reviews FOR SELECT
TO authenticated, anon
USING (true);
-- Create Shop Reviews Table (if needed, or merge)
CREATE TABLE IF NOT EXISTS public.ml_shop_reviews (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id),
shop_id UUID NOT NULL REFERENCES public.ml_shops(id), -- Assuming ml_shops exists
order_id UUID NOT NULL REFERENCES public.ml_orders(id),
description_rating INTEGER CHECK (description_rating >= 1 AND description_rating <= 5),
logistics_rating INTEGER CHECK (logistics_rating >= 1 AND logistics_rating <= 5),
service_rating INTEGER CHECK (service_rating >= 1 AND service_rating <= 5),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create policies for shop reviews
ALTER TABLE public.ml_shop_reviews ENABLE ROW LEVEL SAFETY;
CREATE POLICY "Users can create shop reviews"
ON public.ml_shop_reviews FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Anyone can view shop reviews"
ON public.ml_shop_reviews FOR SELECT
TO authenticated, anon
USING (true);

View File

@@ -0,0 +1,40 @@
-- Fix missing product data in order items
-- Updates order items to use actual product names, images, and specifications from the product tables.
DO $$
BEGIN
-- 1. Update image_url from SKU if available
UPDATE public.ml_order_items oi
SET image_url = sku.image_url
FROM public.ml_product_skus sku
WHERE oi.sku_id = sku.id
AND (oi.image_url IS NULL OR oi.image_url = '');
-- 2. Update image_url from Product Main Image if still NULL
UPDATE public.ml_order_items oi
SET image_url = p.main_image_url
FROM public.ml_products p
WHERE oi.product_id = p.id
AND (oi.image_url IS NULL OR oi.image_url = '');
-- 3. Update product_name from Product if it looks like a placeholder
UPDATE public.ml_order_items oi
SET product_name = p.name
FROM public.ml_products p
WHERE oi.product_id = p.id
AND (
oi.product_name LIKE '%Product%'
OR oi.product_name LIKE 'Pending Order%'
OR oi.product_name = 'Test Product'
);
-- 4. Update specifications from SKU if missing
-- This ensures the frontend shows the correct spec (e.g. "Color: Red")
UPDATE public.ml_order_items oi
SET specifications = sku.specifications
FROM public.ml_product_skus sku
WHERE oi.sku_id = sku.id
AND (oi.specifications IS NULL OR oi.specifications = '{}'::jsonb);
RAISE NOTICE 'Updated order items with real product data (images, names, specs).';
END $$;

View File

@@ -0,0 +1,44 @@
-- Fix missing product data in order items
-- Updates order items to use actual product names and images from the product table
-- instead of placeholders or NULLs.
DO $$
BEGIN
-- 1. Update image_url from SKU if available
UPDATE public.ml_order_items oi
SET image_url = sku.image_url
FROM public.ml_product_skus sku
WHERE oi.sku_id = sku.id
AND (oi.image_url IS NULL OR oi.image_url = '');
-- 2. Update image_url from Product Main Image if still NULL
UPDATE public.ml_order_items oi
SET image_url = p.main_image_url
FROM public.ml_products p
WHERE oi.product_id = p.id
AND (oi.image_url IS NULL OR oi.image_url = '');
-- 3. Update product_name from Product if it looks like a placeholder
-- (checking for "Product" or similar might be too aggressive, but let's update all to ensure consistency with current product DB)
-- Actually, let's only update if it looks like the mock data we inserted "Pending Order Product", etc.
UPDATE public.ml_order_items oi
SET product_name = p.name
FROM public.ml_products p
WHERE oi.product_id = p.id
AND (
oi.product_name LIKE '%Product%'
OR oi.product_name LIKE 'Pending Order%'
OR oi.product_name = 'Test Product'
);
-- 4. Ensure we have items for all orders (Cleanup empty orders if any, or insert default item)
-- For now, let's just log if there are orders without items
-- SELECT count(*) FROM ml_orders o WHERE NOT EXISTS (SELECT 1 FROM ml_order_items oi WHERE oi.order_id = o.id);
-- Insert a default item for orders that have NO items (if any exist)
-- We need a valid product ID for this.
-- This is a bit complex in a DO block without specific IDs, so we'll skip creating new items for now
-- unless specifically requested. The main issue reported was likely "missing associated data" (images/names).
RAISE NOTICE 'Updated order items with real product data.';
END $$;

View File

@@ -0,0 +1,35 @@
-- 为指定用户插入测试数据:余额 8888.88,积分 5000
DO $$
DECLARE
-- 这里直接硬编码目标用户ID
target_user_id uuid := 'b653fded-7d5e-4950-aa0d-725595543e3c';
BEGIN
RAISE NOTICE '开始为用户 % 插入数据...', target_user_id;
-- 2. 插入或更新钱包余额 (设置余额为 8888.88)
INSERT INTO public.ml_user_wallets (user_id, balance, frozen_balance, status, currency)
VALUES (target_user_id, 8888.88, 0.00, 1, 'CNY')
ON CONFLICT (user_id)
DO UPDATE SET
balance = 8888.88,
updated_at = now();
-- 3. 插入一条钱包充值记录
INSERT INTO public.ml_wallet_transactions (user_id, amount, balance_after, type, description)
VALUES (target_user_id, 8888.88, 8888.88, 'recharge', '系统测试赠送资金');
-- 4. 插入或更新积分 (设置积分为 5000)
INSERT INTO public.ml_user_points (user_id, points, total_earned)
VALUES (target_user_id, 5000, 5000)
ON CONFLICT (user_id)
DO UPDATE SET
points = 5000,
updated_at = now();
-- 5. 插入一条积分获取记录
INSERT INTO public.ml_point_records (user_id, points, type, description)
VALUES (target_user_id, 5000, 'admin', '系统测试赠送积分');
RAISE NOTICE '测试数据插入完成。';
END $$;