基于Node.js+Mongo+Express实现SaaS应用未来一年服务日期生成
解决方案
1. 日期处理工具函数
先通过工具函数处理日期解析和服务日期生成,这里用date-fns简化日期操作(也可以用原生Date API,但第三方库更直观不易出错)。
先安装依赖:
npm install date-fns
工具函数代码:
const { addMonths, addWeeks, format, isAfter, startOfMonth } = require('date-fns'); // 解析DD-MM-YYYY格式的日期字符串为Date对象 const parseLastServiceDate = (dateStr) => { const [day, month, year] = dateStr.split('-').map(Number); return new Date(year, month - 1, day); // JS Date的月份是0-based,要减1 }; // 生成未来一年的服务日期列表,过滤出当前月份及之后的日期 const generateNextServices = (lastServiceDate, serviceMode, currentMonth) => { const currentMonthStart = startOfMonth(new Date(currentMonth)); const endDate = addMonths(currentMonthStart, 12); // 未来一年的截止日期 let nextDate = lastServiceDate; const services = []; while (isAfter(endDate, nextDate)) { // 根据服务模式计算下一次服务日期 switch (serviceMode.toLowerCase()) { case 'weekly': nextDate = addWeeks(nextDate, 1); break; case 'monthly': nextDate = addMonths(nextDate, 1); break; case 'quarterly': nextDate = addMonths(nextDate, 3); break; default: throw new Error(`不支持的服务模式:${serviceMode}`); } // 只保留当前月份及之后、且在未来一年内的日期 if (nextDate >= currentMonthStart && isAfter(endDate, nextDate)) { services.push(format(nextDate, 'dd-MM-yyyy')); } } return services; };
2. Express接口实现
创建Express路由,接收currentMonth参数(格式为YYYY-MM,比如2022-10),查询MongoDB数据并处理返回结果。这里用Mongoose作为MongoDB驱动示例:
const express = require('express'); const router = express.Router(); const mongoose = require('mongoose'); const { parseLastServiceDate, generateNextServices } = require('./date-utils'); // 定义产品Schema,和数据库结构匹配 const ProductSchema = new mongoose.Schema({ ItemName: String, LastService: String, ServiceMode: String }); const Product = mongoose.model('Product', ProductSchema); // 获取服务日期列表的接口 router.get('/next-services', async (req, res) => { try { const { currentMonth } = req.query; // 校验参数格式 if (!currentMonth || !/^\d{4}-\d{2}$/.test(currentMonth)) { return res.status(400).json({ error: 'currentMonth参数格式错误,需为YYYY-MM' }); } // 查询所有产品数据 const products = await Product.find(); // 转换为要求的响应格式 const result = products.map(product => { const lastServiceDate = parseLastServiceDate(product.LastService); const nextServices = generateNextServices(lastServiceDate, product.ServiceMode, currentMonth); return { ItemName: product.ItemName, ServiceMode: product.ServiceMode, NextServices: nextServices }; }); res.json(result); } catch (error) { console.error('生成服务日期失败:', error); res.status(500).json({ error: '服务器内部错误' }); } }); module.exports = router;
3. 测试接口
启动Express服务后,访问以下地址即可得到目标响应:
GET /next-services?currentMonth=2022-10
关键注意点
- 日期格式校验:确保数据库中
LastService字段严格遵循DD-MM-YYYY格式,存入时最好做格式校验,避免解析出错。 - 时区问题:如果涉及跨时区用户,建议统一用UTC日期处理,避免时区偏移导致的日期偏差。
- 扩展性:后续新增服务模式(如半年一次),只需在
generateNextServices的switch分支中添加对应逻辑即可。
内容的提问来源于stack exchange,提问作者Prasanth
相关产品推荐
相关产品推荐

