vk框架或者普通函数封装的一些函数可以拿取使用【会持续更新】

1.身份证校验【通用】

javascript 复制代码
/**
 * @function isIDCard
 * @description 判断是否为有效的身份证号码。
 * @param {string} idCard - 待验证的身份证号码。
 * @returns {boolean} 返回验证结果。
 */
pubFun.isIDCard = function (idCard) {
        // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
        let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
        if (!reg.test(idCard)) {
                return false;
        }

        // 校验省份代码
        let provinceCode = idCard.substring(0, 2);
        let provinceList = {
                '11': '北京', '12': '天津', '13': '河北', '14': '山西', '15': '内蒙古',
                '21': '辽宁', '22': '吉林', '23': '黑龙江',
                '31': '上海', '32': '江苏', '33': '浙江', '34': '安徽', '35': '福建', '36': '江西', '37': '山东',
                '41': '河南', '42': '湖北', '43': '湖南', '44': '广东', '45': '广西', '46': '海南',
                '50': '重庆', '51': '四川', '52': '贵州', '53': '云南', '54': '西藏',
                '61': '陕西', '62': '甘肃', '63': '青海', '64': '宁夏', '65': '新疆',
                '71': '台湾', '81': '香港', '82': '澳门'
        };
        if (!provinceList[provinceCode]) {
                return false;
        }

        // 校验出生日期
        let year = idCard.length === 15 ? '19' + idCard.substring(6, 8) : idCard.substring(6, 10);
        let month = idCard.length === 15 ? idCard.substring(8, 10) : idCard.substring(10, 12);
        let day = idCard.length === 15 ? idCard.substring(10, 12) : idCard.substring(12, 14);
        let date = new Date(year + '-' + month + '-' + day);
        if (date.toString() === 'Invalid Date') {
                return false;
        }

        // 18位身份证需要校验最后一位
        if (idCard.length === 18) {
                let factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                let parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
                let sum = 0;
                for (let i = 0; i < 17; i++) {
                        sum += parseInt(idCard.charAt(i)) * factor[i];
                }
                let last = parity[sum % 11];
                if (last.toUpperCase() !== idCard.charAt(17).toUpperCase()) {
                        return false;
                }
        }

        return true;
}

2. 用于自定义时间范围得到x,y图表数据统计【通用】

javascript 复制代码
		/**
		 * 通用时间维度统计(金额 = total_fee - refund_fee)
		 * @param {Array} records - 数据源数组(数据库查询结果)
		 * @param {String} dateField - 时间字段名(如 pass_time)
		 * @param {String} type - 'day' | 'week' | 'month' | 'custom'
		 * @param {Number} startTime - 自定义开始时间(时间戳)
		 * @param {Number} endTime - 自定义结束时间(时间戳)
		 * @returns {Object} { xAxis: [], counts: [] }
		 */
		function statByTimeRange(records, dateField, type, startTime, endTime) {
			const pad = n => String(n).padStart(2, '0');
			const xAxis = [];
			const countsMap = {};
			const counts = [];

			// 统一的累加逻辑:total_fee - refund_fee(如果 refund_fee 为 undefined 则视为 0)
			const calcAmount = r => {
				const fee = Number(r.total_fee || 0);
				const refund = Number(r.refund_fee || 0);
				return fee - refund;
			};

			if (type === 'today') {
				for (let i = 0; i < 24; i++) {
					const label = `${pad(i)}:00`;
					xAxis.push(label);
					countsMap[i] = 0;
				}
				records.forEach(r => {
					const hour = new Date(r[dateField]).getHours();
					countsMap[hour] += calcAmount(r);
				});
				counts.push(...xAxis.map(label => {
					const hour = parseInt(label);
					return countsMap[hour] || 0;
				}));

			} else if (type === 'week') {
				const weekLabels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
				for (let i = 0; i < 7; i++) {
					xAxis.push(weekLabels[i]);
					countsMap[i] = 0;
				}
				records.forEach(r => {
					const day = new Date(r[dateField]).getDay(); // 周日=0
					const index = day === 0 ? 6 : day - 1;
					countsMap[index] += calcAmount(r);
				});
				counts.push(...weekLabels.map((_, i) => countsMap[i]));

			} else if (type === 'month') {
				const baseDate = new Date(records[0]?.[dateField] || Date.now());
				const year = baseDate.getFullYear();
				const month = baseDate.getMonth();
				const daysInMonth = new Date(year, month + 1, 0).getDate();

				for (let i = 1; i <= daysInMonth; i++) {
					const label = pad(i);
					xAxis.push(label);
					countsMap[label] = 0;
				}
				records.forEach(r => {
					const d = new Date(r[dateField]);
					const label = pad(d.getDate());
					countsMap[label] += calcAmount(r);
				});
				counts.push(...xAxis.map(label => countsMap[label]));

			} else if (type === 'custom') {
				if (!startTime || !endTime) {
					throw new Error("自定义时间统计需提供 startTime 和 endTime");
				}
				const diff = endTime - startTime;
				const oneDayMs = 86400000;

				if (diff <= oneDayMs) {
					// 小于等于一天,按小时统计
					for (let i = 0; i < 24; i++) {
						const label = `${pad(i)}:00`;
						xAxis.push(label);
						countsMap[i] = 0;
					}
					records.forEach(r => {
						const hour = new Date(r[dateField]).getHours();
						countsMap[hour] += calcAmount(r);
					});
					counts.push(...xAxis.map(label => {
						const hour = parseInt(label);
						return countsMap[hour] || 0;
					}));
				} else {
					// 跨天,按日期统计
					for (let ts = startTime; ts <= endTime; ts += oneDayMs) {
						const d = new Date(ts);
						const label = `${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
						xAxis.push(label);
						countsMap[label] = 0;
					}
					records.forEach(r => {
						const d = new Date(r[dateField]);
						const label = `${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
						if (countsMap[label] !== undefined) {
							countsMap[label] += calcAmount(r);
						}
					});
					counts.push(...xAxis.map(label => countsMap[label]));
				}
			}

			return { xAxis, counts };
		}

3.按星期几统计数据,可用于计算一周内的金额或者个数!【通用】

javascript 复制代码
/**
		 * 按星期几统计数据
		 * @param {Array} records - 要统计的数据数组(如数据库查询结果)
		 * @param {String} dateField - 记录中表示日期/时间戳的字段名(如 "_add_time"、"register_date")
		 * @param {Function} valueFn - 统计函数,接收每条记录,返回要累加的数值(如 r => 1 统计数量,r => r.total_fee 统计金额)
		 * @returns {Array} 长度为7的数组,依次为[周一, 周二, ..., 周日]的统计结果
		 */
		function statByWeek(records, dateField, valueFn) {
			let arr = new Array(7).fill(0);
			records.forEach(record => {
				if (record[dateField]) {
					let day = new Date(record[dateField]).getDay();
					let index = day === 0 ? 6 : day - 1;
					arr[index] += valueFn(record);
				}
			});
			return arr;
		}

4.可用于"同比昨日"【通用】

javascript 复制代码
		/**
	 * 聚合统计昨天和今天的某个字段(金额/数量等)
	 * @param {Object} params
	 * @param {Object} params.db - db对象
	 * @param {String} params.collection - 集合名
	 * @param {String} params.timeField - 时间字段名(如 _add_time、register_date)
	 * @param {Number} params.yesterdayStart - 昨日开始时间戳
	 * @param {Number} params.yesterdayEnd - 昨日结束时间戳
	 * @param {Number} params.todayStart - 今日开始时间戳
	 * @param {Number} params.todayEnd - 今日结束时间戳
	 * @param {Object} [params.extraMatch] - 额外match条件(如 {type: 'iou'})
	 * @param {String} [params.sumField] - 求和字段名(如 total_fee),不传则统计数量
	 * @returns {Promise<{today: number, yesterday: number}>}
	 */
		async function aggregateTodayYesterday({
			db,
			collection,
			timeField,
			yesterdayStart,
			yesterdayEnd,
			todayStart,
			todayEnd,
			extraMatch = {},
			sumField
		}) {
			// 构造match条件
			let match = Object.assign({}, extraMatch, {
				[timeField]: { $gte: yesterdayStart, $lte: todayEnd }
			});
			// 构造group
			let group = {
				_id: null,
				today: {
					$sum: {
						$cond: [
							{
								$and: [
									...(sumField ? [] : [extraMatch && extraMatch.type ? { $eq: [`$type`, extraMatch.type] } : []]),
									{ $gte: [`$${timeField}`, todayStart] },
									{ $lte: [`$${timeField}`, todayEnd] }
								]
							},
							sumField ? `$${sumField}` : 1,
							0
						]
					}
				},
				yesterday: {
					$sum: {
						$cond: [
							{
								$and: [
									...(sumField ? [] : [extraMatch && extraMatch.type ? { $eq: [`$type`, extraMatch.type] } : []]),
									{ $gte: [`$${timeField}`, yesterdayStart] },
									{ $lte: [`$${timeField}`, yesterdayEnd] }
								]
							},
							sumField ? `$${sumField}` : 1,
							0
						]
					}
				}
			};
			let aggRes = await db.collection(collection).aggregate()
				.match(match)
				.group(group)
				.end();

			let today = aggRes.data?.[0]?.today || 0;
			let yesterday = aggRes.data?.[0]?.yesterday || 0;
			return { today, yesterday };
		}
相关推荐
前端的日常1 分钟前
如何在 Vite 中配置路由?
前端
兮漫天1 分钟前
bun + vite7 的结合,孕育的 Robot Admin 靓仔出道(一)
前端
PineappleCoder2 分钟前
JS 作用域链拆解:变量查找的 “俄罗斯套娃” 规则
前端·javascript·面试
兮漫天3 分钟前
bun + vite7 的结合,孕育的 Robot Admin 靓仔出道(二)
前端
用户47949283569157 分钟前
面试官:为什么很多格式化工具都会在行尾额外空出一行
前端
知识分享小能手8 分钟前
Vue3 学习教程,从入门到精通,Vue3 中使用 Axios 进行 Ajax 请求的语法知识点与案例代码(23)
前端·javascript·vue.js·学习·ajax·vue·vue3
一大树8 分钟前
首屏白屏的处理方案~嗖得一下
前端
凹凸曼说我是怪兽y8 分钟前
python后端之DRF框架(上篇)
开发语言·后端·python
小old弟10 分钟前
🤔同时发送100个请求?!手撕,并发请求⌨️
前端
533_14 分钟前
[echarts] 更新数据
前端·javascript·echarts