database_init.sql 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. -- =============================================
  2. -- 四川路桥 Maas 算力平台 - 数据库初始化脚本
  3. -- PostgreSQL 15+
  4. -- =============================================
  5. -- 创建 schema
  6. CREATE SCHEMA IF NOT EXISTS aigcspace;
  7. -- =============================================
  8. -- 1. 用户表
  9. -- =============================================
  10. CREATE TABLE aigcspace.users (
  11. id VARCHAR(50) NOT NULL PRIMARY KEY,
  12. username VARCHAR(50) UNIQUE,
  13. password_hash VARCHAR(255),
  14. nickname VARCHAR(100) NOT NULL,
  15. phone VARCHAR(20),
  16. email VARCHAR(255),
  17. avatar TEXT,
  18. real_name VARCHAR(100),
  19. id_card VARCHAR(18),
  20. is_verified VARCHAR(20) NOT NULL DEFAULT 'unverified',
  21. verified_at TIMESTAMP WITHOUT TIME ZONE,
  22. apikey VARCHAR(255),
  23. registration_date DATE,
  24. status VARCHAR(20) NOT NULL DEFAULT 'active',
  25. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
  26. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
  27. );
  28. CREATE INDEX idx_users_username ON aigcspace.users(username);
  29. CREATE INDEX idx_users_phone ON aigcspace.users(phone);
  30. CREATE INDEX idx_users_email ON aigcspace.users(email);
  31. CREATE INDEX idx_users_status ON aigcspace.users(status);
  32. -- =============================================
  33. -- 2. 管理员表
  34. -- =============================================
  35. CREATE TABLE aigcspace.admin_users (
  36. id SERIAL NOT NULL PRIMARY KEY,
  37. username VARCHAR(50) NOT NULL UNIQUE,
  38. password_hash VARCHAR(255) NOT NULL,
  39. nickname VARCHAR(100),
  40. status VARCHAR(20) NOT NULL DEFAULT 'active',
  41. last_login_at TIMESTAMP WITHOUT TIME ZONE,
  42. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
  43. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  44. );
  45. CREATE TABLE aigcspace.admin_login_attempt (
  46. id SERIAL NOT NULL PRIMARY KEY,
  47. username VARCHAR(50) NOT NULL,
  48. success BOOLEAN NOT NULL,
  49. ip_address VARCHAR(50),
  50. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  51. );
  52. CREATE TABLE aigcspace.operation_log (
  53. id BIGSERIAL NOT NULL PRIMARY KEY,
  54. admin_id INTEGER NOT NULL REFERENCES aigcspace.admin_users(id),
  55. operation_type VARCHAR(50) NOT NULL,
  56. module VARCHAR(50) NOT NULL,
  57. target_id VARCHAR(100),
  58. detail JSON,
  59. ip_address VARCHAR(50),
  60. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  61. );
  62. CREATE INDEX idx_operation_log_admin_id ON aigcspace.operation_log(admin_id);
  63. CREATE INDEX idx_operation_log_created_at ON aigcspace.operation_log(created_at);
  64. -- =============================================
  65. -- 3. 模型表
  66. -- =============================================
  67. CREATE TABLE aigcspace.models_new (
  68. id SERIAL NOT NULL PRIMARY KEY,
  69. model_code VARCHAR(200) NOT NULL UNIQUE,
  70. description TEXT,
  71. display_tags TEXT[],
  72. input_modalities TEXT[],
  73. output_modalities TEXT[],
  74. features JSONB,
  75. rate_limits JSONB,
  76. tool_call_prices JSONB,
  77. raw_prices JSONB,
  78. source_url TEXT,
  79. crawled_at TIMESTAMP WITHOUT TIME ZONE,
  80. categories INTEGER[] NOT NULL DEFAULT '{0}',
  81. display_name VARCHAR(255),
  82. img TEXT,
  83. supplier VARCHAR(100) NOT NULL DEFAULT '',
  84. tag1 VARCHAR(100),
  85. tag2 VARCHAR(100),
  86. keywords TEXT,
  87. custom_description TEXT,
  88. is_featured BOOLEAN NOT NULL DEFAULT false,
  89. is_show_enabled BOOLEAN NOT NULL DEFAULT true,
  90. is_api_enabled BOOLEAN NOT NULL DEFAULT false,
  91. is_search BOOLEAN NOT NULL DEFAULT false,
  92. is_thinking BOOLEAN NOT NULL DEFAULT false,
  93. source_keys TEXT[],
  94. normalized_keys TEXT[],
  95. group_name VARCHAR(100),
  96. encrypted_api_key TEXT,
  97. -- 本地模型字段
  98. is_local BOOLEAN NOT NULL DEFAULT false,
  99. user_id VARCHAR(50) REFERENCES aigcspace.users(id),
  100. base_url VARCHAR(500),
  101. local_api_key VARCHAR(500),
  102. visibility VARCHAR(20) DEFAULT 'user',
  103. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
  104. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
  105. );
  106. CREATE INDEX idx_models_new_categories ON aigcspace.models_new USING GIN(categories);
  107. CREATE INDEX idx_models_new_supplier ON aigcspace.models_new(supplier);
  108. CREATE INDEX idx_models_new_is_local ON aigcspace.models_new(is_local);
  109. CREATE INDEX idx_models_new_user_id ON aigcspace.models_new(user_id);
  110. CREATE INDEX idx_models_new_is_show_enabled ON aigcspace.models_new(is_show_enabled);
  111. CREATE INDEX idx_models_new_is_api_enabled ON aigcspace.models_new(is_api_enabled);
  112. CREATE TABLE aigcspace.model_price_new (
  113. id SERIAL NOT NULL PRIMARY KEY,
  114. model_code VARCHAR(200) NOT NULL,
  115. label VARCHAR(200) NOT NULL DEFAULT 'default',
  116. tier_min NUMERIC(20, 2),
  117. tier_max NUMERIC(20, 2),
  118. tier_unit VARCHAR(50),
  119. input_price_original NUMERIC(20, 8) NOT NULL DEFAULT 0,
  120. output_price_original NUMERIC(20, 8) NOT NULL DEFAULT 0,
  121. discount_rate NUMERIC(5, 4) NOT NULL DEFAULT 1.0,
  122. discount_label VARCHAR(20),
  123. input_price_discounted NUMERIC(20, 8) NOT NULL DEFAULT 0,
  124. output_price_discounted NUMERIC(20, 8) NOT NULL DEFAULT 0,
  125. currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
  126. unit VARCHAR(100) NOT NULL DEFAULT '千tokens',
  127. display_multiplier INTEGER NOT NULL DEFAULT 1,
  128. source_url TEXT,
  129. crawled_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(),
  130. is_active BOOLEAN NOT NULL DEFAULT true,
  131. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
  132. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
  133. );
  134. CREATE INDEX idx_model_price_new_model_code ON aigcspace.model_price_new(model_code);
  135. CREATE TABLE aigcspace.model_category (
  136. id SERIAL NOT NULL PRIMARY KEY,
  137. code INTEGER NOT NULL UNIQUE,
  138. name VARCHAR(50) NOT NULL,
  139. description VARCHAR(200),
  140. sort_order INTEGER NOT NULL DEFAULT 0,
  141. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
  142. );
  143. -- 初始化模型分类
  144. INSERT INTO aigcspace.model_category (code, name, sort_order) VALUES
  145. (0, '语言模型', 0),
  146. (1, '多模态', 1),
  147. (2, 'TTS', 2),
  148. (3, 'STT', 3),
  149. (4, '文生图', 4),
  150. (5, '生视频', 5),
  151. (6, '图生图', 6),
  152. (7, 'Embedding', 7),
  153. (8, 'Rerank', 8);
  154. -- =============================================
  155. -- 4. API 密钥表
  156. -- =============================================
  157. CREATE TABLE aigcspace.platform_api_key (
  158. id SERIAL NOT NULL PRIMARY KEY,
  159. user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE,
  160. api_key VARCHAR(100) NOT NULL,
  161. api_key_prefix VARCHAR(20) NOT NULL,
  162. name VARCHAR(100),
  163. status VARCHAR(20) NOT NULL DEFAULT 'active',
  164. key_type VARCHAR(20) NOT NULL DEFAULT 'public',
  165. last_used_at TIMESTAMP WITHOUT TIME ZONE,
  166. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
  167. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
  168. );
  169. CREATE INDEX idx_platform_api_key_user_id ON aigcspace.platform_api_key(user_id);
  170. CREATE INDEX idx_platform_api_key_api_key ON aigcspace.platform_api_key(api_key);
  171. CREATE INDEX idx_platform_api_key_status ON aigcspace.platform_api_key(status);
  172. CREATE INDEX idx_platform_api_key_key_type ON aigcspace.platform_api_key(key_type);
  173. -- =============================================
  174. -- 5. API 调用日志表
  175. -- =============================================
  176. CREATE TABLE aigcspace.api_call_log (
  177. id BIGSERIAL NOT NULL PRIMARY KEY,
  178. user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE,
  179. api_key_id INTEGER REFERENCES aigcspace.platform_api_key(id) ON DELETE SET NULL,
  180. model_id INTEGER,
  181. model_name VARCHAR(255) NOT NULL,
  182. is_local BOOLEAN NOT NULL DEFAULT false,
  183. input_tokens INTEGER NOT NULL DEFAULT 0,
  184. output_tokens INTEGER NOT NULL DEFAULT 0,
  185. bill NUMERIC(12, 4) NOT NULL DEFAULT 0,
  186. status VARCHAR(20) NOT NULL DEFAULT 'success',
  187. error_message TEXT,
  188. request_ip VARCHAR(50),
  189. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
  190. );
  191. CREATE INDEX idx_api_call_log_user_id ON aigcspace.api_call_log(user_id);
  192. CREATE INDEX idx_api_call_log_api_key_id ON aigcspace.api_call_log(api_key_id);
  193. CREATE INDEX idx_api_call_log_model_id ON aigcspace.api_call_log(model_id);
  194. CREATE INDEX idx_api_call_log_created_at ON aigcspace.api_call_log(created_at);
  195. CREATE INDEX idx_api_call_log_is_local ON aigcspace.api_call_log(is_local);
  196. CREATE INDEX idx_api_call_log_model_name ON aigcspace.api_call_log(model_name);
  197. -- =============================================
  198. -- 6. 用户本地模型权限表
  199. -- =============================================
  200. CREATE TABLE aigcspace.user_local_model_permission (
  201. id SERIAL NOT NULL PRIMARY KEY,
  202. user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE,
  203. model_id INTEGER NOT NULL REFERENCES aigcspace.models_new(id) ON DELETE CASCADE,
  204. has_access BOOLEAN NOT NULL DEFAULT true,
  205. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
  206. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
  207. UNIQUE(user_id, model_id)
  208. );
  209. -- =============================================
  210. -- 7. 系统配置表
  211. -- =============================================
  212. CREATE TABLE aigcspace.system_config (
  213. id SERIAL NOT NULL PRIMARY KEY,
  214. config_key VARCHAR(100) NOT NULL UNIQUE,
  215. config_value TEXT NOT NULL DEFAULT '',
  216. config_type VARCHAR(20) NOT NULL DEFAULT 'string',
  217. category VARCHAR(50) NOT NULL DEFAULT 'basic',
  218. description VARCHAR(500),
  219. updated_by INTEGER REFERENCES aigcspace.admin_users(id),
  220. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
  221. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  222. );
  223. CREATE TABLE aigcspace.config_history (
  224. id SERIAL NOT NULL PRIMARY KEY,
  225. config_key VARCHAR(100) NOT NULL,
  226. old_value TEXT,
  227. new_value TEXT NOT NULL,
  228. updated_by INTEGER REFERENCES aigcspace.admin_users(id),
  229. updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  230. );
  231. -- =============================================
  232. -- 8. 日志表
  233. -- =============================================
  234. CREATE TABLE aigcspace.login_log (
  235. id SERIAL NOT NULL PRIMARY KEY,
  236. user_id VARCHAR(50) NOT NULL,
  237. username VARCHAR(100),
  238. user_type VARCHAR(20) NOT NULL DEFAULT 'user',
  239. login_result VARCHAR(20) NOT NULL,
  240. fail_reason VARCHAR(200),
  241. ip_address VARCHAR(50),
  242. user_agent TEXT,
  243. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  244. );
  245. CREATE INDEX idx_login_log_user_id ON aigcspace.login_log(user_id);
  246. CREATE INDEX idx_login_log_created_at ON aigcspace.login_log(created_at);
  247. CREATE TABLE aigcspace.api_log (
  248. id SERIAL NOT NULL PRIMARY KEY,
  249. user_id VARCHAR(50),
  250. username VARCHAR(100),
  251. phone VARCHAR(20),
  252. module VARCHAR(50),
  253. api_path VARCHAR(500) NOT NULL,
  254. request_method VARCHAR(10) NOT NULL,
  255. request_params JSON,
  256. response_status INTEGER,
  257. response_time INTEGER,
  258. created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
  259. );
  260. CREATE INDEX idx_api_log_user_id ON aigcspace.api_log(user_id);
  261. CREATE INDEX idx_api_log_created_at ON aigcspace.api_log(created_at);
  262. CREATE INDEX idx_api_log_module ON aigcspace.api_log(module);
  263. -- =============================================
  264. -- 9. 初始化默认管理员(密码: admin123 的 SHA256)
  265. -- =============================================
  266. INSERT INTO aigcspace.admin_users (username, password_hash, nickname, status)
  267. VALUES ('admin', '240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9', '超级管理员', 'active')
  268. ON CONFLICT (username) DO NOTHING;
  269. -- =============================================
  270. -- 10. 初始化系统配置
  271. -- =============================================
  272. INSERT INTO aigcspace.system_config (config_key, config_value, config_type, category, description) VALUES
  273. ('system_name', '四川路桥Maas算力平台', 'string', 'basic', '平台名称'),
  274. ('system_logo', '', 'string', 'basic', '平台Logo URL'),
  275. ('icp_number', '', 'string', 'basic', 'ICP备案号'),
  276. ('contact_email', '', 'string', 'basic', '联系邮箱'),
  277. ('enable_local_models', 'true', 'boolean', 'feature', '是否启用私域模型功能'),
  278. ('enable_registration', 'true', 'boolean', 'feature', '是否开放注册'),
  279. ('max_api_keys_per_user', '5', 'number', 'limit', '每用户最大API Key数量')
  280. ON CONFLICT (config_key) DO NOTHING;