初始提交: Qihu-AIFlow v2.0.1 完整项目

- 前端 React+TypeScript (源码+构建产物)
- 后端 Python FastAPI
- 数据库迁移 001-015
- Docker部署配置
- 微信ClawBot API频道绑定
- 项目文档 README.md
This commit is contained in:
qyyfw committed 2026-07-02 14:40:46 +08:00
commit 78ff261b5a
199 files changed
+69126

No files matched your search

+728
View File
@@ -0,0 +1,728 @@
-- AI智能自动化PaaS平台 - 完整数据库建表脚本
-- 数据库: MySQL 8
-- 编码: utf8mb4
CREATE DATABASE IF NOT EXISTS aiflow DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE aiflow;
-- ============================================================
-- 用户与权限相关表
-- ============================================================
-- 用户表
CREATE TABLE IF NOT EXISTS users (
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) DEFAULT NULL,
phone VARCHAR(20) DEFAULT NULL,
password_hash VARCHAR(255) NOT NULL,
avatar VARCHAR(500) DEFAULT NULL,
role ENUM('user', 'admin') NOT NULL DEFAULT 'user',
status ENUM('active', 'banned') NOT NULL DEFAULT 'active',
real_name_status ENUM('unverified', 'verified') NOT NULL DEFAULT 'unverified',
real_name VARCHAR(50) DEFAULT NULL,
id_card VARCHAR(20) DEFAULT NULL,
membership_plan_id VARCHAR(36) DEFAULT NULL,
membership_level INT DEFAULT 0,
membership_expire_at DATETIME DEFAULT NULL,
auto_renew TINYINT(1) DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_users_email (email),
INDEX idx_users_phone (phone),
INDEX idx_users_role (role),
INDEX idx_users_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 登录日志表
CREATE TABLE IF NOT EXISTS login_logs (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
ip VARCHAR(45) DEFAULT NULL,
user_agent VARCHAR(500) DEFAULT NULL,
login_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_login_logs_user (user_id),
INDEX idx_login_logs_time (login_at),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- API密钥表
CREATE TABLE IF NOT EXISTS api_keys (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
api_key VARCHAR(64) NOT NULL UNIQUE,
secret VARCHAR(128) NOT NULL,
name VARCHAR(100) DEFAULT NULL,
status ENUM('active', 'revoked') NOT NULL DEFAULT 'active',
last_used_at DATETIME DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
expired_at DATETIME DEFAULT NULL,
INDEX idx_api_keys_user (user_id),
INDEX idx_api_keys_key (api_key),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- AI聊天与频道相关表
-- ============================================================
-- 对话会话表
CREATE TABLE IF NOT EXISTS conversations (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
title VARCHAR(200) NOT NULL DEFAULT '新对话',
model_id VARCHAR(36) DEFAULT NULL,
status ENUM('active', 'archived') NOT NULL DEFAULT 'active',
pinned TINYINT(1) DEFAULT 0,
knowledge_graph_count INT DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_conv_user (user_id),
INDEX idx_conv_status (status),
INDEX idx_conv_updated (updated_at),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 对话消息表
CREATE TABLE IF NOT EXISTS messages (
id VARCHAR(36) PRIMARY KEY,
conversation_id VARCHAR(36) NOT NULL,
role ENUM('user', 'assistant', 'system') NOT NULL,
content TEXT NOT NULL,
token_used INT DEFAULT 0,
model_id VARCHAR(36) DEFAULT NULL,
knowledge_ids JSON DEFAULT NULL,
agent_ids JSON DEFAULT NULL,
skill_ids JSON DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_msg_conv (conversation_id),
INDEX idx_msg_created (created_at),
FOREIGN KEY (conversation_id) REFERENCES conversations(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 频道表
CREATE TABLE IF NOT EXISTS channels (
id VARCHAR(36) PRIMARY KEY,
owner_id VARCHAR(36) NOT NULL,
name VARCHAR(100) NOT NULL,
description TEXT DEFAULT NULL,
platform ENUM('feishu', 'wechat', 'dingtalk', 'whatsapp', 'telegram', 'slack') NOT NULL,
account_name VARCHAR(100) DEFAULT NULL,
default_agent_id VARCHAR(36) DEFAULT NULL,
default_skill_id VARCHAR(36) DEFAULT NULL,
knowledge_base_id VARCHAR(36) DEFAULT NULL,
bound_model_id VARCHAR(36) DEFAULT NULL,
features JSON DEFAULT NULL,
status ENUM('connected', 'pending', 'disconnected') NOT NULL DEFAULT 'pending',
last_active DATETIME DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_ch_owner (owner_id),
INDEX idx_ch_status (status),
FOREIGN KEY (owner_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 频道成员表
CREATE TABLE IF NOT EXISTS channel_members (
id VARCHAR(36) PRIMARY KEY,
channel_id VARCHAR(36) NOT NULL,
user_id VARCHAR(36) NOT NULL,
role ENUM('owner', 'member') NOT NULL DEFAULT 'member',
joined_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_cm_channel (channel_id),
INDEX idx_cm_user (user_id),
UNIQUE KEY uk_channel_user (channel_id, user_id),
FOREIGN KEY (channel_id) REFERENCES channels(id),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 频道消息表
CREATE TABLE IF NOT EXISTS channel_messages (
id VARCHAR(36) PRIMARY KEY,
channel_id VARCHAR(36) NOT NULL,
user_id VARCHAR(36) NOT NULL,
role ENUM('user', 'assistant', 'system') NOT NULL,
content TEXT NOT NULL,
token_used INT DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_chmsg_channel (channel_id),
FOREIGN KEY (channel_id) REFERENCES channels(id),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 知识库相关表
-- ============================================================
-- 知识库表
CREATE TABLE IF NOT EXISTS knowledge_bases (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
name VARCHAR(200) NOT NULL,
description TEXT DEFAULT NULL,
directory_path VARCHAR(500) DEFAULT '/',
document_count INT DEFAULT 0,
knowledge_graph_count INT DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_kb_user (user_id),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 知识目录表
CREATE TABLE IF NOT EXISTS knowledge_directories (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
knowledge_base_id VARCHAR(36) DEFAULT NULL,
parent_id VARCHAR(36) DEFAULT NULL,
name VARCHAR(200) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_kd_user (user_id),
INDEX idx_kd_kb (knowledge_base_id),
INDEX idx_kd_parent (parent_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_bases(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 知识文档表
CREATE TABLE IF NOT EXISTS knowledge_documents (
id VARCHAR(36) PRIMARY KEY,
knowledge_base_id VARCHAR(36) NOT NULL,
directory_id VARCHAR(36) DEFAULT NULL,
filename VARCHAR(255) NOT NULL,
file_type VARCHAR(20) NOT NULL,
file_size BIGINT DEFAULT 0,
file_path VARCHAR(500) DEFAULT NULL,
status ENUM('uploading', 'processing', 'completed', 'failed') NOT NULL DEFAULT 'uploading',
chunk_count INT DEFAULT 0,
error_message TEXT DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_kdoc_kb (knowledge_base_id),
INDEX idx_kdoc_dir (directory_id),
INDEX idx_kdoc_status (status),
FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_bases(id),
FOREIGN KEY (directory_id) REFERENCES knowledge_directories(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 应用市场相关表
-- ============================================================
-- 应用市场表
CREATE TABLE IF NOT EXISTS market_apps (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(200) NOT NULL,
type ENUM('skill', 'agent', 'mcp') NOT NULL,
source ENUM('official', 'user') NOT NULL DEFAULT 'user',
publisher_id VARCHAR(36) DEFAULT NULL,
publisher_name VARCHAR(100) DEFAULT NULL,
description TEXT DEFAULT NULL,
icon VARCHAR(500) DEFAULT NULL,
tutorial TEXT DEFAULT NULL,
price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
is_member_free TINYINT(1) DEFAULT 0,
join_promotion TINYINT(1) DEFAULT 0,
status ENUM('pending', 'published', 'removed') NOT NULL DEFAULT 'pending',
rating_avg DECIMAL(3,2) DEFAULT 0.00,
review_count INT DEFAULT 0,
install_count INT DEFAULT 0,
skill_content TEXT DEFAULT NULL,
mcp_transport ENUM('streamable_http', 'sse') DEFAULT NULL,
agent_endpoint VARCHAR(500) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_ma_type (type),
INDEX idx_ma_source (source),
INDEX idx_ma_publisher (publisher_id),
INDEX idx_ma_status (status),
FOREIGN KEY (publisher_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 应用购买表
CREATE TABLE IF NOT EXISTS app_purchases (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
app_id VARCHAR(36) NOT NULL,
price DECIMAL(10,2) NOT NULL,
order_id VARCHAR(36) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_ap_user (user_id),
INDEX idx_ap_app (app_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (app_id) REFERENCES market_apps(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 应用评价表
CREATE TABLE IF NOT EXISTS app_reviews (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
app_id VARCHAR(36) NOT NULL,
rating TINYINT NOT NULL CHECK (rating >= 1 AND rating <= 5),
content TEXT DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_user_app_review (user_id, app_id),
INDEX idx_ar_app (app_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (app_id) REFERENCES market_apps(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 应用安装表
CREATE TABLE IF NOT EXISTS app_installations (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
app_id VARCHAR(36) NOT NULL,
installed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_user_app_install (user_id, app_id),
INDEX idx_ai_user (user_id),
INDEX idx_ai_app (app_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (app_id) REFERENCES market_apps(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 付费与订单相关表
-- ============================================================
-- 会员等级表
CREATE TABLE IF NOT EXISTS membership_plans (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
level INT NOT NULL DEFAULT 0,
duration_type ENUM('month', 'quarter', 'year') NOT NULL,
price DECIMAL(10,2) NOT NULL,
daily_free_tokens INT DEFAULT 0,
features JSON DEFAULT NULL,
free_app_ids JSON DEFAULT NULL,
free_model_ids JSON DEFAULT NULL,
is_active TINYINT(1) DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_mp_level (level),
INDEX idx_mp_duration (duration_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 用户订阅表
CREATE TABLE IF NOT EXISTS membership_subscriptions (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
plan_id VARCHAR(36) NOT NULL,
order_id VARCHAR(36) DEFAULT NULL,
start_at DATETIME NOT NULL,
end_at DATETIME NOT NULL,
auto_renew TINYINT(1) DEFAULT 0,
status ENUM('active', 'expired', 'downgraded') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_ms_user (user_id),
INDEX idx_ms_plan (plan_id),
INDEX idx_ms_status (status),
INDEX idx_ms_end (end_at),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (plan_id) REFERENCES membership_plans(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 订单表
CREATE TABLE IF NOT EXISTS orders (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
order_type ENUM('membership', 'service', 'app') NOT NULL,
item_id VARCHAR(36) DEFAULT NULL,
item_name VARCHAR(200) DEFAULT NULL,
amount DECIMAL(10,2) NOT NULL,
coupon_id VARCHAR(36) DEFAULT NULL,
discount_amount DECIMAL(10,2) DEFAULT 0.00,
payment_method ENUM('wechat', 'alipay') DEFAULT NULL,
payment_id VARCHAR(200) DEFAULT NULL,
status ENUM('pending', 'paid', 'refunded', 'cancelled') NOT NULL DEFAULT 'pending',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_ord_user (user_id),
INDEX idx_ord_type (order_type),
INDEX idx_ord_status (status),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 优惠券表
CREATE TABLE IF NOT EXISTS coupons (
id VARCHAR(36) PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
type ENUM('fixed', 'percent') NOT NULL,
value DECIMAL(10,2) NOT NULL,
min_amount DECIMAL(10,2) DEFAULT 0.00,
valid_from DATETIME NOT NULL,
valid_to DATETIME NOT NULL,
total_count INT DEFAULT NULL,
used_count INT DEFAULT 0,
status ENUM('active', 'expired', 'disabled') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_cp_code (code),
INDEX idx_cp_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 用户优惠券表
CREATE TABLE IF NOT EXISTS user_coupons (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
coupon_id VARCHAR(36) NOT NULL,
status ENUM('unused', 'used', 'expired') NOT NULL DEFAULT 'unused',
used_at DATETIME DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_uc_user (user_id),
INDEX idx_uc_coupon (coupon_id),
INDEX idx_uc_status (status),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (coupon_id) REFERENCES coupons(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 增值服务表
CREATE TABLE IF NOT EXISTS value_added_services (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(200) NOT NULL,
description TEXT DEFAULT NULL,
price DECIMAL(10,2) NOT NULL,
type ENUM('skill', 'agent', 'mcp', 'report', 'custom') NOT NULL,
status VARCHAR(10) NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_vas_type (type),
INDEX idx_vas_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 定制服务订单表
CREATE TABLE IF NOT EXISTS custom_service_orders (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
service_id VARCHAR(36) DEFAULT NULL,
service_type ENUM('skill', 'agent', 'mcp') NOT NULL,
description TEXT DEFAULT NULL,
status ENUM('pending', 'accepted', 'in_progress', 'completed', 'cancelled') NOT NULL DEFAULT 'pending',
price DECIMAL(10,2) DEFAULT 0.00,
order_id VARCHAR(36) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_cso_user (user_id),
INDEX idx_cso_status (status),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- Token与计费相关表
-- ============================================================
-- 模型供应商表
CREATE TABLE IF NOT EXISTS model_providers (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
protocol VARCHAR(30) NOT NULL DEFAULT 'openai_compatible',
api_key VARCHAR(255) DEFAULT NULL,
api_base_url VARCHAR(500) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 大模型表
CREATE TABLE IF NOT EXISTS models (
id VARCHAR(36) PRIMARY KEY,
provider_id VARCHAR(36) NOT NULL,
name VARCHAR(100) NOT NULL,
api_key VARCHAR(255) DEFAULT NULL,
endpoint VARCHAR(500) DEFAULT NULL,
capabilities JSON DEFAULT NULL,
timeout INT DEFAULT 60,
status ENUM('free', 'paid') NOT NULL DEFAULT 'paid',
price_per_million_tokens DECIMAL(10,4) NOT NULL DEFAULT 0.0000,
is_enabled TINYINT(1) DEFAULT 1,
total_calls BIGINT DEFAULT 0,
total_tokens BIGINT DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_m_provider (provider_id),
INDEX idx_m_enabled (is_enabled),
INDEX idx_m_status (status),
FOREIGN KEY (provider_id) REFERENCES model_providers(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Token消耗日志表(不可删除)
CREATE TABLE IF NOT EXISTS token_usage_logs (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
model_id VARCHAR(36) DEFAULT NULL,
model_name VARCHAR(100) DEFAULT NULL,
app_id VARCHAR(36) DEFAULT NULL,
app_name VARCHAR(200) DEFAULT NULL,
conversation_id VARCHAR(36) DEFAULT NULL,
prompt_tokens INT DEFAULT 0,
completion_tokens INT DEFAULT 0,
total_tokens INT DEFAULT 0,
cost DECIMAL(10,6) DEFAULT 0.000000,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_tul_user (user_id),
INDEX idx_tul_model (model_id),
INDEX idx_tul_created (created_at),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Token余额表
CREATE TABLE IF NOT EXISTS token_balances (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL UNIQUE,
total_consumed BIGINT DEFAULT 0,
balance BIGINT DEFAULT 0,
daily_free_used BIGINT DEFAULT 0,
daily_free_date DATE DEFAULT NULL,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tb_user (user_id),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 通知与日志相关表
-- ============================================================
-- 通知表
CREATE TABLE IF NOT EXISTS notifications (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
type ENUM('announcement', 'reminder', 'renewal', 'order', 'update') NOT NULL,
title VARCHAR(200) NOT NULL,
content TEXT DEFAULT NULL,
is_read TINYINT(1) DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_notif_user (user_id),
INDEX idx_notif_type (type),
INDEX idx_notif_read (is_read),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 操作日志表(不可手动删除 - 应用层禁止DELETE)
CREATE TABLE IF NOT EXISTS operation_logs (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
username VARCHAR(50) DEFAULT NULL,
action VARCHAR(100) NOT NULL,
target VARCHAR(100) DEFAULT NULL,
target_id VARCHAR(36) DEFAULT NULL,
detail TEXT DEFAULT NULL,
ip VARCHAR(45) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_ol_user (user_id),
INDEX idx_ol_action (action),
INDEX idx_ol_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 审计日志表(管理员操作 - 不可手动删除)
CREATE TABLE IF NOT EXISTS audit_logs (
id VARCHAR(36) PRIMARY KEY,
admin_id VARCHAR(36) NOT NULL,
admin_name VARCHAR(50) DEFAULT NULL,
action VARCHAR(100) NOT NULL,
target_type VARCHAR(50) DEFAULT NULL,
target_id VARCHAR(36) DEFAULT NULL,
detail TEXT DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_al_admin (admin_id),
INDEX idx_al_action (action),
INDEX idx_al_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 风控规则表
CREATE TABLE IF NOT EXISTS risk_rules (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
type ENUM('rate_limit', 'ban', 'alert') NOT NULL,
threshold INT DEFAULT 0,
duration INT DEFAULT 3600,
is_enabled TINYINT(1) DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_rr_enabled (is_enabled)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 系统配置相关表
-- ============================================================
-- 网站设置表
CREATE TABLE IF NOT EXISTS site_settings (
id VARCHAR(36) PRIMARY KEY,
`key` VARCHAR(100) NOT NULL UNIQUE,
`value` TEXT DEFAULT NULL,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 邮箱配置表
CREATE TABLE IF NOT EXISTS email_configs (
id VARCHAR(36) PRIMARY KEY,
smtp_host VARCHAR(200) NOT NULL,
smtp_port INT NOT NULL DEFAULT 587,
username VARCHAR(200) NOT NULL,
password VARCHAR(200) NOT NULL,
from_address VARCHAR(200) NOT NULL,
use_tls TINYINT(1) DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 短信配置表
CREATE TABLE IF NOT EXISTS sms_configs (
id VARCHAR(36) PRIMARY KEY,
provider VARCHAR(50) NOT NULL,
api_key VARCHAR(200) NOT NULL,
api_secret VARCHAR(200) NOT NULL,
sign_name VARCHAR(100) DEFAULT NULL,
template_code VARCHAR(100) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 支付配置表
CREATE TABLE IF NOT EXISTS payment_configs (
id VARCHAR(36) PRIMARY KEY,
type ENUM('wechat', 'alipay') NOT NULL,
app_id VARCHAR(100) NOT NULL,
merchant_id VARCHAR(100) DEFAULT NULL,
api_key VARCHAR(255) NOT NULL,
cert_path VARCHAR(500) DEFAULT NULL,
gateway_url VARCHAR(500) DEFAULT NULL,
status ENUM('active', 'inactive') NOT NULL DEFAULT 'inactive',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_pc_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 注册设置表
CREATE TABLE IF NOT EXISTS register_settings (
id VARCHAR(36) PRIMARY KEY,
phone_required TINYINT(1) DEFAULT 1,
phone_sms_required TINYINT(1) DEFAULT 1,
email_required TINYINT(1) DEFAULT 1,
email_verify_required TINYINT(1) DEFAULT 1,
real_name_required TINYINT(1) DEFAULT 0,
aliyun_access_key VARCHAR(200) DEFAULT NULL,
aliyun_secret_key VARCHAR(200) DEFAULT NULL,
aliyun_endpoint VARCHAR(200) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 广告位管理表
-- ============================================================
-- 广告轮播图表
CREATE TABLE IF NOT EXISTS ad_banners (
id VARCHAR(36) PRIMARY KEY,
title VARCHAR(200) NOT NULL,
image_url VARCHAR(500) DEFAULT NULL,
link_app_id VARCHAR(36) DEFAULT NULL,
link_app_name VARCHAR(200) DEFAULT NULL,
sort_order INT DEFAULT 0,
click_count INT DEFAULT 0,
status ENUM('active', 'inactive') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_ab_status (status),
INDEX idx_ab_order (sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 资产管理相关表
-- ============================================================
-- 资产分类表
CREATE TABLE IF NOT EXISTS asset_categories (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
type ENUM('file', 'novel', 'image', 'video', 'audio', 'custom') NOT NULL,
icon VARCHAR(200) DEFAULT NULL,
color VARCHAR(20) DEFAULT NULL,
is_default TINYINT(1) DEFAULT 0,
user_id VARCHAR(36) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_ac_type (type),
INDEX idx_ac_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 资产表
CREATE TABLE IF NOT EXISTS assets (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
name VARCHAR(200) NOT NULL,
category ENUM('file', 'novel', 'image', 'video', 'audio', 'custom') NOT NULL,
sub_category VARCHAR(50) DEFAULT NULL,
file_type VARCHAR(50) DEFAULT NULL,
size BIGINT DEFAULT 0,
description TEXT DEFAULT NULL,
cover_url VARCHAR(500) DEFAULT NULL,
url VARCHAR(500) DEFAULT NULL,
novel_meta JSON DEFAULT NULL,
status ENUM('active', 'deleted') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_ast_user (user_id),
INDEX idx_ast_category (category),
INDEX idx_ast_status (status),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 小说章节表
CREATE TABLE IF NOT EXISTS novel_chapters (
id VARCHAR(36) PRIMARY KEY,
asset_id VARCHAR(36) NOT NULL,
title VARCHAR(200) NOT NULL,
word_count INT DEFAULT 0,
sort_order INT DEFAULT 0,
content LONGTEXT DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_nc_asset (asset_id),
INDEX idx_nc_order (sort_order),
FOREIGN KEY (asset_id) REFERENCES assets(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 预留扩展表
-- ============================================================
-- 团队表(预留)
CREATE TABLE IF NOT EXISTS teams (
id VARCHAR(36) PRIMARY KEY,
owner_id VARCHAR(36) NOT NULL,
name VARCHAR(100) NOT NULL,
description TEXT DEFAULT NULL,
status ENUM('active', 'archived') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_team_owner (owner_id),
FOREIGN KEY (owner_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 分销推广表(预留)
CREATE TABLE IF NOT EXISTS referrals (
id VARCHAR(36) PRIMARY KEY,
referrer_id VARCHAR(36) NOT NULL,
referee_id VARCHAR(36) NOT NULL,
referral_code VARCHAR(50) DEFAULT NULL,
status ENUM('pending', 'active', 'cancelled') NOT NULL DEFAULT 'pending',
commission_rate DECIMAL(5,2) DEFAULT 0.00,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_ref_referrer (referrer_id),
INDEX idx_ref_referee (referee_id),
FOREIGN KEY (referrer_id) REFERENCES users(id),
FOREIGN KEY (referee_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- API开放平台表(预留)
CREATE TABLE IF NOT EXISTS open_api_clients (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
name VARCHAR(100) NOT NULL,
client_id VARCHAR(64) NOT NULL UNIQUE,
client_secret VARCHAR(128) NOT NULL,
allowed_models JSON DEFAULT NULL,
rate_limit INT DEFAULT 60,
status ENUM('active', 'suspended') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_oac_user (user_id),
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+94
View File
@@ -0,0 +1,94 @@
-- AIFlow 智能自动化PaaS平台 - 初始化数据(幂等)
USE aiflow;
-- ============================================================
-- 初始化管理员账号
-- 密码: admin123 (bcrypt hash)
-- ============================================================
INSERT IGNORE INTO users (id, username, email, password_hash, role, status, membership_level, membership_expire_at) VALUES
('admin-001', 'admin', 'admin@aiflow.com', '$2b$12$Gqf3M1WJH54pTIWxg9Mztu7W3.NSO6i.H1IITWO7/EDRS4.tqJFyC', 'admin', 'active', 3, '2099-12-31 23:59:59');
-- 幂等修正:覆盖旧数据卷中可能存在的无效密码哈希,确保 admin 密码始终为 admin123
UPDATE users SET password_hash = '$2b$12$Gqf3M1WJH54pTIWxg9Mztu7W3.NSO6i.H1IITWO7/EDRS4.tqJFyC' WHERE username = 'admin';
-- ============================================================
-- 初始化注册设置
-- ============================================================
INSERT IGNORE INTO register_settings (id, phone_required, phone_sms_required, email_required, email_verify_required, real_name_required) VALUES
('reg-default', 0, 0, 0, 0, 0);
-- ============================================================
-- 初始化网站基础设置
-- ============================================================
INSERT IGNORE INTO site_settings (id, `key`, `value`) VALUES
('d1d0c711-598a-11f1-a868-f201d42a48f4', 'logo', ''),
('d1d0c904-598a-11f1-a868-f201d42a48f4', 'site_name', 'AIFlow'),
('d1d0ca18-598a-11f1-a868-f201d42a48f4', 'announcement', '欢迎使用AIFlow智能自动化PaaS平台!'),
('d1d0cadf-598a-11f1-a868-f201d42a48f4', 'icp_number', '京ICP备2026000001号'),
('d1d0cb5c-598a-11f1-a868-f201d42a48f4', 'contact_email', 'support@aiflow.com'),
('d1d0cbf8-598a-11f1-a868-f201d42a48f4', 'contact_phone', '400-000-0000');
-- ============================================================
-- 初始化默认资产分类
-- ============================================================
INSERT IGNORE INTO asset_categories (id, name, type, icon, color, is_default) VALUES
('cat-file', '文件', 'file', 'file', '#4A90D9', 1),
('cat-novel', '小说', 'novel', 'book', '#7B68EE', 1),
('cat-image', '图片', 'image', 'image', '#50C878', 1),
('cat-video', '视频', 'video', 'video', '#FF6347', 1),
('cat-audio', '音频', 'audio', 'audio', '#FFD700', 1),
('cat-custom', '自定义', 'custom', 'folder', '#A9A9A9', 1);
-- ============================================================
-- 初始化默认风控规则
-- ============================================================
INSERT IGNORE INTO risk_rules (id, name, type, threshold, duration, is_enabled) VALUES
('risk-rate-limit', 'API调用频率限制', 'rate_limit', 60, 60, 1),
('risk-token-limit', 'Token日消耗上限', 'rate_limit', 1000000, 86400, 1),
('risk-alert', '异常调用告警', 'alert', 1000, 3600, 1);
-- ============================================================
-- 初始化模型供应商
-- ============================================================
INSERT IGNORE INTO model_providers (id, name, protocol, api_key, api_base_url) VALUES
('prov-001', 'DeepSeek', 'openai_compatible', '', 'https://api.deepseek.com'),
('prov-002', 'OpenAI', 'openai_compatible', '', 'https://api.openai.com'),
('prov-003', '通义千问', 'openai_compatible', '', 'https://dashscope.aliyuncs.com');
-- ============================================================
-- 初始化模型
-- ============================================================
INSERT IGNORE INTO models (id, provider_id, name, api_key, endpoint, capabilities, timeout, status, price_per_million_tokens, is_enabled, total_calls, total_tokens) VALUES
('model-001', 'prov-001', 'DeepSeek-V3', '', 'https://api.deepseek.com/v1/chat/completions', '["text", "thinking"]', 60, 'free', 0.0000, 1, 0, 0),
('model-002', 'prov-002', 'GPT-4o', '', 'https://api.openai.com/v1/chat/completions', '["text", "vision", "tool"]', 60, 'paid', 10.0000, 1, 0, 0),
('model-003', 'prov-003', 'Qwen-Max', '', 'https://dashscope.aliyuncs.com/compatible-mode/v1', '["text", "tool"]', 60, 'free', 0.0000, 1, 0, 0),
('model-004', 'prov-001', 'DeepSeek-R1', '', 'https://api.deepseek.com/v1/chat/completions', '["text", "thinking"]', 120, 'paid', 4.0000, 1, 0, 0),
('model-005', 'prov-003', 'Qwen-Plus', '', 'https://dashscope.aliyuncs.com/compatible-mode/v1', '["text"]', 60, 'free', 0.0000, 0, 0, 0);
-- ============================================================
-- 初始化会员套餐
-- ============================================================
INSERT IGNORE INTO membership_plans (id, name, level, duration_type, price, daily_free_tokens, features, free_app_ids, free_model_ids, is_active) VALUES
('plan-free', 'Free', 0, 'month', 0.00, 5000, '["基础AI对话", "知识库1GB", "每日5000免费Token"]', NULL, NULL, 1),
('plan-pro', 'Pro', 2, 'month', 99.00, 50000, '["高级AI对话", "知识库10GB", "每日50000免费Token", "专属模型", "会员免费应用"]', NULL, NULL, 1),
('plan-enterprise', 'Enterprise', 3, 'month', 299.00, 200000, '["无限AI对话", "知识库100GB", "每日200000免费Token", "全部专属模型", "全部会员免费应用", "API密钥管理"]', NULL, NULL, 1);
-- ============================================================
-- 初始化官方市场应用
-- ============================================================
INSERT IGNORE INTO market_apps (id, name, type, source, publisher_id, publisher_name, description, icon, tutorial, price, is_member_free, join_promotion, status, rating_avg, review_count, install_count) VALUES
('app-001', '智能客服Agent', 'agent', 'official', 'admin-001', 'AIFlow官方', '基于大模型的智能客服Agent,支持多渠道接入、意图识别、情感分析等功能', '🤖', NULL, 0.00, 1, 0, 'published', 4.50, 128, 3500),
('app-002', '数据分析工具箱', 'skill', 'official', 'admin-001', 'AIFlow官方', '一站式数据分析工具集,包含数据清洗、可视化、统计分析等功能模块', '📊', NULL, 29.90, 0, 0, 'published', 4.20, 89, 2100),
('app-003', 'MCP数据库连接器', 'mcp', 'official', 'admin-001', 'AIFlow官方', '标准MCP协议实现的数据库连接器,支持MySQL、PostgreSQL、Redis等主流数据库', '🔌', NULL, 19.90, 0, 0, 'published', 4.00, 56, 1800),
('app-004', 'SEO优化套件', 'skill', 'official', 'admin-001', 'AIFlow官方', '全面的SEO优化工具包,包含关键词分析、内容优化、排名追踪等功能', '🔍', NULL, 39.90, 0, 0, 'published', 4.30, 45, 1200),
('app-005', 'PPT生成器', 'skill', 'official', 'admin-001', 'AIFlow官方', 'AI驱动的PPT自动生成工具,输入主题即可生成精美的演示文稿', '📝', NULL, 9.90, 1, 0, 'published', 4.80, 210, 5600),
('app-legal-agent', '法律文书Agent', 'agent', 'official', 'admin-001', 'AIFlow官方', '智能法律文书生成与审查Agent,支持合同、诉状、法律意见书等多种文书类型的自动生成和合规审查。集成最新法律法规知识库,提供精准的法律文书辅助服务。', '⚖️', NULL, 0.00, 1, 0, 'published', 4.60, 32, 128);
-- ============================================================
-- 初始化广告Banner
-- ============================================================
INSERT IGNORE INTO ad_banners (id, title, image_url, link_app_id, link_app_name, sort_order, click_count, status) VALUES
('ad-001', '智能客服Agent - 零代码搭建', '', 'app-001', '智能客服Agent', 1, 0, 'active'),
('ad-002', '数据分析工具箱 - 让数据说话', '', 'app-002', '数据分析工具箱', 2, 0, 'active'),
('ad-003', 'PPT生成器 - 一键生成精美演示', '', 'app-005', 'PPT生成器', 3, 0, 'active'),
('ad-004', 'MCP数据库连接器 - 无缝对接', '', 'app-003', 'MCP数据库连接器', 4, 0, 'active');
+89
View File
@@ -0,0 +1,89 @@
-- AIFlow 增值服务改造 - 数据库迁移脚本
-- 日期: 2026-05-27
-- 说明: 增加自定义服务支持、修改 value_added_services 表类型枚举
USE aiflow;
-- 1. 创建 custom_service_requests 表(先创建新表,不依赖后续的ALTER)
CREATE TABLE IF NOT EXISTS custom_service_requests (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
service_id VARCHAR(36) NOT NULL,
request_type VARCHAR(20) NOT NULL COMMENT 'data_custom / private_project / platform_proxy',
title VARCHAR(200) NOT NULL,
description TEXT DEFAULT NULL,
requirements JSON DEFAULT NULL COMMENT '需求详情JSON',
status ENUM('pending', 'processing', 'completed', 'rejected') NOT NULL DEFAULT 'pending',
assigned_agent_id VARCHAR(36) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_csr_user (user_id),
INDEX idx_csr_service (service_id),
INDEX idx_csr_type (request_type),
INDEX idx_csr_status (status),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (service_id) REFERENCES value_added_services(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 2. 尝试修改 value_added_services 的 type 列(忽略错误 - 可能已修改过)
-- 使用存储过程实现幂等:检查当前枚举值,如果已包含新值则跳过
SET @dbname = DATABASE();
SET @tablename = 'value_added_services';
SET @columnname = 'type';
-- 检查当前type列的枚举定义是否已经包含新值
SET @needs_alter = (
SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname
AND TABLE_NAME = @tablename
AND COLUMN_NAME = @columnname
AND COLUMN_TYPE LIKE '%app_custom%') > 0,
0, 1
)
);
SET @alter_sql = IF(@needs_alter = 1,
'ALTER TABLE value_added_services MODIFY COLUMN type ENUM(''app_custom'', ''platform_proxy'', ''data_custom'', ''private_project'') NOT NULL',
'SELECT ''type column already migrated'' AS msg'
);
PREPARE stmt FROM @alter_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 3. 新增 features 字段(JSON格式)
SET @sql_features = (
SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'features') > 0,
'SELECT ''Column features already exists'' AS msg',
'ALTER TABLE value_added_services ADD COLUMN features JSON DEFAULT NULL AFTER description'
)
);
PREPARE stmt FROM @sql_features;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 4. 新增 assigned_agent_id 字段
SET @sql_agent = (
SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = 'assigned_agent_id') > 0,
'SELECT ''Column assigned_agent_id already exists'' AS msg',
'ALTER TABLE value_added_services ADD COLUMN assigned_agent_id VARCHAR(36) DEFAULT NULL AFTER status'
)
);
PREPARE stmt FROM @sql_agent;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 5. 初始化四大类增值服务数据(幂等)
INSERT IGNORE INTO value_added_services (id, name, description, features, price, type, status, assigned_agent_id) VALUES
('svc-app-custom', '应用定制服务', '根据您的业务需求,定制开发专属的AI应用。选择Skills/Agent/MCP类型,自动创建对应对话窗口,后台为您配置专属工作Agent。',
'["Skills定制", "Agent定制", "MCP定制", "专属工作Agent", "一对一服务"]', 2999.00, 'app_custom', 'active', NULL),
('svc-platform-proxy', '平台代理申请', '申请成为AIFlow平台的子平台代理,获取独立的运营空间和管理权限,拓展您的业务版图。',
'["独立子平台", "品牌定制", "用户管理", "运营数据分析", "官方技术支持"]', 0.00, 'platform_proxy', 'active', NULL),
('svc-data-custom', '数据定制服务', '提供专业的数据采集、清洗、标注和分析服务,为您的AI模型提供高质量训练数据。',
'["数据采集", "数据清洗", "数据标注", "数据分析", "定制报告"]', 0.00, 'data_custom', 'active', NULL),
('svc-private-project', '私有化项目服务', '为企业提供AIFlow平台整体私有化部署方案,包括环境搭建、数据迁移、安全配置等全方位服务。',
'["私有化部署", "数据迁移", "安全配置", "定制开发", "7x24运维支持"]', 0.00, 'private_project', 'active', NULL);
+16
View File
@@ -0,0 +1,16 @@
-- 添加 oauth_state 列到 channels 表(用于微信ClawBot扫码授权状态管理)
-- MySQL 8 不支持 ADD COLUMN IF NOT EXISTS,使用存储过程实现幂等
SET @dbname = DATABASE();
SET @tablename = 'channels';
SET @columnname = 'oauth_state';
SET @preparedStatement = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname
AND TABLE_NAME = @tablename
AND COLUMN_NAME = @columnname) > 0,
'SELECT 1',
'ALTER TABLE channels ADD COLUMN oauth_state VARCHAR(500) DEFAULT NULL'
));
PREPARE stmt FROM @preparedStatement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
+47
View File
@@ -0,0 +1,47 @@
-- AIFlow - 频道表列补充(幂等迁移)
-- 补充 001_init.sql 中 channels 表缺失的列
-- Model 中有但这些列在初始建表脚本中遗漏了
USE aiflow;
SET @dbname = DATABASE();
-- 1. webhook_url 列(Webhook回调地址)
SET @check = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'channels' AND COLUMN_NAME = 'webhook_url');
SET @sql = IF(@check = 0,
'ALTER TABLE channels ADD COLUMN webhook_url VARCHAR(500) DEFAULT NULL AFTER platform',
'SELECT ''webhook_url already exists'' AS msg');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 2. credential 列(平台凭证JSON)
SET @check = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'channels' AND COLUMN_NAME = 'credential');
SET @sql = IF(@check = 0,
'ALTER TABLE channels ADD COLUMN credential JSON DEFAULT NULL AFTER webhook_url',
'SELECT ''credential already exists'' AS msg');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 3. settings 列(频道设置JSON - AI行为配置等)
SET @check = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'channels' AND COLUMN_NAME = 'settings');
SET @sql = IF(@check = 0,
'ALTER TABLE channels ADD COLUMN settings JSON DEFAULT NULL AFTER credential',
'SELECT ''settings already exists'' AS msg');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 4. is_active 列(是否激活)
SET @check = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'channels' AND COLUMN_NAME = 'is_active');
SET @sql = IF(@check = 0,
'ALTER TABLE channels ADD COLUMN is_active TINYINT(1) DEFAULT 1 AFTER status',
'SELECT ''is_active already exists'' AS msg');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 5. oauth_state 列(OAuth扫码授权状态 - ClawBot)
SET @check = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = 'channels' AND COLUMN_NAME = 'oauth_state');
SET @sql = IF(@check = 0,
'ALTER TABLE channels ADD COLUMN oauth_state VARCHAR(500) DEFAULT NULL AFTER is_active',
'SELECT ''oauth_state already exists'' AS msg');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+34
View File
@@ -0,0 +1,34 @@
-- 006 API调用统计与慢请求日志表
-- 创建日期: 2026-05-29
-- 说明: 用于API调用统计、慢请求记录
USE aiflow;
-- API调用统计表
CREATE TABLE IF NOT EXISTS api_call_stats (
id VARCHAR(36) PRIMARY KEY,
endpoint VARCHAR(200) NOT NULL,
method VARCHAR(10) NOT NULL,
call_count BIGINT DEFAULT 0,
total_response_time DOUBLE DEFAULT 0.0,
error_count BIGINT DEFAULT 0,
last_called_at DATETIME DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_endpoint_method (endpoint, method),
INDEX idx_acs_endpoint (endpoint),
INDEX idx_acs_last_called (last_called_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 慢请求记录表
CREATE TABLE IF NOT EXISTS slow_request_logs (
id VARCHAR(36) PRIMARY KEY,
request_id VARCHAR(64) DEFAULT NULL,
method VARCHAR(10) NOT NULL,
endpoint VARCHAR(500) NOT NULL,
status_code INT DEFAULT 0,
response_time DOUBLE DEFAULT 0.0,
threshold DOUBLE DEFAULT 3.0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_srl_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+78
View File
@@ -0,0 +1,78 @@
-- AI自进化引擎 数据库表
-- Qihu-AIFlow v1.0.0
-- 用户进化配置表
CREATE TABLE IF NOT EXISTS `user_evolution_config` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL UNIQUE,
`skill_dir_path` VARCHAR(500),
`trajectory_dir_path` VARCHAR(500),
`watcher_status` VARCHAR(20) DEFAULT 'stopped',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_uec_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 用户技能表
CREATE TABLE IF NOT EXISTS `evolution_skills` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`skill_name` VARCHAR(200) NOT NULL,
`description` TEXT,
`tags` JSON,
`category` VARCHAR(100),
`state` VARCHAR(20) DEFAULT 'baby',
`use_count` INT DEFAULT 0,
`version` INT DEFAULT 1,
`skill_md_path` VARCHAR(500),
`git_commit_sha` VARCHAR(40),
`last_used_at` DATETIME,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_es_user_id` (`user_id`),
INDEX `idx_es_skill_name` (`skill_name`),
INDEX `idx_es_state` (`state`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 技能进化事件表
CREATE TABLE IF NOT EXISTS `evolution_events` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`skill_name` VARCHAR(200) NOT NULL,
`event_type` VARCHAR(50) NOT NULL,
`description` TEXT,
`version_before` INT,
`version_after` INT,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_ee_user_id` (`user_id`),
INDEX `idx_ee_event_type` (`event_type`),
INDEX `idx_ee_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 进化轨迹表
CREATE TABLE IF NOT EXISTS `evolution_trajectories` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`conversation_id` VARCHAR(36),
`file_path` VARCHAR(500),
`status` VARCHAR(20) DEFAULT 'discovered',
`atom_count` INT DEFAULT 0,
`token_used` INT DEFAULT 0,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`processed_at` DATETIME,
INDEX `idx_et_user_id` (`user_id`),
INDEX `idx_et_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 技能-轨迹关联表 (PRD 7.3.1)
CREATE TABLE IF NOT EXISTS `skill_trajectory_links` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`skill_name` VARCHAR(200) NOT NULL,
`user_id` VARCHAR(36) NOT NULL,
`trajectory_id` VARCHAR(36),
`atom_id` VARCHAR(36),
`weightscore` INT DEFAULT 0,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_stl_user_skill` (`user_id`, `skill_name`),
INDEX `idx_stl_trajectory_id` (`trajectory_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+122
View File
@@ -0,0 +1,122 @@
-- AI自进化引擎 v2 数据库变更
-- Qihu-AIFlow v2.0.0
-- 使用存储过程进行幂等的列添加,确保可重复执行
DELIMITER $$
-- ============================================================
-- 1. 现有表新增字段(幂等操作)
-- ============================================================
-- evolution_trajectories 新增字段
CREATE PROCEDURE IF NOT EXISTS add_col_evtraj()
BEGIN
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'evolution_trajectories' AND COLUMN_NAME = 'error_msg') THEN
ALTER TABLE `evolution_trajectories` ADD COLUMN `error_msg` VARCHAR(500) DEFAULT NULL COMMENT '轨迹处理失败的错误信息';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'evolution_trajectories' AND COLUMN_NAME = 'retry_count') THEN
ALTER TABLE `evolution_trajectories` ADD COLUMN `retry_count` INT DEFAULT 0 COMMENT '失败重试次数';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'evolution_trajectories' AND COLUMN_NAME = 'tasks_extracted') THEN
ALTER TABLE `evolution_trajectories` ADD COLUMN `tasks_extracted` INT DEFAULT 0 COMMENT '拆分的AtomTask数量';
END IF;
END$$
-- messages 新增字段
CREATE PROCEDURE IF NOT EXISTS add_col_msgs()
BEGIN
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'messages' AND COLUMN_NAME = 'used_skills') THEN
ALTER TABLE `messages` ADD COLUMN `used_skills` JSON DEFAULT NULL COMMENT '该轮对话调用的进化技能名列表';
END IF;
END$$
-- user_evolution_config 新增字段
CREATE PROCEDURE IF NOT EXISTS add_col_uec()
BEGIN
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_evolution_config' AND COLUMN_NAME = 'watcher_error') THEN
ALTER TABLE `user_evolution_config` ADD COLUMN `watcher_error` VARCHAR(500) DEFAULT NULL COMMENT 'watcher异常信息';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_evolution_config' AND COLUMN_NAME = 'pipeline_status') THEN
ALTER TABLE `user_evolution_config` ADD COLUMN `pipeline_status` VARCHAR(20) DEFAULT 'idle' COMMENT '流水线状态: running/idle/error';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_evolution_config' AND COLUMN_NAME = 'pipeline_processed') THEN
ALTER TABLE `user_evolution_config` ADD COLUMN `pipeline_processed` INT DEFAULT 0 COMMENT '已处理轨迹数';
END IF;
END$$
DELIMITER ;
-- 执行列添加
CALL add_col_evtraj();
CALL add_col_msgs();
CALL add_col_uec();
-- 清理存储过程
DROP PROCEDURE IF EXISTS add_col_evtraj;
DROP PROCEDURE IF EXISTS add_col_msgs;
DROP PROCEDURE IF EXISTS add_col_uec;
-- ============================================================
-- 2. 新增表: skill_versions (技能版本历史, 用于回滚)
-- ============================================================
CREATE TABLE IF NOT EXISTS `skill_versions` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`skill_name` VARCHAR(200) NOT NULL,
`version` INT NOT NULL DEFAULT 1,
`skill_md_content` LONGTEXT COMMENT '该版本的SKILL.md完整内容',
`git_commit_sha` VARCHAR(40) COMMENT 'Git提交SHA',
`description` TEXT COMMENT '版本变更说明',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_sv_user_skill` (`user_id`, `skill_name`),
INDEX `idx_sv_version` (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 3. 新增表: evolution_reports (进化报告)
-- ============================================================
CREATE TABLE IF NOT EXISTS `evolution_reports` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`report_type` VARCHAR(20) NOT NULL COMMENT 'weekly / monthly',
`period_start` DATE NOT NULL COMMENT '报告周期开始日期',
`period_end` DATE NOT NULL COMMENT '报告周期结束日期',
`report_data` JSON COMMENT '报告详细数据(JSON)',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_er_user_type` (`user_id`, `report_type`),
INDEX `idx_er_period` (`period_start`, `period_end`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 4. 新增表: skill_publish_records (技能市场发布记录)
-- ============================================================
CREATE TABLE IF NOT EXISTS `skill_publish_records` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`skill_id` VARCHAR(36) NOT NULL COMMENT '关联evolution_skills.id',
`skill_name` VARCHAR(200) NOT NULL,
`user_id` VARCHAR(36) NOT NULL,
`market_app_id` VARCHAR(36) COMMENT '关联market_apps.id',
`price` DECIMAL(10, 2) DEFAULT 0.00,
`market_description` TEXT,
`status` VARCHAR(20) NOT NULL DEFAULT 'published' COMMENT 'published/unpublished',
`published_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_spr_skill_id` (`skill_id`),
INDEX `idx_spr_user_id` (`user_id`),
INDEX `idx_spr_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 5. 新增表: team_shared_skills (团队共享技能)
-- ============================================================
CREATE TABLE IF NOT EXISTS `team_shared_skills` (
`id` VARCHAR(36) NOT NULL PRIMARY KEY,
`team_id` VARCHAR(36) NOT NULL,
`skill_id` VARCHAR(36) NOT NULL COMMENT '关联evolution_skills.id',
`skill_name` VARCHAR(200) NOT NULL,
`shared_by` VARCHAR(36) NOT NULL COMMENT '分享者user_id',
`shared_by_name` VARCHAR(100) COMMENT '分享者昵称',
`is_public` TINYINT(1) DEFAULT 1 COMMENT '团队内是否可见',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `uk_tss_team_skill` (`team_id`, `skill_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -0,0 +1,47 @@
-- Qihu-AIFlow 支付配置和实名认证配置字段扩展(幂等)
USE aiflow;
-- ============================================================
-- 支付配置:增加微信v3和支付宝完整字段
-- ============================================================
-- 存储过程:检查并添加列 api_v3_key
DROP PROCEDURE IF EXISTS add_col_if_missing_009;
DELIMITER $$
CREATE PROCEDURE add_col_if_missing_009()
BEGIN
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'payment_configs' AND COLUMN_NAME = 'api_v3_key') THEN
ALTER TABLE payment_configs ADD COLUMN api_v3_key VARCHAR(255) DEFAULT NULL COMMENT '微信APIv3密钥';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'payment_configs' AND COLUMN_NAME = 'cert_serial_no') THEN
ALTER TABLE payment_configs ADD COLUMN cert_serial_no VARCHAR(200) DEFAULT NULL COMMENT '微信证书序列号';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'payment_configs' AND COLUMN_NAME = 'alipay_public_key') THEN
ALTER TABLE payment_configs ADD COLUMN alipay_public_key TEXT DEFAULT NULL COMMENT '支付宝公钥';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'payment_configs' AND COLUMN_NAME = 'app_private_key') THEN
ALTER TABLE payment_configs ADD COLUMN app_private_key TEXT DEFAULT NULL COMMENT '支付宝应用私钥';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'payment_configs' AND COLUMN_NAME = 'notify_url') THEN
ALTER TABLE payment_configs ADD COLUMN notify_url VARCHAR(500) DEFAULT NULL COMMENT '支付回调通知地址';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'payment_configs' AND COLUMN_NAME = 'return_url') THEN
ALTER TABLE payment_configs ADD COLUMN return_url VARCHAR(500) DEFAULT NULL COMMENT '支付宝同步跳转地址';
END IF;
-- 注册设置:增加阿里云短信签名和模板字段
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'register_settings' AND COLUMN_NAME = 'sms_sign_name') THEN
ALTER TABLE register_settings ADD COLUMN sms_sign_name VARCHAR(100) DEFAULT NULL COMMENT '阿里云短信签名';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'register_settings' AND COLUMN_NAME = 'sms_template_code') THEN
ALTER TABLE register_settings ADD COLUMN sms_template_code VARCHAR(50) DEFAULT NULL COMMENT '阿里云短信模板代码';
END IF;
END$$
DELIMITER ;
CALL add_col_if_missing_009();
DROP PROCEDURE IF EXISTS add_col_if_missing_009;
-- ============================================================
-- 幂等插入支付配置初始记录
-- ============================================================
INSERT IGNORE INTO payment_configs (id, type, app_id, merchant_id, api_key, api_v3_key, cert_path, cert_serial_no, alipay_public_key, app_private_key, gateway_url, notify_url, return_url, status) VALUES
('pc1', 'wechat', '', '', '', '', '/etc/certs/apiclient_cert.pem', '', NULL, NULL, 'https://api.mch.weixin.qq.com', '', '', 'inactive'),
('pc2', 'alipay', '', NULL, '', NULL, NULL, NULL, '', '', 'https://openapi.alipay.com/gateway.do', '', '', 'inactive');
+15
View File
@@ -0,0 +1,15 @@
-- Qihu-AIFlow 全局默认模型功能(幂等)
USE aiflow;
-- 添加 is_default 列到 models 表
SET @dbname = DATABASE();
SET @tablename = 'models';
SET @columnname = 'is_default';
SET @prepared_stmt = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = @columnname) = 0,
CONCAT('ALTER TABLE ', @tablename, ' ADD COLUMN ', @columnname, ' TINYINT(1) DEFAULT 0 COMMENT ''全局默认模型'''),
CONCAT('SELECT ''Column ', @columnname, ' already exists''')
));
PREPARE stmt FROM @prepared_stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,5 @@
-- 011_knowledge_storage_and_asset.sql
-- 扩展资产表category枚举以支持知识库文档同步
-- 扩展知识库文件上传功能的数据库支持
ALTER TABLE assets MODIFY COLUMN category ENUM('file','novel','image','video','audio','custom','doc') NOT NULL;
+81
View File
@@ -0,0 +1,81 @@
-- Qihu-AIFlow 012: 幂等修复orders表遗漏列 + 确保生产环境列完整
USE aiflow;
-- ============================================================
-- 存储过程:幂等添加列
-- ============================================================
DROP PROCEDURE IF EXISTS add_col_if_missing_012;
DELIMITER $$
CREATE PROCEDURE add_col_if_missing_012()
BEGIN
-- orders 表:发票相关列(可能在生产环境缺失)
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'paid_at') THEN
ALTER TABLE orders ADD COLUMN paid_at DATETIME DEFAULT NULL COMMENT '支付时间';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'receipt_number') THEN
ALTER TABLE orders ADD COLUMN receipt_number VARCHAR(100) DEFAULT NULL COMMENT '发票凭证号码';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'receipt_type') THEN
ALTER TABLE orders ADD COLUMN receipt_type VARCHAR(20) DEFAULT NULL COMMENT '发票类型';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'receipt_title') THEN
ALTER TABLE orders ADD COLUMN receipt_title VARCHAR(200) DEFAULT NULL COMMENT '发票抬头';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'receipt_tax_number') THEN
ALTER TABLE orders ADD COLUMN receipt_tax_number VARCHAR(50) DEFAULT NULL COMMENT '发票税号';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'receipt_issued_at') THEN
ALTER TABLE orders ADD COLUMN receipt_issued_at DATETIME DEFAULT NULL COMMENT '发票开具时间';
END IF;
-- 确保 storage_overview 需要的关键表有正确结构
-- knowledge_documents 的 file_size 列
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'knowledge_documents' AND COLUMN_NAME = 'file_size') THEN
ALTER TABLE knowledge_documents ADD COLUMN file_size BIGINT DEFAULT 0 COMMENT '文件大小(字节)';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'knowledge_documents' AND COLUMN_NAME = 'file_path') THEN
ALTER TABLE knowledge_documents ADD COLUMN file_path VARCHAR(500) DEFAULT NULL COMMENT '文件存储路径';
END IF;
-- messages 表的 used_skills 列
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'messages' AND COLUMN_NAME = 'used_skills') THEN
ALTER TABLE messages ADD COLUMN used_skills JSON DEFAULT NULL COMMENT '该轮对话调用的进化技能名列表';
END IF;
-- evolution_trajectories 补充列
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'evolution_trajectories' AND COLUMN_NAME = 'error_msg') THEN
ALTER TABLE evolution_trajectories ADD COLUMN error_msg VARCHAR(500) DEFAULT NULL COMMENT '轨迹处理失败的错误信息';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'evolution_trajectories' AND COLUMN_NAME = 'retry_count') THEN
ALTER TABLE evolution_trajectories ADD COLUMN retry_count INT DEFAULT 0 COMMENT '失败重试次数';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'evolution_trajectories' AND COLUMN_NAME = 'tasks_extracted') THEN
ALTER TABLE evolution_trajectories ADD COLUMN tasks_extracted INT DEFAULT 0 COMMENT '拆分的AtomTask数量';
END IF;
-- user_evolution_config 补充列
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'user_evolution_config' AND COLUMN_NAME = 'watcher_error') THEN
ALTER TABLE user_evolution_config ADD COLUMN watcher_error VARCHAR(500) DEFAULT NULL COMMENT 'watcher异常信息';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'user_evolution_config' AND COLUMN_NAME = 'pipeline_status') THEN
ALTER TABLE user_evolution_config ADD COLUMN pipeline_status VARCHAR(20) DEFAULT 'idle' COMMENT '流水线状态';
END IF;
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'user_evolution_config' AND COLUMN_NAME = 'pipeline_processed') THEN
ALTER TABLE user_evolution_config ADD COLUMN pipeline_processed INT DEFAULT 0 COMMENT '已处理轨迹数';
END IF;
-- models 表的 is_default 列
IF NOT EXISTS (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'models' AND COLUMN_NAME = 'is_default') THEN
ALTER TABLE models ADD COLUMN is_default BOOLEAN DEFAULT FALSE COMMENT '全局默认模型';
END IF;
END$$
DELIMITER ;
CALL add_col_if_missing_012();
DROP PROCEDURE IF EXISTS add_col_if_missing_012;
-- ============================================================
-- 补初始化默认模型(如果无任何默认模型)
-- ============================================================
UPDATE models SET is_default = TRUE WHERE name = 'gpt-4o' AND is_default = FALSE
AND NOT EXISTS (SELECT 1 FROM (SELECT 1 FROM models WHERE is_default = TRUE) AS t);
+71
View File
@@ -0,0 +1,71 @@
-- Qihu-AIFlow 013: 知识图谱AI驱动表
USE aiflow;
-- ============================================================
-- 存储过程:幂等创建知识图谱相关表
-- ============================================================
DROP PROCEDURE IF EXISTS create_kg_tables_013;
DELIMITER $$
CREATE PROCEDURE create_kg_tables_013()
BEGIN
-- knowledge_graph_nodes: 图谱实体节点
IF NOT EXISTS (SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'knowledge_graph_nodes') THEN
CREATE TABLE knowledge_graph_nodes (
id VARCHAR(36) NOT NULL,
knowledge_base_id VARCHAR(36) NOT NULL,
source_doc_id VARCHAR(36) DEFAULT NULL,
label VARCHAR(500) NOT NULL,
type VARCHAR(50) NOT NULL COMMENT 'entity/attribute/concept/event',
properties JSON DEFAULT NULL,
description TEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_kgn_kb (knowledge_base_id),
INDEX idx_kgn_doc (source_doc_id),
CONSTRAINT fk_kgn_kb FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_bases(id) ON DELETE CASCADE,
CONSTRAINT fk_kgn_doc FOREIGN KEY (source_doc_id) REFERENCES knowledge_documents(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
END IF;
-- knowledge_graph_edges: 图谱关系边
IF NOT EXISTS (SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'knowledge_graph_edges') THEN
CREATE TABLE knowledge_graph_edges (
id VARCHAR(36) NOT NULL,
knowledge_base_id VARCHAR(36) NOT NULL,
source_node_id VARCHAR(36) NOT NULL,
target_node_id VARCHAR(36) NOT NULL,
relation VARCHAR(200) NOT NULL,
weight FLOAT DEFAULT 1.0,
description TEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_kge_kb (knowledge_base_id),
INDEX idx_kge_source (source_node_id),
INDEX idx_kge_target (target_node_id),
CONSTRAINT fk_kge_kb FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_bases(id) ON DELETE CASCADE,
CONSTRAINT fk_kge_source FOREIGN KEY (source_node_id) REFERENCES knowledge_graph_nodes(id) ON DELETE CASCADE,
CONSTRAINT fk_kge_target FOREIGN KEY (target_node_id) REFERENCES knowledge_graph_nodes(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
END IF;
-- knowledge_graph_build_logs: 构建记录用于增量更新
IF NOT EXISTS (SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'knowledge_graph_build_logs') THEN
CREATE TABLE knowledge_graph_build_logs (
id VARCHAR(36) NOT NULL,
knowledge_base_id VARCHAR(36) NOT NULL,
document_id VARCHAR(36) NOT NULL,
node_count INT DEFAULT 0,
edge_count INT DEFAULT 0,
status VARCHAR(20) DEFAULT 'completed',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_kgbl_kb (knowledge_base_id),
INDEX idx_kgbl_doc (document_id),
CONSTRAINT fk_kgbl_kb FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_bases(id) ON DELETE CASCADE,
CONSTRAINT fk_kgbl_doc FOREIGN KEY (document_id) REFERENCES knowledge_documents(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
END IF;
END$$
DELIMITER ;
CALL create_kg_tables_013();
DROP PROCEDURE IF EXISTS create_kg_tables_013;
+80
View File
@@ -0,0 +1,80 @@
-- ============================================================
-- 014: 清除 Mock 和测试数据,保留 admin 账号及种子数据
-- ============================================================
-- 1. 删除 test/seed 会话和消息
DELETE FROM messages;
DELETE FROM conversations;
-- 2. 删除测试资产
DELETE FROM assets;
-- 3. 删除测试知识库和文档
DELETE FROM knowledge_documents;
DELETE FROM knowledge_graph_edges;
DELETE FROM knowledge_graph_nodes;
DELETE FROM knowledge_graph_build_logs;
DELETE FROM knowledge_bases;
-- 4. 删除 token 使用日志(保留余额)
DELETE FROM token_usage_logs;
-- 5. 删除操作日志和审计日志
DELETE FROM operation_logs;
DELETE FROM audit_logs;
-- 6. 删除通知
DELETE FROM notifications;
-- 7. 删除频道数据
DELETE FROM channel_messages;
DELETE FROM channel_members;
DELETE FROM channels;
-- 8. 删除登录日志
DELETE FROM login_logs;
-- 9. 删除 API 调用统计
DELETE FROM api_call_stats;
DELETE FROM slow_request_logs;
-- 10. 删除进化相关测试数据
DELETE FROM evolution_events;
DELETE FROM evolution_trajectories;
DELETE FROM skill_trajectory_links;
DELETE FROM skill_versions;
DELETE FROM skill_publish_records;
DELETE FROM evolution_reports;
-- 11. 修复 model 引用,然后删除重复的 model_provider(保留第一个)
UPDATE models SET provider_id = '03ce94d2-a889-4d0e-a389-dd5d2176d0a0' WHERE provider_id = '23bf76d4-b3e9-4b47-a374-83f5d46741de';
DELETE FROM model_providers WHERE id = '23bf76d4-b3e9-4b47-a374-83f5d46741de';
-- 12. 删除订单和支付测试数据
DELETE FROM custom_service_orders;
DELETE FROM custom_service_requests;
DELETE FROM orders;
-- 13. 删除应用安装/购买记录(保留市场应用本身)
DELETE FROM app_installations;
DELETE FROM app_purchases;
DELETE FROM app_reviews;
-- 14. 删除优惠券使用记录
DELETE FROM user_coupons;
-- 15. 删除会员订阅测试数据
DELETE FROM membership_subscriptions;
-- 16. 删除团队和共享数据
DELETE FROM team_shared_skills;
DELETE FROM teams;
-- 17. 删除推荐数据
DELETE FROM referrals;
-- 18. 删除开放API客户端
DELETE FROM open_api_clients;
-- 19. 确认 admin 存在且状态正常
UPDATE users SET status = 'active' WHERE username = 'admin';
+11
View File
@@ -0,0 +1,11 @@
-- ============================================================
-- 015: 生产环境缺陷修复
-- ============================================================
-- 问题2修复: knowledge_documents 表添加 content 列
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'aiflow' AND TABLE_NAME = 'knowledge_documents' AND COLUMN_NAME = 'content');
SET @sql = IF(@col_exists = 0, 'ALTER TABLE knowledge_documents ADD COLUMN content LONGTEXT DEFAULT NULL AFTER error_message', 'SELECT ''content column already exists'' AS msg');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;