initDatabase.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. require('dotenv').config();
  2. const mysql = require('mysql2/promise');
  3. const dbConfig = {
  4. host: process.env.DB_HOST,
  5. port: process.env.DB_PORT,
  6. user: process.env.DB_USER,
  7. password: process.env.DB_PASSWORD,
  8. };
  9. async function initDatabase() {
  10. let connection;
  11. try {
  12. connection = await mysql.createConnection(dbConfig);
  13. console.log('数据库连接成功');
  14. // 创建数据库
  15. await connection.query(`CREATE DATABASE IF NOT EXISTS ${process.env.DB_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`);
  16. console.log(`数据库 ${process.env.DB_NAME} 创建成功`);
  17. await connection.query(`USE ${process.env.DB_NAME}`);
  18. // 用户表
  19. await connection.query(`
  20. CREATE TABLE IF NOT EXISTS users (
  21. id VARCHAR(36) PRIMARY KEY,
  22. username VARCHAR(50) UNIQUE NOT NULL,
  23. password VARCHAR(255) NOT NULL,
  24. real_name VARCHAR(50) NOT NULL,
  25. email VARCHAR(100),
  26. phone VARCHAR(20),
  27. role ENUM('sales', 'sales_manager', 'sales_director', 'admin') NOT NULL DEFAULT 'sales',
  28. department VARCHAR(50),
  29. team VARCHAR(50),
  30. status ENUM('active', 'inactive') DEFAULT 'active',
  31. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  32. updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  33. INDEX idx_role (role),
  34. INDEX idx_department (department),
  35. INDEX idx_team (team)
  36. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  37. `);
  38. console.log('用户表创建成功');
  39. // 客户报备表
  40. await connection.query(`
  41. CREATE TABLE IF NOT EXISTS customers (
  42. id VARCHAR(36) PRIMARY KEY,
  43. customer_name VARCHAR(200) NOT NULL,
  44. industry VARCHAR(100),
  45. region VARCHAR(100),
  46. contact_person VARCHAR(50),
  47. contact_phone VARCHAR(20),
  48. demand_description TEXT,
  49. source VARCHAR(50),
  50. sales_owner VARCHAR(36) NOT NULL,
  51. report_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  52. protected_end_date TIMESTAMP,
  53. status ENUM('following', 'won', 'lost', 'released') DEFAULT 'following',
  54. last_followup TIMESTAMP,
  55. release_reason VARCHAR(200),
  56. is_in_pool BOOLEAN DEFAULT FALSE,
  57. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  58. updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  59. FOREIGN KEY (sales_owner) REFERENCES users(id) ON DELETE RESTRICT,
  60. INDEX idx_customer_name (customer_name),
  61. INDEX idx_sales_owner (sales_owner),
  62. INDEX idx_status (status),
  63. INDEX idx_protected_end_date (protected_end_date),
  64. INDEX idx_is_in_pool (is_in_pool),
  65. FULLTEXT idx_ft_customer_name (customer_name)
  66. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  67. `);
  68. console.log('客户报备表创建成功');
  69. // 跟进记录表
  70. await connection.query(`
  71. CREATE TABLE IF NOT EXISTS followup_records (
  72. id VARCHAR(36) PRIMARY KEY,
  73. customer_id VARCHAR(36) NOT NULL,
  74. user_id VARCHAR(36) NOT NULL,
  75. followup_type ENUM('call', 'visit', 'email', 'wechat', 'other') DEFAULT 'call',
  76. content TEXT,
  77. next_plan TEXT,
  78. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  79. FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE,
  80. FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  81. INDEX idx_customer_id (customer_id),
  82. INDEX idx_user_id (user_id),
  83. INDEX idx_created_at (created_at)
  84. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  85. `);
  86. console.log('跟进记录表创建成功');
  87. // 公海池领取记录表
  88. await connection.query(`
  89. CREATE TABLE IF NOT EXISTS pool_claim_records (
  90. id VARCHAR(36) PRIMARY KEY,
  91. customer_id VARCHAR(36) NOT NULL,
  92. user_id VARCHAR(36) NOT NULL,
  93. claim_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  94. FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE,
  95. FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  96. INDEX idx_customer_id (customer_id),
  97. INDEX idx_user_id (user_id),
  98. INDEX idx_claim_time (claim_time)
  99. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  100. `);
  101. console.log('公海池领取记录表创建成功');
  102. // 审批流程表
  103. await connection.query(`
  104. CREATE TABLE IF NOT EXISTS approvals (
  105. id VARCHAR(36) PRIMARY KEY,
  106. type ENUM('extension', 'force_release', 'collaboration') NOT NULL,
  107. applicant_id VARCHAR(36) NOT NULL,
  108. approver_id VARCHAR(36),
  109. customer_id VARCHAR(36),
  110. reason TEXT,
  111. extension_days INT,
  112. status ENUM('pending', 'approved', 'rejected') DEFAULT 'pending',
  113. result_comment TEXT,
  114. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  115. processed_at TIMESTAMP,
  116. FOREIGN KEY (applicant_id) REFERENCES users(id) ON DELETE CASCADE,
  117. FOREIGN KEY (approver_id) REFERENCES users(id) ON DELETE SET NULL,
  118. FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE,
  119. INDEX idx_applicant_id (applicant_id),
  120. INDEX idx_approver_id (approver_id),
  121. INDEX idx_status (status),
  122. INDEX idx_type (type)
  123. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  124. `);
  125. console.log('审批流程表创建成功');
  126. // 操作日志表
  127. await connection.query(`
  128. CREATE TABLE IF NOT EXISTS operation_logs (
  129. id VARCHAR(36) PRIMARY KEY,
  130. user_id VARCHAR(36),
  131. action VARCHAR(50) NOT NULL,
  132. target_type VARCHAR(50),
  133. target_id VARCHAR(36),
  134. details TEXT,
  135. ip_address VARCHAR(45),
  136. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  137. FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
  138. INDEX idx_user_id (user_id),
  139. INDEX idx_action (action),
  140. INDEX idx_created_at (created_at)
  141. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  142. `);
  143. console.log('操作日志表创建成功');
  144. // 附件表
  145. await connection.query(`
  146. CREATE TABLE IF NOT EXISTS attachments (
  147. id VARCHAR(36) PRIMARY KEY,
  148. customer_id VARCHAR(36) NOT NULL,
  149. filename VARCHAR(255) NOT NULL,
  150. original_name VARCHAR(255) NOT NULL,
  151. file_path VARCHAR(500) NOT NULL,
  152. file_size INT,
  153. mime_type VARCHAR(100),
  154. uploaded_by VARCHAR(36) NOT NULL,
  155. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  156. FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE,
  157. FOREIGN KEY (uploaded_by) REFERENCES users(id) ON DELETE CASCADE,
  158. INDEX idx_customer_id (customer_id)
  159. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  160. `);
  161. console.log('附件表创建成功');
  162. // 插入默认管理员账号 (密码: admin123)
  163. const bcrypt = require('bcryptjs');
  164. const crypto = require('crypto');
  165. const adminPassword = await bcrypt.hash('admin123', 10);
  166. const adminId = crypto.randomUUID();
  167. await connection.query(`
  168. INSERT INTO users (id, username, password, real_name, role, department)
  169. VALUES (?, 'admin', ?, '系统管理员', 'admin', '管理部')
  170. ON DUPLICATE KEY UPDATE username=username
  171. `, [adminId, adminPassword]);
  172. console.log('默认管理员账号创建成功 (用户名: admin, 密码: admin123)');
  173. console.log('\n数据库初始化完成!');
  174. } catch (error) {
  175. console.error('数据库初始化失败:', error);
  176. process.exit(1);
  177. } finally {
  178. if (connection) {
  179. await connection.end();
  180. }
  181. }
  182. }
  183. initDatabase();