Files
akmon/doc_mall/database/mall_fields_only_upgrade.sql
2026-01-20 08:04:15 +08:00

735 lines
32 KiB
PL/PgSQL
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.
-- =====================================================================================
-- 商城系统字段增量添加脚本 (仅字段和索引)
-- 适用于已有表结构,仅添加缺失字段和索引的场景
-- =====================================================================================
-- =====================================================================================
-- 1. 为现有 ak_users 表添加商城字段
-- =====================================================================================
DO $$
BEGIN
-- 商城状态字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'mall_status') THEN
ALTER TABLE public.ak_users ADD COLUMN mall_status INTEGER DEFAULT 1;
ALTER TABLE public.ak_users ADD CONSTRAINT chk_ak_users_mall_status CHECK (mall_status IN (1,2));
RAISE NOTICE '✓ 添加字段: ak_users.mall_status';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.mall_status';
END IF;
-- 商城用户类型字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'mall_type') THEN
ALTER TABLE public.ak_users ADD COLUMN mall_type INTEGER DEFAULT 1;
ALTER TABLE public.ak_users ADD CONSTRAINT chk_ak_users_mall_type CHECK (mall_type IN (1,2,3));
RAISE NOTICE '✓ 添加字段: ak_users.mall_type';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.mall_type';
END IF;
-- 最后登录IP字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'last_login_ip') THEN
ALTER TABLE public.ak_users ADD COLUMN last_login_ip INET;
RAISE NOTICE '✓ 添加字段: ak_users.last_login_ip';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.last_login_ip';
END IF;
-- 总订单数字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'total_orders') THEN
ALTER TABLE public.ak_users ADD COLUMN total_orders INTEGER DEFAULT 0 CHECK (total_orders >= 0);
RAISE NOTICE '✓ 添加字段: ak_users.total_orders';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.total_orders';
END IF;
-- 总消费金额字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'total_spent') THEN
ALTER TABLE public.ak_users ADD COLUMN total_spent DECIMAL(12,2) DEFAULT 0.00 CHECK (total_spent >= 0);
RAISE NOTICE '✓ 添加字段: ak_users.total_spent';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.total_spent';
END IF;
-- 用户等级字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'user_level') THEN
ALTER TABLE public.ak_users ADD COLUMN user_level INTEGER DEFAULT 1 CHECK (user_level >= 1 AND user_level <= 10);
RAISE NOTICE '✓ 添加字段: ak_users.user_level';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.user_level';
END IF;
-- 积分字段
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'points') THEN
ALTER TABLE public.ak_users ADD COLUMN points INTEGER DEFAULT 0 CHECK (points >= 0);
RAISE NOTICE '✓ 添加字段: ak_users.points';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.points';
END IF;
-- 实名认证状态
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'verified_status') THEN
ALTER TABLE public.ak_users ADD COLUMN verified_status INTEGER DEFAULT 0 CHECK (verified_status IN (0,1,2));
RAISE NOTICE '✓ 添加字段: ak_users.verified_status';
ELSE
RAISE NOTICE '○ 字段已存在: ak_users.verified_status';
END IF;
RAISE NOTICE '>> ak_users 表字段检查完成';
END $$;
-- =====================================================================================
-- 2. 为现有商城表添加CID字段SEO优化必需
-- =====================================================================================
-- 为主要商城表添加cid自增字段
DO $$
BEGIN
-- 为 ml_categories 表添加 cid 字段
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_categories') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'cid') THEN
-- 创建序列
CREATE SEQUENCE IF NOT EXISTS public.ml_categories_cid_seq;
-- 添加cid字段
ALTER TABLE public.ml_categories ADD COLUMN cid INTEGER UNIQUE DEFAULT nextval('public.ml_categories_cid_seq');
-- 设置序列所有者
ALTER SEQUENCE public.ml_categories_cid_seq OWNED BY public.ml_categories.cid;
-- 更新现有记录的cid值
UPDATE public.ml_categories SET cid = nextval('public.ml_categories_cid_seq') WHERE cid IS NULL;
RAISE NOTICE '✓ 添加字段: ml_categories.cid (自增SEO ID)';
ELSE
RAISE NOTICE '○ 字段已存在: ml_categories.cid';
END IF;
END IF;
-- 为 ml_brands 表添加 cid 字段
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_brands') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_brands' AND column_name = 'cid') THEN
CREATE SEQUENCE IF NOT EXISTS public.ml_brands_cid_seq;
ALTER TABLE public.ml_brands ADD COLUMN cid INTEGER UNIQUE DEFAULT nextval('public.ml_brands_cid_seq');
ALTER SEQUENCE public.ml_brands_cid_seq OWNED BY public.ml_brands.cid;
UPDATE public.ml_brands SET cid = nextval('public.ml_brands_cid_seq') WHERE cid IS NULL;
RAISE NOTICE '✓ 添加字段: ml_brands.cid (自增SEO ID)';
ELSE
RAISE NOTICE '○ 字段已存在: ml_brands.cid';
END IF;
END IF;
-- 为 ml_products 表添加 cid 字段
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_products') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'cid') THEN
CREATE SEQUENCE IF NOT EXISTS public.ml_products_cid_seq;
ALTER TABLE public.ml_products ADD COLUMN cid INTEGER UNIQUE DEFAULT nextval('public.ml_products_cid_seq');
ALTER SEQUENCE public.ml_products_cid_seq OWNED BY public.ml_products.cid;
UPDATE public.ml_products SET cid = nextval('public.ml_products_cid_seq') WHERE cid IS NULL;
RAISE NOTICE '✓ 添加字段: ml_products.cid (自增SEO ID)';
ELSE
RAISE NOTICE '○ 字段已存在: ml_products.cid';
END IF;
END IF;
-- 为 ml_shops 表添加 cid 字段
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_shops') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_shops' AND column_name = 'cid') THEN
CREATE SEQUENCE IF NOT EXISTS public.ml_shops_cid_seq;
ALTER TABLE public.ml_shops ADD COLUMN cid INTEGER UNIQUE DEFAULT nextval('public.ml_shops_cid_seq');
ALTER SEQUENCE public.ml_shops_cid_seq OWNED BY public.ml_shops.cid;
UPDATE public.ml_shops SET cid = nextval('public.ml_shops_cid_seq') WHERE cid IS NULL;
RAISE NOTICE '✓ 添加字段: ml_shops.cid (自增SEO ID)';
ELSE
RAISE NOTICE '○ 字段已存在: ml_shops.cid';
END IF;
END IF;
-- 为 ml_orders 表添加 cid 字段
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_orders') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_orders' AND column_name = 'cid') THEN
CREATE SEQUENCE IF NOT EXISTS public.ml_orders_cid_seq;
ALTER TABLE public.ml_orders ADD COLUMN cid INTEGER UNIQUE DEFAULT nextval('public.ml_orders_cid_seq');
ALTER SEQUENCE public.ml_orders_cid_seq OWNED BY public.ml_orders.cid;
UPDATE public.ml_orders SET cid = nextval('public.ml_orders_cid_seq') WHERE cid IS NULL;
RAISE NOTICE '✓ 添加字段: ml_orders.cid (自增SEO ID)';
ELSE
RAISE NOTICE '○ 字段已存在: ml_orders.cid';
END IF;
END IF;
RAISE NOTICE '>> CID 字段添加完成';
END $$;
-- =====================================================================================
-- 3. 为现有商城表添加其他字段(如果表存在的话)
-- =====================================================================================
-- 为 ml_products 表添加SEO和营销字段
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_products') THEN
-- SEO标题
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'seo_title') THEN
ALTER TABLE public.ml_products ADD COLUMN seo_title VARCHAR(200);
RAISE NOTICE '✓ 添加字段: ml_products.seo_title';
END IF;
-- SEO描述
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'seo_description') THEN
ALTER TABLE public.ml_products ADD COLUMN seo_description VARCHAR(500);
RAISE NOTICE '✓ 添加字段: ml_products.seo_description';
END IF;
-- SEO关键词
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'seo_keywords') THEN
ALTER TABLE public.ml_products ADD COLUMN seo_keywords TEXT[];
RAISE NOTICE '✓ 添加字段: ml_products.seo_keywords';
END IF;
-- URL slug
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'slug') THEN
ALTER TABLE public.ml_products ADD COLUMN slug VARCHAR(200) UNIQUE;
RAISE NOTICE '✓ 添加字段: ml_products.slug';
END IF;
-- 标签
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'tags') THEN
ALTER TABLE public.ml_products ADD COLUMN tags TEXT[];
RAISE NOTICE '✓ 添加字段: ml_products.tags';
END IF;
-- 是否特色商品
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'is_featured') THEN
ALTER TABLE public.ml_products ADD COLUMN is_featured BOOLEAN DEFAULT FALSE;
RAISE NOTICE '✓ 添加字段: ml_products.is_featured';
END IF;
-- 是否新品
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'is_new') THEN
ALTER TABLE public.ml_products ADD COLUMN is_new BOOLEAN DEFAULT FALSE;
RAISE NOTICE '✓ 添加字段: ml_products.is_new';
END IF;
-- 是否热销
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'is_hot') THEN
ALTER TABLE public.ml_products ADD COLUMN is_hot BOOLEAN DEFAULT FALSE;
RAISE NOTICE '✓ 添加字段: ml_products.is_hot';
END IF;
-- 浏览次数
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'view_count') THEN
ALTER TABLE public.ml_products ADD COLUMN view_count INTEGER DEFAULT 0;
RAISE NOTICE '✓ 添加字段: ml_products.view_count';
END IF;
-- 销售数量
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'sale_count') THEN
ALTER TABLE public.ml_products ADD COLUMN sale_count INTEGER DEFAULT 0;
RAISE NOTICE '✓ 添加字段: ml_products.sale_count';
END IF;
-- 收藏数量
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'favorite_count') THEN
ALTER TABLE public.ml_products ADD COLUMN favorite_count INTEGER DEFAULT 0;
RAISE NOTICE '✓ 添加字段: ml_products.favorite_count';
END IF;
RAISE NOTICE '>> ml_products 表字段检查完成';
ELSE
RAISE NOTICE '○ ml_products 表不存在,跳过字段添加';
END IF;
END $$;
-- 为 ml_categories 表添加SEO字段
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_categories') THEN
-- SEO标题
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'seo_title') THEN
ALTER TABLE public.ml_categories ADD COLUMN seo_title VARCHAR(200);
RAISE NOTICE '✓ 添加字段: ml_categories.seo_title';
END IF;
-- SEO描述
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'seo_description') THEN
ALTER TABLE public.ml_categories ADD COLUMN seo_description VARCHAR(500);
RAISE NOTICE '✓ 添加字段: ml_categories.seo_description';
END IF;
-- URL slug
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'slug') THEN
ALTER TABLE public.ml_categories ADD COLUMN slug VARCHAR(200) UNIQUE;
RAISE NOTICE '✓ 添加字段: ml_categories.slug';
END IF;
RAISE NOTICE '>> ml_categories 表字段检查完成';
ELSE
RAISE NOTICE '○ ml_categories 表不存在,跳过字段添加';
END IF;
END $$;
-- =====================================================================================
-- 4. 创建CID字段索引SEO优化必需
-- =====================================================================================
-- 为CID字段创建索引
DO $$
BEGIN
-- ml_categories cid 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'cid') THEN
CREATE INDEX IF NOT EXISTS idx_ml_categories_cid ON public.ml_categories(cid);
RAISE NOTICE '✓ 创建索引: idx_ml_categories_cid';
END IF;
-- ml_brands cid 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_brands' AND column_name = 'cid') THEN
CREATE INDEX IF NOT EXISTS idx_ml_brands_cid ON public.ml_brands(cid);
RAISE NOTICE '✓ 创建索引: idx_ml_brands_cid';
END IF;
-- ml_products cid 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'cid') THEN
CREATE INDEX IF NOT EXISTS idx_ml_products_cid ON public.ml_products(cid);
RAISE NOTICE '✓ 创建索引: idx_ml_products_cid';
END IF;
-- ml_shops cid 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_shops' AND column_name = 'cid') THEN
CREATE INDEX IF NOT EXISTS idx_ml_shops_cid ON public.ml_shops(cid);
RAISE NOTICE '✓ 创建索引: idx_ml_shops_cid';
END IF;
-- ml_orders cid 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_orders' AND column_name = 'cid') THEN
CREATE INDEX IF NOT EXISTS idx_ml_orders_cid ON public.ml_orders(cid);
RAISE NOTICE '✓ 创建索引: idx_ml_orders_cid';
END IF;
RAISE NOTICE '>> CID 索引创建完成';
END $$;
-- =====================================================================================
-- 5. 创建索引(仅在字段存在时创建)
-- =====================================================================================
-- ak_users 表索引
DO $$
BEGIN
-- 商城状态索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'mall_status') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_mall_status ON public.ak_users(mall_status);
RAISE NOTICE '✓ 创建索引: idx_ak_users_mall_status';
END IF;
-- 商城类型索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'mall_type') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_mall_type ON public.ak_users(mall_type);
RAISE NOTICE '✓ 创建索引: idx_ak_users_mall_type';
END IF;
-- 订单数量索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'total_orders') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_total_orders ON public.ak_users(total_orders DESC);
RAISE NOTICE '✓ 创建索引: idx_ak_users_total_orders';
END IF;
-- 消费金额索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'total_spent') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_total_spent ON public.ak_users(total_spent DESC);
RAISE NOTICE '✓ 创建索引: idx_ak_users_total_spent';
END IF;
-- 用户等级索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'user_level') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_level ON public.ak_users(user_level);
RAISE NOTICE '✓ 创建索引: idx_ak_users_level';
END IF;
-- 积分索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'points') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_points ON public.ak_users(points DESC);
RAISE NOTICE '✓ 创建索引: idx_ak_users_points';
END IF;
-- 认证状态索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'verified_status') THEN
CREATE INDEX IF NOT EXISTS idx_ak_users_verified ON public.ak_users(verified_status);
RAISE NOTICE '✓ 创建索引: idx_ak_users_verified';
END IF;
RAISE NOTICE '>> ak_users 表索引创建完成';
END $$;
-- ml_products 表索引
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_products') THEN
-- slug 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'slug') THEN
CREATE INDEX IF NOT EXISTS idx_ml_products_slug ON public.ml_products(slug);
RAISE NOTICE '✓ 创建索引: idx_ml_products_slug';
END IF;
-- 特色商品索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'is_featured') THEN
CREATE INDEX IF NOT EXISTS idx_ml_products_featured ON public.ml_products(is_featured, status);
RAISE NOTICE '✓ 创建索引: idx_ml_products_featured';
END IF;
-- 标签索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'tags') THEN
CREATE INDEX IF NOT EXISTS idx_ml_products_tags ON public.ml_products USING GIN(tags);
RAISE NOTICE '✓ 创建索引: idx_ml_products_tags (GIN)';
END IF;
-- 浏览量索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'view_count') THEN
CREATE INDEX IF NOT EXISTS idx_ml_products_view_count ON public.ml_products(view_count DESC);
RAISE NOTICE '✓ 创建索引: idx_ml_products_view_count';
END IF;
-- 销量索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'sale_count') THEN
CREATE INDEX IF NOT EXISTS idx_ml_products_sale_count ON public.ml_products(sale_count DESC);
RAISE NOTICE '✓ 创建索引: idx_ml_products_sale_count';
END IF;
RAISE NOTICE '>> ml_products 表索引创建完成';
ELSE
RAISE NOTICE '○ ml_products 表不存在,跳过索引创建';
END IF;
END $$;
-- ml_categories 表索引
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_categories') THEN
-- slug 索引
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'slug') THEN
CREATE INDEX IF NOT EXISTS idx_ml_categories_slug ON public.ml_categories(slug);
RAISE NOTICE '✓ 创建索引: idx_ml_categories_slug';
END IF;
RAISE NOTICE '>> ml_categories 表索引创建完成';
ELSE
RAISE NOTICE '○ ml_categories 表不存在,跳过索引创建';
END IF;
END $$;
-- =====================================================================================
-- 6. 创建或更新约束
-- =====================================================================================
DO $$
BEGIN
-- ak_users 表约束检查
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'mall_status') THEN
-- 检查约束是否存在,不存在则添加
IF NOT EXISTS (SELECT 1 FROM information_schema.check_constraints WHERE constraint_name = 'chk_ak_users_mall_status') THEN
ALTER TABLE public.ak_users ADD CONSTRAINT chk_ak_users_mall_status CHECK (mall_status IN (1,2));
RAISE NOTICE '✓ 添加约束: chk_ak_users_mall_status';
END IF;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'mall_type') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.check_constraints WHERE constraint_name = 'chk_ak_users_mall_type') THEN
ALTER TABLE public.ak_users ADD CONSTRAINT chk_ak_users_mall_type CHECK (mall_type IN (1,2,3));
RAISE NOTICE '✓ 添加约束: chk_ak_users_mall_type';
END IF;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ak_users' AND column_name = 'verified_status') THEN
IF NOT EXISTS (SELECT 1 FROM information_schema.check_constraints WHERE constraint_name = 'chk_ak_users_verified_status') THEN
ALTER TABLE public.ak_users ADD CONSTRAINT chk_ak_users_verified_status CHECK (verified_status IN (0,1,2));
RAISE NOTICE '✓ 添加约束: chk_ak_users_verified_status';
END IF;
END IF;
RAISE NOTICE '>> 约束检查完成';
END $$;
-- =====================================================================================
-- 7. 创建SEO相关函数
-- =====================================================================================
-- 根据 cid 获取商品信息 (SEO 友好)
CREATE OR REPLACE FUNCTION public.get_product_by_cid(p_cid INTEGER)
RETURNS TABLE (
id UUID,
cid INTEGER,
name VARCHAR,
slug VARCHAR,
description TEXT,
main_image_url TEXT,
base_price DECIMAL,
rating_avg DECIMAL,
sale_count INTEGER
) AS $$
BEGIN
RETURN QUERY
SELECT
p.id,
p.cid,
p.name,
p.slug,
p.description,
p.main_image_url,
p.base_price,
p.rating_avg,
p.sale_count
FROM public.ml_products p
WHERE p.cid = p_cid AND p.status = 1;
END;
$$ LANGUAGE plpgsql;
-- 根据 cid 获取分类信息 (SEO 友好)
CREATE OR REPLACE FUNCTION public.get_category_by_cid(p_cid INTEGER)
RETURNS TABLE (
id UUID,
cid INTEGER,
name VARCHAR,
slug VARCHAR,
description TEXT,
icon_url TEXT,
path TEXT[]
) AS $$
BEGIN
RETURN QUERY
SELECT
c.id,
c.cid,
c.name,
c.slug,
c.description,
c.icon_url,
c.path
FROM public.ml_categories c
WHERE c.cid = p_cid AND c.is_active = TRUE;
END;
$$ LANGUAGE plpgsql;
-- 根据 cid 获取品牌信息 (SEO 友好)
CREATE OR REPLACE FUNCTION public.get_brand_by_cid(p_cid INTEGER)
RETURNS TABLE (
id UUID,
cid INTEGER,
name VARCHAR,
logo_url TEXT,
description TEXT
) AS $$
BEGIN
RETURN QUERY
SELECT
b.id,
b.cid,
b.name,
b.logo_url,
b.description
FROM public.ml_brands b
WHERE b.cid = p_cid AND b.is_active = TRUE;
END;
$$ LANGUAGE plpgsql;
-- 根据 cid 获取店铺信息 (SEO 友好)
CREATE OR REPLACE FUNCTION public.get_shop_by_cid(p_cid INTEGER)
RETURNS TABLE (
id UUID,
cid INTEGER,
shop_name VARCHAR,
description TEXT,
shop_logo TEXT,
rating_avg DECIMAL,
product_count INTEGER
) AS $$
BEGIN
RETURN QUERY
SELECT
s.id,
s.cid,
s.shop_name,
s.description,
s.shop_logo,
s.rating_avg,
s.product_count
FROM public.ml_shops s
WHERE s.cid = p_cid AND s.status = 1;
END;
$$ LANGUAGE plpgsql;
-- 生成 SEO 友好的 URL 路径
CREATE OR REPLACE FUNCTION public.generate_seo_url(
p_type VARCHAR, -- 'product', 'category', 'brand', 'shop'
p_cid INTEGER,
p_slug VARCHAR DEFAULT NULL
)
RETURNS TEXT AS $$
DECLARE
url_path TEXT;
BEGIN
CASE p_type
WHEN 'product' THEN
url_path := '/product/' || p_cid;
IF p_slug IS NOT NULL THEN
url_path := url_path || '/' || p_slug;
END IF;
WHEN 'category' THEN
url_path := '/category/' || p_cid;
IF p_slug IS NOT NULL THEN
url_path := url_path || '/' || p_slug;
END IF;
WHEN 'brand' THEN
url_path := '/brand/' || p_cid;
IF p_slug IS NOT NULL THEN
url_path := url_path || '/' || p_slug;
END IF;
WHEN 'shop' THEN
url_path := '/shop/' || p_cid;
IF p_slug IS NOT NULL THEN
url_path := url_path || '/' || p_slug;
END IF;
ELSE
url_path := '/' || p_type || '/' || p_cid;
END CASE;
RETURN url_path;
END;
$$ LANGUAGE plpgsql;
-- 批量更新 slug 字段的函数
CREATE OR REPLACE FUNCTION public.update_seo_slugs()
RETURNS VOID AS $$
BEGIN
-- 更新商品 slug
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_products') THEN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_products' AND column_name = 'slug') THEN
UPDATE public.ml_products
SET slug = LOWER(REGEXP_REPLACE(TRIM(name), '[^a-zA-Z0-9\u4e00-\u9fa5]+', '-', 'g'))
WHERE slug IS NULL OR slug = '';
END IF;
END IF;
-- 更新分类 slug
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_categories') THEN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_categories' AND column_name = 'slug') THEN
UPDATE public.ml_categories
SET slug = LOWER(REGEXP_REPLACE(TRIM(name), '[^a-zA-Z0-9\u4e00-\u9fa5]+', '-', 'g'))
WHERE slug IS NULL OR slug = '';
END IF;
END IF;
RAISE NOTICE 'SEO slugs updated successfully';
END;
$$ LANGUAGE plpgsql;
-- =====================================================================================
-- 8. 创建基础函数(如果不存在)
-- =====================================================================================
-- 更新用户商城统计数据的函数
CREATE OR REPLACE FUNCTION public.update_user_mall_stats(p_user_id UUID)
RETURNS VOID AS $$
BEGIN
UPDATE public.ak_users
SET
total_orders = (
SELECT COUNT(*)
FROM public.ml_orders
WHERE user_id = p_user_id AND order_status = 4
),
total_spent = (
SELECT COALESCE(SUM(total_amount), 0)
FROM public.ml_orders
WHERE user_id = p_user_id AND order_status = 4
)
WHERE id = p_user_id;
END;
$$ LANGUAGE plpgsql;
-- 为用户计算等级的函数
CREATE OR REPLACE FUNCTION public.calculate_user_level(p_total_spent DECIMAL)
RETURNS INTEGER AS $$
BEGIN
CASE
WHEN p_total_spent >= 100000 THEN RETURN 10;
WHEN p_total_spent >= 50000 THEN RETURN 9;
WHEN p_total_spent >= 20000 THEN RETURN 8;
WHEN p_total_spent >= 10000 THEN RETURN 7;
WHEN p_total_spent >= 5000 THEN RETURN 6;
WHEN p_total_spent >= 2000 THEN RETURN 5;
WHEN p_total_spent >= 1000 THEN RETURN 4;
WHEN p_total_spent >= 500 THEN RETURN 3;
WHEN p_total_spent >= 100 THEN RETURN 2;
ELSE RETURN 1;
END CASE;
END;
$$ LANGUAGE plpgsql;
-- 批量更新用户等级的函数
CREATE OR REPLACE FUNCTION public.update_all_user_levels()
RETURNS INTEGER AS $$
DECLARE
affected_rows INTEGER := 0;
BEGIN
UPDATE public.ak_users
SET user_level = public.calculate_user_level(total_spent)
WHERE total_spent > 0;
GET DIAGNOSTICS affected_rows = ROW_COUNT;
RETURN affected_rows;
END;
$$ LANGUAGE plpgsql;
-- =====================================================================================
-- 9. 完成提示
-- =====================================================================================
DO $$
BEGIN
RAISE NOTICE '=======================================================';
RAISE NOTICE '商城系统字段增量添加完成!';
RAISE NOTICE '=======================================================';
RAISE NOTICE '执行内容:';
RAISE NOTICE '✓ ak_users 表增加商城相关字段';
RAISE NOTICE '✓ 商城核心表增加 cid 自增字段 (SEO优化)';
RAISE NOTICE '✓ 现有商城表增加SEO和营销字段';
RAISE NOTICE '✓ 创建相应的索引 (包括CID索引)';
RAISE NOTICE '✓ 添加约束检查';
RAISE NOTICE '✓ 创建SEO相关函数';
RAISE NOTICE '✓ 创建实用函数';
RAISE NOTICE '=======================================================';
RAISE NOTICE '新增字段说明:';
RAISE NOTICE '• ak_users.mall_status: 商城状态 (1:正常 2:禁用)';
RAISE NOTICE '• ak_users.mall_type: 用户类型 (1:消费者 2:商家 3:其他)';
RAISE NOTICE '• ak_users.total_orders: 总订单数';
RAISE NOTICE '• ak_users.total_spent: 总消费金额';
RAISE NOTICE '• ak_users.user_level: 用户等级 (1-10)';
RAISE NOTICE '• ak_users.points: 用户积分';
RAISE NOTICE '• ak_users.verified_status: 认证状态 (0:未认证 1:已认证 2:认证失败)';
RAISE NOTICE '-------------------------------------------------------';
RAISE NOTICE 'CID 字段说明 (SEO优化):';
RAISE NOTICE '• ml_categories.cid: 分类SEO友好ID';
RAISE NOTICE '• ml_brands.cid: 品牌SEO友好ID';
RAISE NOTICE '• ml_products.cid: 商品SEO友好ID';
RAISE NOTICE '• ml_shops.cid: 店铺SEO友好ID';
RAISE NOTICE '• ml_orders.cid: 订单SEO友好ID';
RAISE NOTICE '-------------------------------------------------------';
RAISE NOTICE 'SEO 函数说明:';
RAISE NOTICE '• get_product_by_cid(cid): 根据CID获取商品信息';
RAISE NOTICE '• get_category_by_cid(cid): 根据CID获取分类信息';
RAISE NOTICE '• get_brand_by_cid(cid): 根据CID获取品牌信息';
RAISE NOTICE '• get_shop_by_cid(cid): 根据CID获取店铺信息';
RAISE NOTICE '• generate_seo_url(type, cid, slug): 生成SEO友好URL';
RAISE NOTICE '• update_seo_slugs(): 批量更新slug字段';
RAISE NOTICE '=======================================================';
RAISE NOTICE '使用建议:';
RAISE NOTICE '1. 此脚本可安全重复执行';
RAISE NOTICE '2. 使用 IF NOT EXISTS 检查避免重复操作';
RAISE NOTICE '3. 建议在测试环境先执行验证';
RAISE NOTICE '4. 可根据实际需要注释掉不需要的字段';
RAISE NOTICE '5. 执行后可调用 update_seo_slugs() 初始化slug字段';
RAISE NOTICE '=======================================================';
RAISE NOTICE 'SEO URL 示例:';
RAISE NOTICE '• 商品页面: /product/123/iphone-15-pro';
RAISE NOTICE '• 分类页面: /category/45/digital-electronics';
RAISE NOTICE '• 品牌页面: /brand/12/apple';
RAISE NOTICE '• 店铺页面: /shop/88/official-store';
RAISE NOTICE '=======================================================';
END $$;