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

crm-backend-fixed.js 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. require('dotenv').config();
  2. const express = require('express');
  3. const cors = require('cors');
  4. const fs = require('fs');
  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. // 使用 JSON 文件存储数据 - 修复路径
  11. const dbPath = path.join(__dirname, '..', '..', 'data', 'crm-data.json');
  12. function loadDB() {
  13. try {
  14. if (fs.existsSync(dbPath)) {
  15. return JSON.parse(fs.readFileSync(dbPath, 'utf-8'));
  16. }
  17. } catch (e) {
  18. console.error('加载数据库失败:', e.message);
  19. }
  20. return { customers: [], followUps: [] };
  21. }
  22. function saveDB(data) {
  23. try {
  24. const dir = path.dirname(dbPath);
  25. if (!fs.existsSync(dir)) {
  26. fs.mkdirSync(dir, { recursive: true });
  27. }
  28. fs.writeFileSync(dbPath, JSON.stringify(data, null, 2), 'utf-8');
  29. console.log('💾 数据已保存:', dbPath);
  30. } catch (e) {
  31. console.error('保存数据库失败:', e.message);
  32. }
  33. }
  34. // 初始化
  35. let db = loadDB();
  36. console.log('📊 数据文件:', dbPath);
  37. console.log('📝 当前客户数:', db.customers.length);
  38. // 健康检查
  39. app.get('/api/health', (req, res) => {
  40. res.json({ status: 'ok', service: 'CRM API', customers: db.customers.length });
  41. });
  42. // 获取客户列表
  43. app.get('/api/customers', (req, res) => {
  44. try {
  45. const { status, keyword } = req.query;
  46. let customers = db.customers;
  47. if (status) {
  48. customers = customers.filter(c => c.status === status);
  49. }
  50. if (keyword) {
  51. const k = keyword.toLowerCase();
  52. customers = customers.filter(c =>
  53. c.name.toLowerCase().includes(k) ||
  54. (c.company && c.company.toLowerCase().includes(k)) ||
  55. (c.phone && c.phone.includes(k))
  56. );
  57. }
  58. customers.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
  59. res.json({ success: true, data: customers });
  60. } catch (error) {
  61. res.status(500).json({ success: false, error: error.message });
  62. }
  63. });
  64. // 获取客户详情
  65. app.get('/api/customers/:id', (req, res) => {
  66. try {
  67. const customer = db.customers.find(c => c.id == req.params.id);
  68. if (!customer) {
  69. return res.status(404).json({ success: false, error: '客户不存在' });
  70. }
  71. const followUps = db.followUps.filter(f => f.customer_id == req.params.id)
  72. .sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
  73. res.json({ success: true, data: { ...customer, followUps } });
  74. } catch (error) {
  75. res.status(500).json({ success: false, error: error.message });
  76. }
  77. });
  78. // 创建客户
  79. app.post('/api/customers', (req, res) => {
  80. try {
  81. const { name, company, phone, email, source, notes } = req.body;
  82. if (!name) {
  83. return res.status(400).json({ success: false, error: '客户名称必填' });
  84. }
  85. const customer = {
  86. id: Date.now(),
  87. name,
  88. company: company || '',
  89. phone: phone || '',
  90. email: email || '',
  91. source: source || '',
  92. status: 'potential',
  93. notes: notes || '',
  94. created_at: new Date().toISOString(),
  95. updated_at: new Date().toISOString()
  96. };
  97. db.customers.push(customer);
  98. saveDB(db);
  99. res.json({ success: true, data: { id: customer.id }, message: '客户创建成功' });
  100. } catch (error) {
  101. console.error('创建客户失败:', error);
  102. res.status(500).json({ success: false, error: error.message });
  103. }
  104. });
  105. // 更新客户
  106. app.put('/api/customers/:id', (req, res) => {
  107. try {
  108. const index = db.customers.findIndex(c => c.id == req.params.id);
  109. if (index === -1) {
  110. return res.status(404).json({ success: false, error: '客户不存在' });
  111. }
  112. const { name, company, phone, email, source, status, notes } = req.body;
  113. db.customers[index] = {
  114. ...db.customers[index],
  115. name, company, phone, email, source, status, notes,
  116. updated_at: new Date().toISOString()
  117. };
  118. saveDB(db);
  119. res.json({ success: true, message: '客户更新成功' });
  120. } catch (error) {
  121. res.status(500).json({ success: false, error: error.message });
  122. }
  123. });
  124. // 删除客户
  125. app.delete('/api/customers/:id', (req, res) => {
  126. try {
  127. const index = db.customers.findIndex(c => c.id == req.params.id);
  128. if (index === -1) {
  129. return res.status(404).json({ success: false, error: '客户不存在' });
  130. }
  131. db.customers.splice(index, 1);
  132. db.followUps = db.followUps.filter(f => f.customer_id != req.params.id);
  133. saveDB(db);
  134. res.json({ success: true, message: '客户删除成功' });
  135. } catch (error) {
  136. res.status(500).json({ success: false, error: error.message });
  137. }
  138. });
  139. // 添加跟进记录
  140. app.post('/api/customers/:id/followups', (req, res) => {
  141. try {
  142. const { type, content, nextFollowup } = req.body;
  143. const followUp = {
  144. id: Date.now(),
  145. customer_id: parseInt(req.params.id),
  146. type: type || '',
  147. content: content || '',
  148. next_followup: nextFollowup || null,
  149. created_at: new Date().toISOString()
  150. };
  151. db.followUps.push(followUp);
  152. // 更新客户状态
  153. if (type === '成交') {
  154. const index = db.customers.findIndex(c => c.id == req.params.id);
  155. if (index !== -1) {
  156. db.customers[index].status = 'customer';
  157. db.customers[index].updated_at = new Date().toISOString();
  158. }
  159. }
  160. saveDB(db);
  161. res.json({ success: true, data: { id: followUp.id }, message: '跟进记录添加成功' });
  162. } catch (error) {
  163. res.status(500).json({ success: false, error: error.message });
  164. }
  165. });
  166. // 获取统计数据
  167. app.get('/api/stats', (req, res) => {
  168. try {
  169. const total = db.customers.length;
  170. const potential = db.customers.filter(c => c.status === 'potential').length;
  171. const contacting = db.customers.filter(c => c.status === 'contacting').length;
  172. const customer = db.customers.filter(c => c.status === 'customer').length;
  173. res.json({ success: true, data: { total, potential, contacting, customer } });
  174. } catch (error) {
  175. res.status(500).json({ success: false, error: error.message });
  176. }
  177. });
  178. app.listen(PORT, () => {
  179. console.log(`🚀 CRM API 服务已启动:http://localhost:${PORT}`);
  180. });