新增教练端,实现业务闭环:会员登录注册→查询团课→预约团课→扫码签到→教练端开课→记录实际开课时间→教练端结课→记录实际结课时间→后台查询数据
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
const CryptoJS = require('crypto-js')
|
||||
|
||||
const SIGNATURE_SECRET = 'NovalonManageSystemSecretKey2026'
|
||||
|
||||
/**
|
||||
* 生成 HMAC-SHA256 签名
|
||||
*/
|
||||
function generateSignature(method, path, query, body, timestamp, nonce) {
|
||||
const stringToSign = [method, path, query || '', body || '', String(timestamp), nonce].join('\n')
|
||||
const signature = CryptoJS.HmacSHA256(stringToSign, SIGNATURE_SECRET)
|
||||
return CryptoJS.enc.Base64.stringify(signature)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机 nonce
|
||||
*/
|
||||
function generateNonce() {
|
||||
const timestamp = Date.now().toString(36)
|
||||
const randomPart = Math.random().toString(36).substring(2, 15)
|
||||
return timestamp + '-' + randomPart
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 URL 解析 path 和 query
|
||||
*/
|
||||
function parseUrl(url) {
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
const withoutProtocol = url.substring(url.indexOf('://') + 3)
|
||||
const pathStart = withoutProtocol.indexOf('/')
|
||||
if (pathStart === -1) return { path: '/', query: '' }
|
||||
const pathAndQuery = withoutProtocol.substring(pathStart)
|
||||
const queryIndex = pathAndQuery.indexOf('?')
|
||||
if (queryIndex === -1) return { path: pathAndQuery, query: '' }
|
||||
return { path: pathAndQuery.substring(0, queryIndex), query: pathAndQuery.substring(queryIndex + 1) }
|
||||
}
|
||||
const queryIndex = url.indexOf('?')
|
||||
if (queryIndex === -1) return { path: url, query: '' }
|
||||
return { path: url.substring(0, queryIndex), query: url.substring(queryIndex + 1) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名请求头
|
||||
*/
|
||||
function generateSignatureHeaders(method, url, body) {
|
||||
const timestamp = Date.now()
|
||||
const nonce = generateNonce()
|
||||
const { path, query } = parseUrl(url)
|
||||
const bodyStr = body ? (typeof body === 'string' ? body : JSON.stringify(body)) : ''
|
||||
|
||||
const signature = generateSignature(method.toUpperCase(), path, query, bodyStr, timestamp, nonce)
|
||||
|
||||
return {
|
||||
'X-Signature': signature,
|
||||
'X-Timestamp': String(timestamp),
|
||||
'X-Nonce': nonce
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { generateSignatureHeaders }
|
||||
Reference in New Issue
Block a user