dqm-api-client
Version:
A Node.js client library for court booking API services including authentication, SMS verification, and court management
182 lines (163 loc) • 4.63 kB
JavaScript
const crypto = require('crypto');
function generateWxPaySign(params) {
function getSignStr(params) {
var signStr = '';
var keys = [];
for (var key in params) {
if (params[key] !== '' && params[key] && key !== 'sign') {
keys.push(key);
}
}
keys.sort();
for (var i = 0; i < keys.length; i++) {
if (i > 0) {
signStr += '&';
}
var value =
typeof params[keys[i]] === 'object'
? JSON.stringify(params[keys[i]])
: params[keys[i]];
signStr += keys[i] + '=' + value;
}
return encodeURIComponent(signStr);
}
const signStr = getSignStr(params);
const sign = crypto.createHash('md5').update(signStr).digest('hex');
return sign;
}
function randomString(len) {
var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678=';
var maxPos = chars.length;
var str = '';
for (var i = 0; i < len; i++) {
str += chars.charAt(Math.floor(Math.random() * maxPos));
}
return str;
}
function encodeOpenId(openId) {
// 检查输入的 openId 是否有效
if (!openId || typeof openId !== 'string') {
return ''; // 如果 openId 为空或不是字符串,返回空字符串
}
// 获取当前分钟级时间戳
const timestamp = Math.floor(Date.now() / 60000).toString();
// 拼接 openId 和时间戳
const combined = openId + timestamp;
// 使用 Buffer 将拼接字符串转换为 Base64 编码
const encoded = Buffer.from(combined).toString('base64');
return encoded;
}
function findAvailableSlots(courtData, fieldName, startTime, endTime) {
if (!courtData || !courtData.booking_array) {
console.error('无效的场地数据结构');
return [];
}
const availableSlots = [];
// 遍历每个时间段 (例如: 13:00-14:00, 14:00-15:00)
for (const timeSlot of courtData.booking_array) {
if (!timeSlot.booking_infos) {
continue;
}
// 遍历该时间段下的所有场地信息
for (const courtInfo of timeSlot.booking_infos) {
// 检查是否满足所有条件
const isTargetField = courtInfo.fieldName === fieldName;
const isInTimeRange =
courtInfo.startDateHours >= startTime &&
courtInfo.startDateHours < endTime;
const isAvailable = courtInfo.state?.state === '可预订';
if (isTargetField && isInTimeRange && isAvailable) {
availableSlots.push({
_time: courtInfo._time,
_field: courtInfo._field,
});
}
}
}
return availableSlots;
}
//构建订单参数
const getOrderParams = (
org,
memberId,
orderDate,
orderArr,
openid,
smscode = ''
) => {
const randomStr = randomString(15);
const orderParam = {
_org: org,
_member: memberId,
orderDate: orderDate,
spbill_create_ip: '0.0.0.0',
orderArr: orderArr,
wxid: openid,
state: 'xiaochengxu',
thirdName: '微信',
randomStr: randomStr,
openid: openid,
payment: 'cup',
code: smscode,
thirdSerect: '微信',
};
// 生成签名
const signParams = { ...orderParam, thirdSerect: '微信' };
const sign = generateWxPaySign(signParams);
console.log('生成的签名:', sign);
// 移除 thirdSerect 并添加签名
delete orderParam.thirdSerect;
orderParam.sign = sign;
return orderParam;
};
//生成订单时间戳
const generateOrderTimestamp = dateStr => {
const [month, day] = dateStr.split('-');
const year = new Date().getFullYear();
return new Date(`${year}-${month}-${day}T00:00:00`).getTime();
};
/**
* 解码 OpenID (Base64 解码)
* @param {string} encodedOpenId 编码后的 OpenID
* @returns {string} 解码后的 OpenID
*/
const decodeOpenId = encodedOpenId => {
try {
return Buffer.from(encodedOpenId, 'base64').toString('utf8');
} catch (error) {
console.error('OpenID 解码失败:', error);
return encodedOpenId; // 解码失败时返回原值
}
};
/**
* 生成当前时间戳(毫秒)
* @returns {number} 时间戳
*/
const generateTimestamp = () => {
return Date.now();
};
/**
* 生成随机字符串
* @param {number} length 字符串长度,默认16
* @returns {string} 随机字符串
*/
const generateNonce = (length = 16) => {
const chars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
};
module.exports = {
generateWxPaySign,
randomString,
encodeOpenId,
decodeOpenId,
findAvailableSlots,
getOrderParams,
generateOrderTimestamp,
generateTimestamp,
generateNonce,
};