智慧水务管理系统 - 精河县供水工程综合管理平台

crm-backend.js 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. require('dotenv').config();
  2. const express = require('express');
  3. const cors = require('cors');
  4. const Database = require('better-sqlite3');
  5. const path = require('path');
  6. const app = express();
  7. const PORT = process.env.PORT || 3002;
  8. app.use(cors());
  9. app.use(express.json());
  10. // 初始化数据库
  11. const dbPath = path.join(__dirname, '..', 'data', 'crm.db');
  12. const db = new Database(dbPath);
  13. // 创建客户表
  14. db.exec(`
  15. CREATE TABLE IF NOT EXISTS customers (
  16. id INTEGER PRIMARY KEY AUTOINCREMENT,
  17. name TEXT NOT NULL,
  18. company TEXT,
  19. phone TEXT,
  20. email TEXT,
  21. source TEXT,
  22. status TEXT DEFAULT 'potential',
  23. notes TEXT,
  24. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  25. updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  26. )
  27. `);
  28. // 创建跟进记录表
  29. db.exec(`
  30. CREATE TABLE IF NOT EXISTS follow_ups (
  31. id INTEGER PRIMARY KEY AUTOINCREMENT,
  32. customer_id INTEGER NOT NULL,
  33. type TEXT,
  34. content TEXT,
  35. next_followup DATE,
  36. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  37. FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE
  38. )
  39. `);
  40. // 健康检查
  41. app.get('/api/health', (req, res) => {
  42. res.json({ status: 'ok', service: 'CRM API' });
  43. });
  44. // 获取客户列表
  45. app.get('/api/customers', (req, res) => {
  46. try {
  47. const { status, keyword } = req.query;
  48. let sql = 'SELECT * FROM customers WHERE 1=1';
  49. const params = [];
  50. if (status) {
  51. sql += ' AND status = ?';
  52. params.push(status);
  53. }
  54. if (keyword) {
  55. sql += ' AND (name LIKE ? OR company LIKE ? OR phone LIKE ?)';
  56. params.push(`%${keyword}%`, `%${keyword}%`, `%${keyword}%`);
  57. }
  58. sql += ' ORDER BY created_at DESC';
  59. const customers = db.prepare(sql).all(...params);
  60. res.json({ success: true, data: customers });
  61. } catch (error) {
  62. res.status(500).json({ success: false, error: error.message });
  63. }
  64. });
  65. // 获取客户详情
  66. app.get('/api/customers/:id', (req, res) => {
  67. try {
  68. const customer = db.prepare('SELECT * FROM customers WHERE id = ?').get(req.params.id);
  69. if (!customer) {
  70. return res.status(404).json({ success: false, error: '客户不存在' });
  71. }
  72. const followUps = db.prepare('SELECT * FROM follow_ups WHERE customer_id = ? ORDER BY created_at DESC')
  73. .all(req.params.id);
  74. res.json({ success: true, data: { ...customer, followUps } });
  75. } catch (error) {
  76. res.status(500).json({ success: false, error: error.message });
  77. }
  78. });
  79. // 创建客户
  80. app.post('/api/customers', (req, res) => {
  81. try {
  82. const { name, company, phone, email, source, notes } = req.body;
  83. if (!name) {
  84. return res.status(400).json({ success: false, error: '客户名称必填' });
  85. }
  86. const stmt = db.prepare(`
  87. INSERT INTO customers (name, company, phone, email, source, notes)
  88. VALUES (?, ?, ?, ?, ?, ?)
  89. `);
  90. const result = stmt.run(name, company || '', phone || '', email || '', source || '', notes || '');
  91. res.json({
  92. success: true,
  93. data: { id: result.lastInsertRowid },
  94. message: '客户创建成功'
  95. });
  96. } catch (error) {
  97. res.status(500).json({ success: false, error: error.message });
  98. }
  99. });
  100. // 更新客户
  101. app.put('/api/customers/:id', (req, res) => {
  102. try {
  103. const { name, company, phone, email, source, status, notes } = req.body;
  104. const stmt = db.prepare(`
  105. UPDATE customers
  106. SET name = ?, company = ?, phone = ?, email = ?, source = ?, status = ?, notes = ?, updated_at = CURRENT_TIMESTAMP
  107. WHERE id = ?
  108. `);
  109. stmt.run(name, company, phone, email, source, status, notes, req.params.id);
  110. res.json({ success: true, message: '客户更新成功' });
  111. } catch (error) {
  112. res.status(500).json({ success: false, error: error.message });
  113. }
  114. });
  115. // 删除客户
  116. app.delete('/api/customers/:id', (req, res) => {
  117. try {
  118. db.prepare('DELETE FROM customers WHERE id = ?').run(req.params.id);
  119. res.json({ success: true, message: '客户删除成功' });
  120. } catch (error) {
  121. res.status(500).json({ success: false, error: error.message });
  122. }
  123. });
  124. // 添加跟进记录
  125. app.post('/api/customers/:id/followups', (req, res) => {
  126. try {
  127. const { type, content, nextFollowup } = req.body;
  128. const stmt = db.prepare(`
  129. INSERT INTO follow_ups (customer_id, type, content, next_followup)
  130. VALUES (?, ?, ?, ?)
  131. `);
  132. const result = stmt.run(req.params.id, type || '', content || '', nextFollowup || null);
  133. // 更新客户状态
  134. if (type === '成交') {
  135. db.prepare("UPDATE customers SET status = 'customer' WHERE id = ?").run(req.params.id);
  136. }
  137. res.json({
  138. success: true,
  139. data: { id: result.lastInsertRowid },
  140. message: '跟进记录添加成功'
  141. });
  142. } catch (error) {
  143. res.status(500).json({ success: false, error: error.message });
  144. }
  145. });
  146. // 获取统计数据
  147. app.get('/api/stats', (req, res) => {
  148. try {
  149. const total = db.prepare('SELECT COUNT(*) as count FROM customers').get().count;
  150. const potential = db.prepare("SELECT COUNT(*) as count FROM customers WHERE status = 'potential'").get().count;
  151. const contacting = db.prepare("SELECT COUNT(*) as count FROM customers WHERE status = 'contacting'").get().count;
  152. const customer = db.prepare("SELECT COUNT(*) as count FROM customers WHERE status = 'customer'").get().count;
  153. res.json({
  154. success: true,
  155. data: { total, potential, contacting, customer }
  156. });
  157. } catch (error) {
  158. res.status(500).json({ success: false, error: error.message });
  159. }
  160. });
  161. app.listen(PORT, () => {
  162. console.log(`🚀 CRM API 服务已启动:http://localhost:${PORT}`);
  163. console.log(`📊 数据库:${dbPath}`);
  164. });