V3.0: 门店分级与风险等级页面、数据填充脚本、后端API
- 新增V3.0数据库表结构(12-15)和数据填充脚本(16)
- 新增后端路由: store-grade, enterprise, product, intelligence, alert, scheduler, target
- 新增前端页面: StoreGradePage, EnterprisePage, ProductLifecyclePage, IntelligencePage, AlertManagementPage, DataImportPage, SchedulerManagementPage, TargetManagementPage
- 门店分级: 自动分级算法(达成率40%+毛利率25%+会员15%+风险20%)
- 风险等级: 基于mv_store_risk_rating模型展示风险分布和原因
- 弹窗: 雷达图+详细指标+分级原因+风险原因(primary_issue)
- FilterableTable: filterOptions支持{value,label}对象格式
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
-- ============================================================
|
||||
-- 14_v3_phase2_tables.sql
|
||||
-- Phase 2: 供应链SRM + MES + 审批流 + 消息推送 + HR + LMS + 营销 + 财务 + 扫码 + 闭环验证 + 安全
|
||||
-- ============================================================
|
||||
|
||||
-- T-201: 供应商主数据
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_supplier_master (
|
||||
id SERIAL PRIMARY KEY,
|
||||
supplier_code TEXT NOT NULL UNIQUE,
|
||||
supplier_name TEXT NOT NULL,
|
||||
category TEXT,
|
||||
grade TEXT DEFAULT '合格', -- 战略/优选/合格/淘汰
|
||||
contact_person TEXT,
|
||||
contact_phone TEXT,
|
||||
address TEXT,
|
||||
delivery_on_time_rate NUMERIC(5,2),
|
||||
quality_score NUMERIC(5,2),
|
||||
price_score NUMERIC(5,2),
|
||||
service_score NUMERIC(5,2),
|
||||
food_safety_score NUMERIC(5,2),
|
||||
overall_score NUMERIC(5,2),
|
||||
is_strategic BOOLEAN DEFAULT false,
|
||||
backup_supplier_code TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-203: 采购订单
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_purchase_order (
|
||||
id SERIAL PRIMARY KEY,
|
||||
po_number TEXT NOT NULL UNIQUE,
|
||||
supplier_code TEXT NOT NULL,
|
||||
store_code TEXT,
|
||||
order_date DATE NOT NULL,
|
||||
expected_delivery_date DATE,
|
||||
actual_delivery_date DATE,
|
||||
status TEXT DEFAULT 'draft', -- draft/submitted/approved/executed/delivered/settled
|
||||
total_amount NUMERIC(14,2),
|
||||
approval_status TEXT DEFAULT 'pending',
|
||||
created_by TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-203: 采购订单明细
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_purchase_order_item (
|
||||
id SERIAL PRIMARY KEY,
|
||||
po_id INT REFERENCES analytics.v3_purchase_order(id) ON DELETE CASCADE,
|
||||
sku_code TEXT NOT NULL,
|
||||
sku_name TEXT,
|
||||
quantity NUMERIC(12,2) NOT NULL,
|
||||
unit TEXT,
|
||||
unit_price NUMERIC(10,2),
|
||||
total_price NUMERIC(14,2),
|
||||
received_quantity NUMERIC(12,2)
|
||||
);
|
||||
|
||||
-- T-220: 审批申请
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_approval_request (
|
||||
id SERIAL PRIMARY KEY,
|
||||
request_type TEXT NOT NULL, -- salary_adjust/purchase/promotion/recipe/supplier_close/store_close
|
||||
applicant_id TEXT NOT NULL,
|
||||
applicant_name TEXT,
|
||||
store_code TEXT,
|
||||
status TEXT DEFAULT 'pending', -- pending/approved/rejected/cancelled
|
||||
current_step INT DEFAULT 1,
|
||||
total_steps INT,
|
||||
request_data JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-221: 审批步骤
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_approval_step (
|
||||
id SERIAL PRIMARY KEY,
|
||||
request_id INT REFERENCES analytics.v3_approval_request(id) ON DELETE CASCADE,
|
||||
step_order INT NOT NULL,
|
||||
approver_role TEXT NOT NULL,
|
||||
approver_id TEXT,
|
||||
approver_name TEXT,
|
||||
result TEXT, -- approved/rejected/pending
|
||||
comment TEXT,
|
||||
approved_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-222: 审批规则
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_approval_rule (
|
||||
id SERIAL PRIMARY KEY,
|
||||
request_type TEXT NOT NULL,
|
||||
step_order INT NOT NULL,
|
||||
approver_role TEXT NOT NULL,
|
||||
escalation_condition JSONB,
|
||||
escalation_role TEXT,
|
||||
is_enabled BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
UNIQUE(request_type, step_order)
|
||||
);
|
||||
|
||||
-- T-241: 站内消息
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_notification (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id TEXT,
|
||||
user_role TEXT,
|
||||
title TEXT NOT NULL,
|
||||
content TEXT,
|
||||
notification_type TEXT, -- alert/task/report/approval
|
||||
related_id INT,
|
||||
is_read BOOLEAN DEFAULT false,
|
||||
is_handled BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-260: 培训课程
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_training_course (
|
||||
id SERIAL PRIMARY KEY,
|
||||
course_name TEXT NOT NULL,
|
||||
course_type TEXT, -- SOP/技能/食安/管理
|
||||
content_url TEXT,
|
||||
exam_enabled BOOLEAN DEFAULT false,
|
||||
pass_score INT DEFAULT 60,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-261: 学习记录
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_learning_record (
|
||||
id SERIAL PRIMARY KEY,
|
||||
course_id INT REFERENCES analytics.v3_training_course(id) ON DELETE CASCADE,
|
||||
employee_name TEXT NOT NULL,
|
||||
store_code TEXT,
|
||||
progress_pct NUMERIC(5,2) DEFAULT 0,
|
||||
completion_status TEXT DEFAULT '未开始', -- 未开始/进行中/已完成/未通过
|
||||
exam_score INT,
|
||||
started_at TIMESTAMPTZ,
|
||||
completed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-270: 营销活动
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_marketing_campaign (
|
||||
id SERIAL PRIMARY KEY,
|
||||
campaign_name TEXT NOT NULL,
|
||||
campaign_type TEXT, -- 促销/拉新/召回/品牌
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE NOT NULL,
|
||||
budget NUMERIC(14,2),
|
||||
actual_spend NUMERIC(14,2),
|
||||
roi NUMERIC(8,2),
|
||||
target_stores TEXT,
|
||||
status TEXT DEFAULT 'draft', -- draft/active/completed/cancelled
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-271: 券码
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_coupon (
|
||||
id SERIAL PRIMARY KEY,
|
||||
campaign_id INT REFERENCES analytics.v3_marketing_campaign(id) ON DELETE CASCADE,
|
||||
coupon_code TEXT NOT NULL UNIQUE,
|
||||
coupon_type TEXT, -- 满减/折扣/赠品
|
||||
face_value NUMERIC(10,2),
|
||||
min_spend NUMERIC(10,2),
|
||||
status TEXT DEFAULT 'unused', -- unused/used/expired/refunded
|
||||
issued_to TEXT,
|
||||
used_at TIMESTAMPTZ,
|
||||
expiry_date DATE,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-280: 预算管理
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_budget (
|
||||
id SERIAL PRIMARY KEY,
|
||||
year INT NOT NULL,
|
||||
month DATE,
|
||||
store_code TEXT,
|
||||
department TEXT,
|
||||
budget_type TEXT, -- revenue/expense/capex
|
||||
budget_amount NUMERIC(14,2),
|
||||
actual_amount NUMERIC(14,2),
|
||||
execution_rate NUMERIC(5,2),
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-302: 审计日志
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_audit_log (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id TEXT,
|
||||
user_name TEXT,
|
||||
user_role TEXT,
|
||||
action TEXT NOT NULL, -- create/update/delete/view
|
||||
resource_type TEXT,
|
||||
resource_id TEXT,
|
||||
details JSONB,
|
||||
ip_address TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- T-295: 闭环验证
|
||||
CREATE TABLE IF NOT EXISTS analytics.v3_loop_verification (
|
||||
id SERIAL PRIMARY KEY,
|
||||
loop_name TEXT NOT NULL,
|
||||
store_code TEXT,
|
||||
check_date DATE NOT NULL,
|
||||
status TEXT DEFAULT 'open', -- open/completed/escalated
|
||||
completion_rate NUMERIC(5,2),
|
||||
cycle_days INT,
|
||||
bottleneck TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_supplier_grade ON analytics.v3_supplier_master(grade);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_po_supplier ON analytics.v3_purchase_order(supplier_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_po_status ON analytics.v3_purchase_order(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_approval_req_status ON analytics.v3_approval_request(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_approval_step_req ON analytics.v3_approval_step(request_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_notification_user ON analytics.v3_notification(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_notification_read ON analytics.v3_notification(is_read);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_training_course_type ON analytics.v3_training_course(course_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_learning_record_course ON analytics.v3_learning_record(course_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_learning_record_employee ON analytics.v3_learning_record(employee_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_campaign_status ON analytics.v3_marketing_campaign(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_coupon_code ON analytics.v3_coupon(coupon_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_budget_month ON analytics.v3_budget(year, month);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_audit_log_user ON analytics.v3_audit_log(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_audit_log_created ON analytics.v3_audit_log(created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_v3_loop_verification_date ON analytics.v3_loop_verification(check_date);
|
||||
|
||||
-- 初始化默认审批规则
|
||||
INSERT INTO analytics.v3_approval_rule (request_type, step_order, approver_role, escalation_condition, escalation_role) VALUES
|
||||
('salary_adjust', 1, 'regional', '{"amount": 5000}', 'hq'),
|
||||
('salary_adjust', 2, 'hq', NULL, NULL),
|
||||
('purchase', 1, 'regional', '{"amount": 10000}', 'hq'),
|
||||
('purchase', 2, 'hq', NULL, NULL),
|
||||
('promotion', 1, 'regional', NULL, NULL),
|
||||
('promotion', 2, 'hq', NULL, NULL),
|
||||
('recipe_change', 1, 'hq', '{"cost_change_pct": 5}', 'platform_admin'),
|
||||
('supplier_close', 1, 'hq', NULL, 'platform_admin'),
|
||||
('store_close', 1, 'hq', '{"consecutive_loss_months": 3}', 'platform_admin')
|
||||
ON CONFLICT DO NOTHING;
|
||||
Reference in New Issue
Block a user