123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- const express = require('express');
- const router = express.Router();
- const { Contact } = require('../models');
- const { sendContactNotification, sendAutoReply } = require('../utils/emailService');
- const { successResponse, errorResponse } = require('../utils/responese');
- /**
- * @api {post} /contact 提交联系我们表单
- * @apiName CreateContact
- * @apiGroup Contact
- *
- * @apiParam {String} name 联系人姓名(必填)
- * @apiParam {String} email 联系人邮箱(必填)
- * @apiParam {String} [phone] 联系电话
- * @apiParam {String} [company] 公司名称
- * @apiParam {String} subject 留言主题(必填)
- * @apiParam {String} message 留言内容(必填)
- *
- * @apiSuccess {Boolean} status 请求状态
- * @apiSuccess {String} message 响应消息
- * @apiSuccess {Object} data 创建的联系信息
- *
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 201 Created
- * {
- * "status": true,
- * "message": "留言提交成功,我们会尽快回复您",
- * "data": {
- * "id": 1,
- * "message": "感谢您的留言,我们已收到并会在24小时内回复"
- * }
- * }
- */
- router.post('/', async (req, res) => {
- try {
- const { name, email, phone, company, subject, message } = req.body;
-
- // 参数验证
- const errors = [];
- if (!name || name.trim().length === 0) {
- errors.push('联系人姓名不能为空');
- }
- if (!email || email.trim().length === 0) {
- errors.push('联系人邮箱不能为空');
- }
- if (!subject || subject.trim().length === 0) {
- errors.push('留言主题不能为空');
- }
- if (!message || message.trim().length === 0) {
- errors.push('留言内容不能为空');
- }
-
- // 邮箱格式验证
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- if (email && !emailRegex.test(email)) {
- errors.push('邮箱格式不正确');
- }
-
- // 字符长度验证
- if (name && name.trim().length > 100) {
- errors.push('联系人姓名不能超过100个字符');
- }
- if (subject && subject.trim().length > 200) {
- errors.push('留言主题不能超过200个字符');
- }
- if (company && company.trim().length > 200) {
- errors.push('公司名称不能超过200个字符');
- }
- if (phone && phone.trim().length > 20) {
- errors.push('联系电话不能超过20个字符');
- }
-
- if (errors.length > 0) {
- return res.status(400).json(errorResponse('参数验证失败', errors));
- }
-
- // 保存到数据库
- const contactData = await Contact.create({
- name: name.trim(),
- email: email.trim().toLowerCase(),
- phone: phone ? phone.trim() : null,
- company: company ? company.trim() : null,
- subject: subject.trim(),
- message: message.trim()
- });
-
- // 异步发送邮件(不阻塞响应)
- setImmediate(async () => {
- try {
- // 发送通知邮件给管理员
- const notificationSent = await sendContactNotification(contactData.toJSON());
-
- // 发送自动回复给客户
- const autoReplySent = await sendAutoReply(contactData.toJSON());
-
- // 更新邮件发送状态
- if (notificationSent || autoReplySent) {
- await contactData.update({ isEmailSent: true });
- }
-
- console.log(`联系表单处理完成 - ID: ${contactData.id}, 通知邮件: ${notificationSent ? '成功' : '失败'}, 自动回复: ${autoReplySent ? '成功' : '失败'}`);
- } catch (emailError) {
- console.error('邮件发送过程出错:', emailError);
- }
- });
-
- // 立即返回成功响应
- res.status(201).json(successResponse('留言提交成功,我们会尽快回复您', {
- id: contactData.id,
- message: '感谢您的留言,我们已收到并会在24小时内回复'
- }));
-
- } catch (error) {
- console.error('提交联系表单失败:', error);
- res.status(500).json(errorResponse('服务器内部错误'));
- }
- });
- /**
- * @api {get} /contact 获取联系我们列表(管理员用)
- * @apiName GetContacts
- * @apiGroup Contact
- *
- * @apiParam {Number} [page=1] 页码
- * @apiParam {Number} [limit=10] 每页数量
- * @apiParam {Number} [status] 处理状态筛选(0-未处理,1-已处理)
- */
- router.get('/', async (req, res) => {
- try {
- const { page = 1, limit = 10, status } = req.query;
- const offset = (page - 1) * limit;
-
- const whereConditions = {};
- if (status !== undefined) {
- whereConditions.status = parseInt(status);
- }
-
- const { count, rows } = await Contact.findAndCountAll({
- where: whereConditions,
- order: [['createdAt', 'DESC']],
- limit: parseInt(limit),
- offset: parseInt(offset)
- });
-
- res.json(successResponse('获取成功', {
- contacts: rows,
- pagination: {
- total: count,
- page: parseInt(page),
- limit: parseInt(limit),
- totalPages: Math.ceil(count / limit)
- }
- }));
- } catch (error) {
- console.error('获取联系列表失败:', error);
- res.status(500).json(errorResponse('服务器内部错误'));
- }
- });
- /**
- * @api {get} /contact/:id 获取联系详情
- * @apiName GetContactDetail
- * @apiGroup Contact
- */
- router.get('/:id', async (req, res) => {
- try {
- const { id } = req.params;
-
- const contact = await Contact.findByPk(id);
- if (!contact) {
- return res.status(404).json(errorResponse('联系记录不存在'));
- }
-
- res.json(successResponse('获取成功', contact));
- } catch (error) {
- console.error('获取联系详情失败:', error);
- res.status(500).json(errorResponse('服务器内部错误'));
- }
- });
- /**
- * @api {put} /contact/:id/status 更新处理状态
- * @apiName UpdateContactStatus
- * @apiGroup Contact
- *
- * @apiParam {Number} status 处理状态(0-未处理,1-已处理)
- */
- router.put('/:id/status', async (req, res) => {
- try {
- const { id } = req.params;
- const { status } = req.body;
-
- if (![0, 1].includes(parseInt(status))) {
- return res.status(400).json(errorResponse('状态值只能是0或1'));
- }
-
- const contact = await Contact.findByPk(id);
- if (!contact) {
- return res.status(404).json(errorResponse('联系记录不存在'));
- }
-
- await contact.update({ status: parseInt(status) });
-
- res.json(successResponse('状态更新成功', contact));
- } catch (error) {
- console.error('更新联系状态失败:', error);
- res.status(500).json(errorResponse('服务器内部错误'));
- }
- });
- /**
- * @api {delete} /contact/:id 删除联系记录
- * @apiName DeleteContact
- * @apiGroup Contact
- */
- router.delete('/:id', async (req, res) => {
- try {
- const { id } = req.params;
-
- const contact = await Contact.findByPk(id);
- if (!contact) {
- return res.status(404).json(errorResponse('联系记录不存在'));
- }
-
- await contact.destroy();
-
- res.json(successResponse('删除成功'));
- } catch (error) {
- console.error('删除联系记录失败:', error);
- res.status(500).json(errorResponse('服务器内部错误'));
- }
- });
- module.exports = router;
|