Commit 1b96a8ac authored by 姜登's avatar 姜登

zmop_alipay正式服

parents
{
// 启动端口
"httpPort": 10031,
// 域名配置
"host": "http://t.51gjj.com",
"tj1": "http://tj1.51gjj.com:5118/",
// 正式服地址
"tj2": "http://tj2.51gjj.com:5118/",
// 测试服地址
"tj3": "http://tj3.51gjj.com:5118/",
"mongoUrl": "http://tv.51gjj.com",
"zhukeUrl": "http://tv.51gjj.com",
"hexinUrl": "http://td.51gjj.com",
"wlnUrl": "http://t.51gjj.com",
// 定时任务配置
"timeInterval": "00 00 00 * * *",
// log4js配置
"log4jsName": "zmop",
"log4jsConfig": {
"appenders": [
{
"type": "console"
},
{
"category": [
"console"
],
"type": "dateFile",
"filename": "./logs/",
"alwaysIncludePattern": true,
"pattern": "-yyyyMMdd.log"
}
],
"replaceConsole": true,
"levels": {
"console": "ALL"
}
},
"dbConfig": {
"connectionLimit": 50,
"host": "rm-bp1272001633qc0x9.mysql.rds.aliyuncs.com",
"user": "hexin",
"password": "gYUHszn9#q",
"database": "node_zm"
},
"dbConfigOcr": {
"connectionLimit": 50,
"host": "rm-bp1272001633qc0x9.mysql.rds.aliyuncs.com",
"user": "query",
"password": "5gqR2EQK",
"database": "ocr"
},
"dbConfigBG": {
"connectionLimit": 50,
"host": "rm-bp1272001633qc0x9.mysql.rds.aliyuncs.com",
"user": "query",
"password": "5gqR2EQK",
"database": "background"
},
"zmop_app_id":"300002663",
//"zmop_app_id": "300002565",
//"zmop_app_id": "300002796",
"entities": {
"300002565": "杭州巨业企业管理咨询有限公司",
"300002663": "杭州巨业企业管理咨询有限公司",
"300002796": "浙江容泽网络科技有限公司",
"2018051160085345": "",
"2018042460057138": "杭州盆钵信息技术有限公司",
"2018051560161652": "杭州靖乾网络科技有限公司"
}
}
[
{
"eventId": 5,
"desc": "每日登录",
"max_times": 1,
"times": 0,
"total": "0",
"complete": false
},
{
"eventId": 7,
"desc": "邀请好友",
"max_times": 0,
"times": 0,
"total": "0",
"complete": false
},
{
"eventId": 8,
"desc": "购买卡券",
"max_times": 3,
"times": 5,
"total": "100",
"complete": true
},
{
"eventId": 10,
"desc": "出售卡券",
"max_times": 5,
"times": 11,
"total": "220",
"complete": true
},
{
"date": "",
"delta": 0,
"complete": false,
"eventId": 3,
"desc": "社保认证"
},
{
"date": "2018-03-01",
"delta": -13,
"complete": false,
"eventId": 1,
"desc": "公积金认证"
}
]
const rp = require('request-promise'),
moment = require('moment'),
fs = require('fs'),
rsa = require('./rsa'),
orm = require('../orm'),
extend = require('extend'),
log = console.log.bind(console),
error = console.error.bind(console)
function build_transaction_id() {
let t = moment().format('YYYYMMDDHHmmssSSS')
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
while (t.length < 32) {
t += str[Math.round(Math.random() * (str.length - 1))]
}
return t
}
// 芝麻分
async function score(app_id, auth_token, user_id) {
let transaction_id = build_transaction_id()
let data = {
app_id: app_id,
method: 'zhima.credit.score.get',
format: 'JSON',
charset: 'utf-8',
sign_type: 'RSA2',
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
version: '1.0',
auth_token: auth_token,
biz_content: JSON.stringify({transaction_id: transaction_id, product_code: 'w1010100100000000001'}),
}
data.sign = rsa.sign(data, app_id)
let resp = await rp.post({
url: 'https://openapi.alipay.com/gateway.do',
json: true,
form: data
})
let row = {
transaction_id: transaction_id,
resp: JSON.stringify(resp),
open_id: user_id,
platform: 'alipay',
method: 'watch_list'
}
log('zmop_score resp: ', resp)
await orm.create_api_task(row)
if (rsa.verify(resp.sign, JSON.stringify(resp.zhima_credit_score_get_response), app_id)) {
return resp.zhima_credit_score_get_response
} else {
error('API-[ alipay/score ] 验签失败| app_id: ', app_id)
throw new Error('验签失败')
}
}
// 行业关注名单
async function watch_list(app_id, auth_token, user_id) {
let transaction_id = build_transaction_id()
let data = {
app_id: app_id,
method: 'zhima.credit.watchlistii.get',
format: 'JSON',
charset: 'utf-8',
sign_type: 'RSA2',
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
version: '1.0',
auth_token: auth_token,
biz_content: JSON.stringify({transaction_id: transaction_id, product_code: 'w1010100100000000022'}),
}
data.sign = rsa.sign(data, app_id)
let resp = await rp.post({
url: 'https://openapi.alipay.com/gateway.do',
json: true,
form: data
})
let row = {
transaction_id: transaction_id,
resp: JSON.stringify(resp),
open_id: user_id,
platform: 'alipay',
method: 'watch_list'
}
log('zmop_score resp: ', resp)
await orm.create_api_task(row)
if (rsa.verify(resp.sign, JSON.stringify(resp.zhima_credit_watchlistii_get_response), app_id)) {
return resp.zhima_credit_watchlistii_get_response
} else {
error('API-[ alipay/score ] 验签失败| app_id: ', app_id)
throw new Error('验签失败')
}
}
async function access_token(app_id, auth_code,) {
let data = {
app_id: app_id,
method: 'alipay.system.oauth.token',
charset: 'utf-8',
sign_type: 'RSA2',
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
version: '1.0',
grant_type: 'authorization_code',
code: auth_code
}
data.sign = rsa.sign(data, app_id)
let resp = await rp.post({
url: 'https://openapi.alipay.com/gateway.do',
json: true,
form: data
})
console.log('##### Access_token #####\n', resp)
if (resp.error_response) {
return resp.error_response
}
if (rsa.verify(resp.sign, JSON.stringify(resp.alipay_system_oauth_token_response), app_id)) {
console.log('access_token: ', resp)
return resp.alipay_system_oauth_token_response
} else {
error('API-[ alipay/access_token ] 验签失败| app_id: ', app_id)
throw new Error('验签失败')
}
}
// 支付用户账户
async function pay_forName(open_id,parter_name,appKey,cert_name) {
let transaction_id = build_transaction_id()
let data = {
app_id: '2018030502317524',
method: 'alipay.fund.trans.toaccount.transfer',
format: 'JSON',
charset: 'utf-8',
sign_type: 'RSA2',
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
version: '1.0',
biz_content: JSON.stringify({
out_biz_no: transaction_id,
payee_type: 'ALIPAY_USERID',
payee_account: open_id,
amount: '0.1',
payer_show_name: parter_name,
payee_real_name: cert_name
}),
}
await orm.insert_pay_task(transaction_id,appKey,open_id,cert_name);
data.sign = rsa.signpay(data, "2018030502317524")
let p = formatUrl(data)
let resp = await rp.post({
url: p.url,
form: p.execParams,
json: true
})
let row = {
transaction_id: transaction_id,
resp: JSON.stringify(resp),
open_id: open_id,
platform: 'alipay',
method: 'pay'
}
log('pay_forName resp: ', resp)
await orm.create_api_task(row)
return resp.alipay_fund_trans_toaccount_transfer_response;
}
module.exports = {
build_transaction_id,
access_token,
score,
pay_forName
}
function formatUrl(params) {
let requestUrl = 'https://openapi.alipay.com/gateway.do';
// 需要放在 url 中的参数列表
const urlArgs = [
'app_id', 'method', 'format', 'charset',
'sign_type', 'sign', 'timestamp', 'version',
'notify_url', 'return_url', 'auth_token', 'app_auth_token',
];
for (const key in params) {
if (urlArgs.includes(key)) {
const val = encodeURIComponent(params[key]);
requestUrl = `${requestUrl}${requestUrl.includes('?') ? '&' : '?'}${key}=${val}`;
// 删除 postData 中对应的数据
delete params[key];
}
}
return {execParams: params, url: requestUrl};
}
// access_token('2018042460057138','e58ed29be5664ef9b174f9b02776UX48').then(r=>{log(r)}).catch(e=>{log(e)})
\ No newline at end of file
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnv0wNm0RDlJFeOfYO2Ed
IOF1snkiUSqp5pvwX8z6+3kc/kOdhDfwrPUk4LWx+PmCiuSUyEsojBKDCwtK8kzH
4OrA3B4yG+NrjJ1060fRJsaxX+m95+2q0a7LIz2gXuAS4glWrx3i5rSDpOF9R9qw
hNjg3pExn7NZ2n/ro3cUT+Lauzqu0A9GzJ1TwbXt97XN4mx33sfbrT+NaS6UBCMS
3KUgA1kl/AUB34eWEyDbwAei/czMUfa73eeMFGqacXESEJl/qKdulB6XPEDV0Msk
tcqbL+qx8l0jFJyh9OW829l7Pu2lBqFLk/owp9HztuHSX7N9kvO1wPu+dHk/Mgdj
FQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0y38Y65ulJhzPm4BZLZ0UK98Qcmz6munK7kZTLW7il2MvErc
DgmJ2faajxDyMDKh7fDQTcj2ZlvuwrKK9UpLfnSg5444LYSZpFTkySydQe+VPBC/
/MB9bZ/JSVotM4bEjoVdbCrs4bk3A+CjTMkq8V8WlWOBOX7HwLd6kIyfR2QrUO5q
b7v8C1Jl0B81IRkCHNTZ91rpVDzcpJkbTzVTDeC/Ydsc0KQL3FAFe+nl0+pkLyEs
H/Wr1LV0d5v63wE1Dn10CYRQ9n6tsTceNPcd2NRrWTyrczKULxtf8ylds116UCDo
bxDFUx4xr44z4qyjz4omc3zUTe5vZ7lCFSKpsQIDAQABAoIBABk+U/8uaLWGi7AY
wj3huYGzmGzcyY7qE2+cjrOmvaZKjHotkKR062+MlOkpI2ozgzvIH35M2Xde4emQ
IiA0I1YYZuuHCpwWT69fHoIVvS6WjwZBElIKSHQEN7F3ABQ6teA7fPFjKDHLTBJA
lgSlv2Ze8XomDNpsl0AoLpR82sVTsmr3wjCOPxrF/b6waXZKf7GU7wo3erziJ8gr
2qLZzxgjNaMWYIAeqFiaSp0orTLDMR06oPqOlp/vxMvIUpOlPFnvfnha2FGWAmJj
QRrENSagKO2/lLo+mvZM8GG7yuLSfH4+obMf5805j2EKdTGBHSkgAhS1J6nLIJVe
Gy4axIECgYEA6kBzkGenbCXHgeB1+PpHcgwjZsMFqDBgV6bRH2J+msGTgLviBwhj
n6qMuYJdsv2eOSHUEAtcZNVn9fsZrbg8giaGF65cFmpQZKuDE1AqfdvHePM0W8Nn
uaUzz1UjGSqhMl2N/GHoKfBMCrljnvwwJ4lbphwhzMl4yiJaWmE5U8kCgYEA5skr
quZG5b3FK85CS0qR10z/EqLElxJRF9X9vuyiQ+aIRMg4GhRajMQTDo7YIXh/rD9O
myjO1KwXa62vhB3zjy7ytQyfFuoWPDMSf6860W+Tuc2a9HSJQxQzjUMbv+gLlJYf
orrSoiVoMK4VdsW7mQXl+2IqEMRaHktcZ1YgiqkCgYEA38WT37V09NWeIQ5YA/Cq
AWNhChBwvfsAfZrImE+Rm6ohis9wGsHD0UmtxqSnd43Y8MDFAFKp/1TxS8SEAjRF
8Rp16/dO1sbWZ2SEARYKkVI62eqR8LrYwjnzJTMyJR9Y/3DpatfoXO/E5FW2ubA1
G/+WAjdLfoJTldx9LWtExSkCgYA3RAlu/YIQ1ib3XIdHnG3cTxXuEohdXQeKW7ZO
GECrXfNX9VJp/GHKv9GIdPCQ41g/mVFrmpQdHbDmGkujqcB/k1CPxpv6UshMVjah
2QaOzNdlcTUgQR/1rkrCE0X76MeNJ34f6/kw1yBiN+3v6V4JQP5X+qP0K/EgvA8+
t8NHMQKBgAcoUbBKOa5njQ9tppJK3zML2Z/miJIaXwaX/9A7Wtpdqwa/0tSa7sBQ
2lYRqMV54t1/L0DqSeYzN59yOUwmX6DBsThiwx0Vg5z8WI5aVYT+690MnL0VtHLj
jlhcBNqMxRXjH7M1Fyq+i3NjBkRutthMGO66ZEjH+BKJJ7CU2DyC
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3FVEfUyu1O1th+9JeYO
6zvuxl0OVscCi9Rx9QiPYyJAugCzQYBguk+tqkNgYI00NIz/y99NsulyjCGkLnlZ
lSolKrefjKVSSWxiNcy3yA0loLDUturIxg2kR13uSzm46fPIX3fxRc37n3Y7hIio
pE+3NCUAJGnIkQFStlvVKUoh65zkf7+sygS8l6u338THsLEcq0WBABx36NrGqxP9
Olus12Jvc9MGhrgPo4Dj0OUd8IbamHDUYPDPF2oc0a5huMKNjeTeJuJEK42k5DUj
Gdn4ZLS2AQowimKt5qwKjMC2sFcqRH1hTZD9mthuNE0PXfj61Nw5KKItob5Que53
EQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsw0WUygOnvIYW6bIJaK4
WzNBwF7NhIqTTk7dew/Of2PQto+iEmv2o1Tyc53gLjvMXSbG46nxsEvyXH19OPb+
A74j4LCnQl4Mg8yph2689rJnHWmdmqvw+8A6/XcCq7rjN2LlQhu5ibya3Gi41+uy
PPUPuc2B1tL0JTydxIt8bGg3wCLXmdpHxJJ8aegBRd1+3NkfEy+53/maBujmjni/
HqJ/nsFoqJ2CjRv0Oo6hSKHi50k5wc85u4+Mp0PY0FHP8PJ6qw6vUjakiWBs16vH
0uA+/JEgAftMbpvFOuM70/5blUFg6KnMPnynbD4jIwMYpsNVJSCJOmjUERZZF2n3
ewIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0y38Y65ulJhzPm4BZLZ0UK98Qcmz6munK7kZTLW7il2MvErc
DgmJ2faajxDyMDKh7fDQTcj2ZlvuwrKK9UpLfnSg5444LYSZpFTkySydQe+VPBC/
/MB9bZ/JSVotM4bEjoVdbCrs4bk3A+CjTMkq8V8WlWOBOX7HwLd6kIyfR2QrUO5q
b7v8C1Jl0B81IRkCHNTZ91rpVDzcpJkbTzVTDeC/Ydsc0KQL3FAFe+nl0+pkLyEs
H/Wr1LV0d5v63wE1Dn10CYRQ9n6tsTceNPcd2NRrWTyrczKULxtf8ylds116UCDo
bxDFUx4xr44z4qyjz4omc3zUTe5vZ7lCFSKpsQIDAQABAoIBABk+U/8uaLWGi7AY
wj3huYGzmGzcyY7qE2+cjrOmvaZKjHotkKR062+MlOkpI2ozgzvIH35M2Xde4emQ
IiA0I1YYZuuHCpwWT69fHoIVvS6WjwZBElIKSHQEN7F3ABQ6teA7fPFjKDHLTBJA
lgSlv2Ze8XomDNpsl0AoLpR82sVTsmr3wjCOPxrF/b6waXZKf7GU7wo3erziJ8gr
2qLZzxgjNaMWYIAeqFiaSp0orTLDMR06oPqOlp/vxMvIUpOlPFnvfnha2FGWAmJj
QRrENSagKO2/lLo+mvZM8GG7yuLSfH4+obMf5805j2EKdTGBHSkgAhS1J6nLIJVe
Gy4axIECgYEA6kBzkGenbCXHgeB1+PpHcgwjZsMFqDBgV6bRH2J+msGTgLviBwhj
n6qMuYJdsv2eOSHUEAtcZNVn9fsZrbg8giaGF65cFmpQZKuDE1AqfdvHePM0W8Nn
uaUzz1UjGSqhMl2N/GHoKfBMCrljnvwwJ4lbphwhzMl4yiJaWmE5U8kCgYEA5skr
quZG5b3FK85CS0qR10z/EqLElxJRF9X9vuyiQ+aIRMg4GhRajMQTDo7YIXh/rD9O
myjO1KwXa62vhB3zjy7ytQyfFuoWPDMSf6860W+Tuc2a9HSJQxQzjUMbv+gLlJYf
orrSoiVoMK4VdsW7mQXl+2IqEMRaHktcZ1YgiqkCgYEA38WT37V09NWeIQ5YA/Cq
AWNhChBwvfsAfZrImE+Rm6ohis9wGsHD0UmtxqSnd43Y8MDFAFKp/1TxS8SEAjRF
8Rp16/dO1sbWZ2SEARYKkVI62eqR8LrYwjnzJTMyJR9Y/3DpatfoXO/E5FW2ubA1
G/+WAjdLfoJTldx9LWtExSkCgYA3RAlu/YIQ1ib3XIdHnG3cTxXuEohdXQeKW7ZO
GECrXfNX9VJp/GHKv9GIdPCQ41g/mVFrmpQdHbDmGkujqcB/k1CPxpv6UshMVjah
2QaOzNdlcTUgQR/1rkrCE0X76MeNJ34f6/kw1yBiN+3v6V4JQP5X+qP0K/EgvA8+
t8NHMQKBgAcoUbBKOa5njQ9tppJK3zML2Z/miJIaXwaX/9A7Wtpdqwa/0tSa7sBQ
2lYRqMV54t1/L0DqSeYzN59yOUwmX6DBsThiwx0Vg5z8WI5aVYT+690MnL0VtHLj
jlhcBNqMxRXjH7M1Fyq+i3NjBkRutthMGO66ZEjH+BKJJ7CU2DyC
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuV742wnO6btJsiQ53AF1rY8HMDaUPhpoTpjGIyKvPbE3PF1c
rYsjmFyQCrdLePcXSS9YCIXi9QDElvkNsIF7+YB7MHcS1ejlw8k3/PeewRzRQGPG
I4rda86cWB1qNj6g9Eq/GnHnKSMc7rEoB1LHdeBCO+XtR0YmkYZYoXVJ5T+iLgR3
zfLhXuICZaodSuTdSFA9R623OnSxoanYc/yQR7sVEXHJRI7gkMIlKU1IYzUDvIUM
BUB+1nY/gPApowxWe7Yq5ARz27UxtaJ3WWlPWSnLbgv2Hlg/0Zs1MaNxptHxL4fw
1aV8vm9RX0zaCgPQsoDdTo8fO2/7yYvBnT9tqwIDAQABAoIBAF9dkMF/RkfQ5pUT
NgENbzEfCB+xtIpOo6LrzeN9kJI4faY8kdVmY6Wa2S/qJJXS6NPp22xnFN/eyUSy
VGyd8N3nT3kbiUErVClpd7hY2/+Vh8GMkv7uDgPMg3qBh4boqX2EhtRgDQCI4/WY
hnNeDueBvBF8tJmaaXUsnKRT5vRc7C9aF6lJVTAcdZ+ZtNtPPMwyugLp9XFdcaTR
wBoz1ma+1BkYnheV0WWru0S+YQJGquZ1DHKV+VAVPVWZZg/y5wBQmv3nD4eU+grx
V2pLQnesWhLvWdZvoBSqxc+LvknOcccIZLYjF9GKkJYiSh6YO9jJ45VgbhGcDVtD
+g+aOYECgYEA3gqSOIrt/ZXahbukoUr2WnX+hIo0fZrIWslYuhBPR7nWcfA9Yo5i
fpd9VwzIePghkmhs0bRYIyK+3RII4rxvIUJsq7YkMlGa14/aIMV9FJQq22brOAjB
/tW5qiUNjx/jk7pmMy2EVOC0iaIuoEzkDzCmQEiKGn6Kz1YsxjuCGbECgYEA1bis
eflr+0/lVh9Z2jv5oEk6A+WQXYccek0wvGGkeJzLzWB2dwzDQpLZGeomjf5RktHN
T128gLWE7Uy+y2aXcgC1Uf97vxMS5hltFbUZLGGwx2V7F2SSWOJJZPImj1vMWjJU
KMHbA3IybVksriz+gtfpxA5m6NdsdJZ4XMFoOBsCgYB7PjLa34IpdrvL7tL6E7mZ
jFSxDGUGMptyiL+Oxu66SRQWOdpYkd9plHwljRrYyiEYOo3r98XT+r0lx5TXBPBJ
7ayTwo1kwJbJfzb7aaJ7gaIoFYAJohLLd6WOIvLbtj+DB7siPOlukyqiGjr3Dran
F8GvfJPrEMHLQ3GmtfEIgQKBgQDBk+OlFyWXG2a9+ueHo4sWgzzpCqUYEajZndDm
0AoItPxjqVujuQui4R+DOXJyake4lA9CM8TpT4B272xhDytdNwcEnkOXbc9QWvdT
EhUa/eEAugojxhRILa4MoMgMUTlm+O8Be5TEKktCf+LYYCimmqpBykmr3HN/pkqe
uQ+MwQKBgQDa0xQX7Db7ndmwQDpGrFK5p1IN29H8m/c/TDsI7e/4ruOeaLHaKifa
fL6v/axQnLvIW8ksUw45mBONaHsdAkaka5bF25zTIx9baHnfrcMr8Fy030vs/1Td
uMisDrGmxEbDlZnFeUUDW7VM9/zIEc/D5vZAZQnRXdFbQA4ta0zRHQ==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnv0wNm0RDlJFeOfYO2Ed
IOF1snkiUSqp5pvwX8z6+3kc/kOdhDfwrPUk4LWx+PmCiuSUyEsojBKDCwtK8kzH
4OrA3B4yG+NrjJ1060fRJsaxX+m95+2q0a7LIz2gXuAS4glWrx3i5rSDpOF9R9qw
hNjg3pExn7NZ2n/ro3cUT+Lauzqu0A9GzJ1TwbXt97XN4mx33sfbrT+NaS6UBCMS
3KUgA1kl/AUB34eWEyDbwAei/czMUfa73eeMFGqacXESEJl/qKdulB6XPEDV0Msk
tcqbL+qx8l0jFJyh9OW829l7Pu2lBqFLk/owp9HztuHSX7N9kvO1wPu+dHk/Mgdj
FQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PUBLIC KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0y38Y65ulJhzPm4BZLZ0
UK98Qcmz6munK7kZTLW7il2MvErcDgmJ2faajxDyMDKh7fDQTcj2ZlvuwrKK9UpL
fnSg5444LYSZpFTkySydQe+VPBC//MB9bZ/JSVotM4bEjoVdbCrs4bk3A+CjTMkq
8V8WlWOBOX7HwLd6kIyfR2QrUO5qb7v8C1Jl0B81IRkCHNTZ91rpVDzcpJkbTzVT
DeC/Ydsc0KQL3FAFe+nl0+pkLyEsH/Wr1LV0d5v63wE1Dn10CYRQ9n6tsTceNPcd
2NRrWTyrczKULxtf8ylds116UCDobxDFUx4xr44z4qyjz4omc3zUTe5vZ7lCFSKp
sQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0y38Y65ulJhzPm4BZLZ0UK98Qcmz6munK7kZTLW7il2MvErc
DgmJ2faajxDyMDKh7fDQTcj2ZlvuwrKK9UpLfnSg5444LYSZpFTkySydQe+VPBC/
/MB9bZ/JSVotM4bEjoVdbCrs4bk3A+CjTMkq8V8WlWOBOX7HwLd6kIyfR2QrUO5q
b7v8C1Jl0B81IRkCHNTZ91rpVDzcpJkbTzVTDeC/Ydsc0KQL3FAFe+nl0+pkLyEs
H/Wr1LV0d5v63wE1Dn10CYRQ9n6tsTceNPcd2NRrWTyrczKULxtf8ylds116UCDo
bxDFUx4xr44z4qyjz4omc3zUTe5vZ7lCFSKpsQIDAQABAoIBABk+U/8uaLWGi7AY
wj3huYGzmGzcyY7qE2+cjrOmvaZKjHotkKR062+MlOkpI2ozgzvIH35M2Xde4emQ
IiA0I1YYZuuHCpwWT69fHoIVvS6WjwZBElIKSHQEN7F3ABQ6teA7fPFjKDHLTBJA
lgSlv2Ze8XomDNpsl0AoLpR82sVTsmr3wjCOPxrF/b6waXZKf7GU7wo3erziJ8gr
2qLZzxgjNaMWYIAeqFiaSp0orTLDMR06oPqOlp/vxMvIUpOlPFnvfnha2FGWAmJj
QRrENSagKO2/lLo+mvZM8GG7yuLSfH4+obMf5805j2EKdTGBHSkgAhS1J6nLIJVe
Gy4axIECgYEA6kBzkGenbCXHgeB1+PpHcgwjZsMFqDBgV6bRH2J+msGTgLviBwhj
n6qMuYJdsv2eOSHUEAtcZNVn9fsZrbg8giaGF65cFmpQZKuDE1AqfdvHePM0W8Nn
uaUzz1UjGSqhMl2N/GHoKfBMCrljnvwwJ4lbphwhzMl4yiJaWmE5U8kCgYEA5skr
quZG5b3FK85CS0qR10z/EqLElxJRF9X9vuyiQ+aIRMg4GhRajMQTDo7YIXh/rD9O
myjO1KwXa62vhB3zjy7ytQyfFuoWPDMSf6860W+Tuc2a9HSJQxQzjUMbv+gLlJYf
orrSoiVoMK4VdsW7mQXl+2IqEMRaHktcZ1YgiqkCgYEA38WT37V09NWeIQ5YA/Cq
AWNhChBwvfsAfZrImE+Rm6ohis9wGsHD0UmtxqSnd43Y8MDFAFKp/1TxS8SEAjRF
8Rp16/dO1sbWZ2SEARYKkVI62eqR8LrYwjnzJTMyJR9Y/3DpatfoXO/E5FW2ubA1
G/+WAjdLfoJTldx9LWtExSkCgYA3RAlu/YIQ1ib3XIdHnG3cTxXuEohdXQeKW7ZO
GECrXfNX9VJp/GHKv9GIdPCQ41g/mVFrmpQdHbDmGkujqcB/k1CPxpv6UshMVjah
2QaOzNdlcTUgQR/1rkrCE0X76MeNJ34f6/kw1yBiN+3v6V4JQP5X+qP0K/EgvA8+
t8NHMQKBgAcoUbBKOa5njQ9tppJK3zML2Z/miJIaXwaX/9A7Wtpdqwa/0tSa7sBQ
2lYRqMV54t1/L0DqSeYzN59yOUwmX6DBsThiwx0Vg5z8WI5aVYT+690MnL0VtHLj
jlhcBNqMxRXjH7M1Fyq+i3NjBkRutthMGO66ZEjH+BKJJ7CU2DyC
-----END RSA PRIVATE KEY-----
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const NodeRSA = require('node-rsa');
// def sign(privatekey, data):
// '''
// 加签
// :param privatekey:私钥文件路径
// :param data:要加签的数据
// :return string:签名
// '''
// signEVP = EVP.load_key(privatekey)
// signEVP.sign_init()
// signEVP.sign_update(data)
// result = signEVP.sign_final()
// return base64.b64encode(result)
const private_key = fs.readFileSync(path.join(__dirname, 'keys/private_key.pem')).toString()
const private_pay_key = fs.readFileSync(path.join(__dirname, 'keys/private_pay_key.pem')).toString()
const ant_public_key = {}
ant_public_key['2018042460057138'] = fs.readFileSync(path.join(__dirname, 'keys/2018042460057138_ant_public_key.pem')).toString()
ant_public_key['2018051160085345'] = fs.readFileSync(path.join(__dirname, 'keys/2018051160085345_ant_public_key.pem')).toString()
ant_public_key['2018051560161652'] = fs.readFileSync(path.join(__dirname, 'keys/2018051560161652_ant_public_key.pem')).toString()
//params= URLEncode(Base64(RSAEncrypt(param1=URLEncode(param1value)&param2=URLEncode(param2value))))
// 加签
// :param privatekey:私钥文件路径
// :param data:要加签的数据
// :return string:签名
function RSAEncrypt(data) {
let str = params2str(data)
let key = new NodeRSA(private_key)
key.setOptions({encryptionScheme: 'pkcs1'});
let encrypted = key.encrypt(str, 'base64')
return encrypted
}
function RSADecrypt(str) {
let key = new NodeRSA(private_key)
key.setOptions({encryptionScheme: 'pkcs1'});
let encrypted = key.decrypt(str, 'utf8')
return encrypted
}
// 转换业务参数为str
function params2str(data) {
let str = ''
for (let k of Object.keys(data).sort()) {
let v = data[k]
if (Object.prototype.toString.call(v) === '[object Object]') {
v = JSON.stringify(v)
}
str += k + '=' + v + '&'
}
return str.slice(0, str.length - 1)
}
// str 转为 json
function str2params(str) {
let ret = {}
let arr = str.split('&')
for (let item of arr) {
let index = item.indexOf('=')
ret[item.slice(0, index)] = decodeURIComponent(item.slice(index + 1))
}
return ret
}
// 加签
function sign(data) {
let str = params2str(data)
let sign = crypto.createSign('RSA-SHA256')
sign.update(str)
return sign.sign(private_key, 'base64')
}
// 加签
function signpay(data) {
let str = params2str(data)
let sign = crypto.createSign('RSA-SHA256')
sign.update(str)
return sign.sign(private_pay_key, 'base64')
}
// 验签
// sign_value: 签名,
// str: 待验签的数据
function verify(sign_value, str, app_id) {
var verify = crypto.createVerify('RSA-SHA256');
verify.update(str);
return verify.verify(ant_public_key[app_id], sign_value, 'base64')
}
// let resp = { alipay_system_oauth_token_response:
// { access_token: 'authzmaBd3a9fe8c041843cdbd01cb6ba1c4fX48',
// alipay_user_id: '20881049053508330572421081610248',
// expires_in: 31536000,
// re_expires_in: 31622400,
// refresh_token: 'authzmaB6991f8567e38405c85803d5023550X48',
// user_id: '2088802182470482' },
// sign: 'LriQN3gcY177GL1SPqGqsnD1YuJdR9qKg4fSaS8V3KNXF/Fi2I0eDSK0t8o0lAHB3AgHF6YyD7+VwtO/pKc9yZpbTIVSrCm2kFaEJGaJgG7F7sh+CNEZnNE69usW50Y7LQUGPy8olr2+LnE6eyM4xR9KlYDTCP4RA+K0OlFSKz8V0ylwgC0H9nij+le3pyQZdESarLGMuZk24+a49lYgZfjsnI6rf2DkrCN1/0RNNuIGqS2XtXBuQCY15gzBIyY9ux65YIvEoc+LUKTyNOpXvBeQYP9JzkQqc7Nkh1f6lozcrNtoxdP8ltZU/dW3/2TpIQ4oQ1J2ztezmamZvTxjDg==' }
// if (verify(resp.sign, JSON.stringify(resp.alipay_system_oauth_token_response), '2018051560161652')) {
// console.log('success')
// } else {
// console.log('error')
// }
// let a = {
// apiname: 'com.alipay.account.auth',
// method: 'alipay.open.auth.sdk.code.get',
// app_id: 2018042460057138,
// app_name: 'mc',
// biz_type: 'openservice',
// pid: 2088031974398640,
// product_id: 'APP_FAST_LOGIN',
// scope: 'kuaijie',
// target_id: 'kkkkk091125',
// auth_type: 'AUTHACCOUNT',
// sign_type: 'RSA2',
// }
// a.sign = encodeURIComponent(sign(a))
// console.log(sign('app_id=2018042460057138&amp;charset=utf-8&amp;code=1558df8e1bd2409dafeb9f428075SX48&amp;format=JSON&amp;grant_type=authorization_code&amp;method=alipay.system.oauth.token&amp;sign_type=RSA2&amp;timestamp=2018-05-03 16:40:45&amp;version=1.0'));
module.exports = {
signpay,
sign,
verify,
RSAEncrypt,
RSADecrypt,
params2str,
str2params
}
This diff is collapsed.
This diff is collapsed.
const OSS = require('ali-oss')
const co = require('co')
const crypto = require('crypto')
const fs = require('fs')
const config = require('config')
const client = new OSS({
bucket: '51query',
accessKeyId: 'LTAI6Glaum6TDzKf',
accessKeySecret: 'zmNjWhmOD1nIClZ3hoDmGrdNNiBJBi',
secure: true,
region: "oss-cn-hangzhou"
})
function upload_image(key, data) {
return co(function*() {
// use 'chunked encoding'
//var stream = fs.createReadStream('./exp.js');
data = data.replace(/^data:image\/\S+?;base64,/,"");
var result = yield client.put(key, new Buffer(data, 'base64'));
console.log('upload_image: ', result);
return result
}).catch(function (err) {
console.log('upload_image error: ', err);
});
}
function upload(key, data) {
return co(function*() {
// use 'chunked encoding'
//var stream = fs.createReadStream('./exp.js');
var result = yield client.put(key, new Buffer(data));
console.log('upload: ', result);
return result
}).catch(function (err) {
console.log('upload error: ', err);
});
}
const getUploadSign = (dirPath, fileName) => {
const {AccessKeyId, Host, AccessKeySecret} = config.oss
let callback = {
"callbackUrl": `${config.host}/kqyx/oss/callback`,
"callbackBody": "filename=${object}&size=${size}&mimeType=${mimeType}",
"callbackBodyType": "application/x-www-form-urlencoded"
}
callback = JSON.stringify(callback)
const callbackbody = new Buffer(callback).toString('base64')
const end = new Date().getTime() + 300000
const expiration = new Date(end).toISOString()
let policyString = {
expiration,
conditions: [
// 1024*1024 1mb限制
['content-length-range', 0, 1048576],
['starts-with', '$key', 'kqyx']
]
}
policyString = JSON.stringify(policyString)
const policy = new Buffer(policyString).toString('base64')
const signature = crypto.createHmac('sha1', AccessKeySecret).update(policy).digest('base64')
return {
AccessKeyId,
host: Host,
policy,
signature,
fileName,
dirPath,
callbackbody
}
}
const signed_url = (name) => {
return client.signatureUrl(name)
}
const deleteFile = (key) => {
co(function*() {
return yield client.delete(key)
}).catch(function (err) {
console.log(err)
throw err
})
}
module.exports = {
upload_image,
signed_url,
deleteFile,
upload
}
\ No newline at end of file
/**
* Created by xaj on 2017/5/26.
*/
var rp = require('request-promise');
var request = require('request');
var config = require('config')
var tj1 = config.get('tj1');
var tj2 = config.get('tj2');
/*************************************************************************************
* Description: getToken
* Author: xaj
* Date: 2017/6/05
* Parameter: body Obeject 传进来的参数
* Callback: promise
* Return: N/A
* Caution:
*************************************************************************************/
function getToken(body) {
return new Promise((resolve, reject) => {
let form_data = body
let reqUrl = tj2 + "access/getToken";
let options= {
url: reqUrl,
method: "POST",
json: true,
body: form_data,
headers: {
'content-type': 'application/json'
}
}
request(options,(e,r,b)=>{
if(e){
console.error('[getToken] error: ' + JSON.stringify(e));
reject(e);
}else{
console.log('[getToken] success result: ' + JSON.stringify(b));
resolve(b);
}
})
})
}
/*************************************************************************************
* Description: getOrderSn
* Author: xaj
* Date: 2017/6/05
* Parameter: body Object 传进来的参数
* Callback: promise
* Return: N/A
* Caution:
*************************************************************************************/
function getOrderSn(body) {
return new Promise((resolve, reject) => {
let form_data = body;
let reqUrl = tj2 + "order/getOrderSn";
let options= {
url: reqUrl,
method: "POST",
json: true,
body: form_data,
headers: {
'content-type': 'application/json'
}
}
request(options,(e,r,b)=>{
if(e){
console.error('[getOrderSn] error: ' + JSON.stringify(e));
reject(e);
}else{
console.log('[getOrderSn] success result: ' + JSON.stringify(b));
resolve(b);
}
})
})
}
/*************************************************************************************
* Description: 检查签名是否失效
* Author: xaj
* Date: 2017/5/27
* Parameter: body, Object 传进来的参数
* Callback: promise
* Return: N/A
* Caution:
*************************************************************************************/
function signValidityCheck(body) {
return new Promise((resolve, reject) => {
let form_data = body;
let url = tj2 + "access/signValidityCheck";
let options= {
url: url,
method: "POST",
json: true,
body: form_data,
headers: {
'content-type': 'application/json'
}
}
request(options,(e,r,vb)=>{
if(e) {
console.error('[signValidityCheck] signValidityCheck error: ' + JSON.stringify(e));
reject("服务器维护")
}
else {
console.log('[signValidityCheck] signValidityCheck success: ' + JSON.stringify(vb));
resolve(vb);
}
})
})
}
async function app_key_info(app_key) {
try {
let resp = await rp.get({
url: tj2 + 'customer/query/?appKey=' + app_key,
json: true
})
if (resp.code == 0) {
if (resp.data.customerList.length > 0) {
return resp.data.customerList[0]
} else {
throw new Error('无效的appKey')
}
} else {
throw new Error('API-[app_key_info] error ', resp)
}
} catch (e) {
throw e
}
}
// app_key_info('122818D0E79CCEB3B8D3D6BB51BF615E').then(r=>{console.log(r)}).catch(e=>{console.log(e)})
exports.getToken = getToken;
exports.app_key_info = app_key_info;
exports.getOrderSn = getOrderSn;
exports.signValidityCheck = signValidityCheck;
/**
* Created by xaj on 2017/6/6.
*/
const schedule = require('node-schedule');
const fs = require('fs');
const path = require('path');
const moment = require('moment');
const config = require('config');
const basic = require('../middlewares/_pub').basic;
const process = require('child_process');
/*每分钟的第30秒触发: '30 * * * * *'
每小时的1分30秒触发 :'30 1 * * * *'
每天的凌晨1点1分30秒触发 :'30 1 1 * * *'
每月的1日1点1分30秒触发 :'30 1 1 1 * *'
2016年的1月1日1点1分30秒触发 :'30 1 1 1 1 2016'
每周1的1点1分30秒触发 :'30 1 1 * * 1'*/
function BeginCleanLogWork(timeInterval){
schedule.scheduleJob(timeInterval, cleanLogJob);
}
function BeginCleanPm2LogWork(){
schedule.scheduleJob('00 00 00 1 * *', cleanPm2LogJob);
}
function cleanLogJob() {
console.log('[cleanLogJob] BeginDayWork:' + new Date());
let servicName = config.get('log4jsName');
let dateMoment = moment(new Date()).subtract(3, 'days').format('YYYYMMDD');
let fileName = basic.getLocalIP('eth', 'IPv4') + '-' + servicName + '-' + dateMoment + '.log';
let filePath = path.join('./logs/' + fileName);
console.log(fileName)
console.log(filePath)
if (fs.existsSync(filePath)) {
fs.unlink(filePath, function (err) {
if (err) {
console.error('[cleanLogJob] 清除3天前日志失败,原因:' + JSON.stringify(err));
}
else {
console.log('[cleanLogJob] 清除3天前日志成功,被清除日志:' + fileName);
}
})
}
else {
console.error('[cleanLogJob] 日志文件: %s 不存在', filePath);
}
}
function cleanPm2LogJob() {
process.exec('pm2 flush', function (error, stdout, stderr) {
if (error) {
console.log('[cleanPm2LogJob] exec error: ' + error);
}
else {
console.log(stdout);
console.log(stderr);
}
});
}
// BeginCleanLogWork();
module.exports = {
"BeginCleanLogWork": BeginCleanLogWork,
"BeginCleanPm2LogWork": BeginCleanPm2LogWork
};
const moment = require('moment')
const orm = require('./orm')
function test_month(str) {
let a = which_month()
let b = which_month(str)
if (a == b) {
return true
} else {
return false
}
}
function which_month(str = null) {
let today = moment()
if (str) {
today = moment(str)
}
let day = today.get('date')
if (day > 6) {
return today.format('YYYY-MM')
} else {
return today.subtract(1, 'month').format('YYYY-MM')
}
}
async function test_order_id(order_id) {
try {
if (!order_id) {
throw new Error('无效的订单号')
}
let ret = true
let t = order_id.slice(0, 17)
let append = order_id.slice(17)
if (/[^0-9a-zA-Z_-]/.test(append) || order_id.length != 32 || /[^\d]/.test(t)) {
throw new Error('无效的订单号')
}
return await orm.check_order_id(order_id)
} catch (e) {
throw e
}
}
function to_base64(str) {
return new Buffer(str).toString('base64')
}
function from_base64(base64) {
return new Buffer(base64, 'base64').toString()
}
// 加权随机
function load_balance(items) {
let list = []
for (let item of items) {
for (let i = 0; i < item.weight; i++) {
list.push(item.app_id)
}
}
let randint = getRandomInt(0, list.length)
return list[randint]
}
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}
module.exports = {
test_order_id,
test_month,
which_month,
to_base64,
from_base64,
load_balance
}
\ No newline at end of file
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCir0A1PyJ+v56i21m/hjECVtM43oq7Uj8SC1lDhJqeOWMCZEQc
ChHYpnRkhyrypVRhNKXq7edq5Cp1f5/q4mPrw5GcyX68VPBTeRml7wtp/0oYoW1c
9wEqbgPWsHelVdb+2VN3V6Hryot7ovz01jkndPK+T4R2LdwbaK2hUnKdFwIDAQAB
AoGAJlbw5duUMJTOOQlC1G02nZuCufNQdKcEcCc2iT/2BHX3zHd+ybDh1dIcuhhU
2cx231W+CGi60ikljH1gXcWu0GAbGMSyvC4sTs+sDNpzp2peYtZ67bSNp7rd6sNA
v8zZgC66zpNQVuD0WQNxHAISQNUNNaxDGz+AYRIBM4VKy7kCQQDOnWsEHKdr12f5
1GgiownfoC53U+oRiyuoxFx+YS7iR9QCAPRHx8822LgThMA1qvINKfDwtocpK+UO
imi2MyHNAkEAyZHGRPO+ij9XRIw5IfFNpGpt40MQv4PQYpmI/of7zbBVUaEFvJ0y
DZ6s9KhU7cHblKsruUHu6KZS/Lu37k4mcwJAQNf2thuoD5hS8X1QEU7J0n0bGCgl
1cuvsA+wV5l4dVvFlbtm7wAucDAj1Txcdntn6+m1zFX8pVc5VA7sPgJeIQJAG1SO
o47BCRGpjXvNy1JiiqZ7m9LeFHmU6amTr59UfwEnsFe65WYTAVHAdbPVQB+G3FOR
LB9Ke3UBz47MU515DQJAMeAIdlp71W1TKNhLv5pLQtfSmFzMQWvhXZuLnysvqFfg
IJpsio6hJcr9sJI72s6kBPaVyVvwCYOlreXq2SM2uw==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyDAB5cXvXum9x9z3S6akLTxnZ
curc0hpldpWdlB315gOUbKvjJKvpaocWiVMHMcv6UZ2Ml7TVXXmEd/7e7iG1wIJm
ocNaC86wpOyLqlsg7P22weuy3dq8SyOcZ8PQkn346VahJ7OUoPNc/8Y23tNJXdO/
+lpl98nzOe0ABdanIQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyDAB5cXvXum9x9z3S6akLTxnZ
curc0hpldpWdlB315gOUbKvjJKvpaocWiVMHMcv6UZ2Ml7TVXXmEd/7e7iG1wIJm
ocNaC86wpOyLqlsg7P22weuy3dq8SyOcZ8PQkn346VahJ7OUoPNc/8Y23tNJXdO/
+lpl98nzOe0ABdanIQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCir0A1PyJ+v56i21m/hjECVtM43oq7Uj8SC1lDhJqeOWMCZEQc
ChHYpnRkhyrypVRhNKXq7edq5Cp1f5/q4mPrw5GcyX68VPBTeRml7wtp/0oYoW1c
9wEqbgPWsHelVdb+2VN3V6Hryot7ovz01jkndPK+T4R2LdwbaK2hUnKdFwIDAQAB
AoGAJlbw5duUMJTOOQlC1G02nZuCufNQdKcEcCc2iT/2BHX3zHd+ybDh1dIcuhhU
2cx231W+CGi60ikljH1gXcWu0GAbGMSyvC4sTs+sDNpzp2peYtZ67bSNp7rd6sNA
v8zZgC66zpNQVuD0WQNxHAISQNUNNaxDGz+AYRIBM4VKy7kCQQDOnWsEHKdr12f5
1GgiownfoC53U+oRiyuoxFx+YS7iR9QCAPRHx8822LgThMA1qvINKfDwtocpK+UO
imi2MyHNAkEAyZHGRPO+ij9XRIw5IfFNpGpt40MQv4PQYpmI/of7zbBVUaEFvJ0y
DZ6s9KhU7cHblKsruUHu6KZS/Lu37k4mcwJAQNf2thuoD5hS8X1QEU7J0n0bGCgl
1cuvsA+wV5l4dVvFlbtm7wAucDAj1Txcdntn6+m1zFX8pVc5VA7sPgJeIQJAG1SO
o47BCRGpjXvNy1JiiqZ7m9LeFHmU6amTr59UfwEnsFe65WYTAVHAdbPVQB+G3FOR
LB9Ke3UBz47MU515DQJAMeAIdlp71W1TKNhLv5pLQtfSmFzMQWvhXZuLnysvqFfg
IJpsio6hJcr9sJI72s6kBPaVyVvwCYOlreXq2SM2uw==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCir0A1PyJ+v56i21m/hjECVtM4
3oq7Uj8SC1lDhJqeOWMCZEQcChHYpnRkhyrypVRhNKXq7edq5Cp1f5/q4mPrw5Gc
yX68VPBTeRml7wtp/0oYoW1c9wEqbgPWsHelVdb+2VN3V6Hryot7ovz01jkndPK+
T4R2LdwbaK2hUnKdFwIDAQAB
-----END PUBLIC KEY-----
tt.51gjj.com:5000/redirect?params=JevbQqScHiM1Qoryf1%2FD4MIrl7mvWRtt8neRUzLelEdru%2FRUt8N%2FQOs3qWgdOqUXVNXZnUL87Bc0uFFm4dxAwRRNxr0ek4kFPBoDwuk063AS3vFz%2Bsm0wy808hX6s63MnXfCbGqq1tpvkVb4mFp1jDFXJJgZjOoJ%2FBhTLfQWI%2BSE4YjWcvm3%2BV9enCv8TrYZ3jPhmf%2F3KeX%2BuZB3HhWmnqQHv6nu9Wbh%2Fqf2sevtvWzV08F6eT8JcDhF%2FK%2F1aZvSVgr83%2BuzRbO%2BCUa7KY0GWNc5moFfhT45TeR2PslcTDde36sUumlLdEQxR2qXXf7TPL2z0Y0bWKE7JMpbx%2BqnPg%3D%3D&sign=HOg8UcgLT4zFTq5J7sTy9N7XHjS%2Fg8NfMnYoR4ip9UdPPScHXiqnuIDZ44zQT9NU5X6z3XoeGt04YFfeDS3DXGaD1YhyTvWwCigAMPnu7YlSG1ZeAputY0xD8sCkN7Dv20GQE42%2BU%2BSOQk8wzcsHJ87KwQUkXF9oTQviaIS0fk0%3D
\ No newline at end of file
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyDAB5cXvXum9x9z3S6akLTxnZ
curc0hpldpWdlB315gOUbKvjJKvpaocWiVMHMcv6UZ2Ml7TVXXmEd/7e7iG1wIJm
ocNaC86wpOyLqlsg7P22weuy3dq8SyOcZ8PQkn346VahJ7OUoPNc/8Y23tNJXdO/
+lpl98nzOe0ABdanIQIDAQAB
-----END PUBLIC KEY-----
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const NodeRSA = require('node-rsa');
// def sign(privatekey, data):
// '''
// 加签
// :param privatekey:私钥文件路径
// :param data:要加签的数据
// :return string:签名
// '''
// signEVP = EVP.load_key(privatekey)
// signEVP.sign_init()
// signEVP.sign_update(data)
// result = signEVP.sign_final()
// return base64.b64encode(result)
const private_key = fs.readFileSync(path.join(__dirname, 'keys/rsa_private_key.pem')).toString()
const zmop_public_key = fs.readFileSync(path.join(__dirname, 'keys/zmop_public_key.pem')).toString()
//params= URLEncode(Base64(RSAEncrypt(param1=URLEncode(param1value)&param2=URLEncode(param2value))))
// 加签
// :param privatekey:私钥文件路径
// :param data:要加签的数据
// :return string:签名
function RSAEncrypt(data) {
let str = params2str(data)
let key = new NodeRSA(zmop_public_key)
key.setOptions({encryptionScheme: 'pkcs1'});
let encrypted = key.encrypt(str, 'base64')
return encrypted
}
function RSADecrypt(str) {
let key = new NodeRSA(private_key)
key.setOptions({encryptionScheme: 'pkcs1'});
let encrypted = key.decrypt(str, 'utf8')
return encrypted
}
// 转换业务参数为str
function params2str(data) {
let str = ''
for (let k of Object.keys(data)) {
let v = data[k]
if (Object.prototype.toString.call(v) === '[object Object]') {
v = JSON.stringify(v)
}
str += k + '=' + encodeURIComponent(v) + '&'
}
return str.slice(0, str.length - 1)
}
// str 转为 json
function str2params(str) {
let ret = {}
let arr = str.split('&')
for (let item of arr) {
let index = item.indexOf('=')
ret[item.slice(0, index)] = decodeURIComponent(item.slice(index + 1))
}
return ret
}
// 加签
function sign(data) {
// 签名采用sha1withRsa算法
let str = params2str(data)
let sign = crypto.createSign('RSA-SHA1')
sign.update(str)
return sign.sign(private_key, 'base64')
}
// 验签
// sign_value: 签名,
// str: 待验签的数据
function verify(sign_value, str) {
var verify = crypto.createVerify('RSA-SHA1');
verify.update(str);
return verify.verify(zmop_public_key, sign_value, 'base64')
}
// let resp = {
// "encrypted": true,
// "sign": {
// "signSource": "zhima_sign_value",
// "signResult": "OKICqUJzHMn9ee5p0xIlJE7L5FZ5nOmjtdDYCqHD3FsQCM5RLJ2U3kFCpXf4sWnSW5J/DRsCmYRffofZapP7wH//xrJq5n9rVDg+CHQ3i5E5Mrtv4/X3wsURaDXpX1wJr+mGd2RL8zTwDi9FW1N7bHK28I3sNgwaoWLeS15iJ4s="
// },
// "biz_response_sign": "cEHP5udepFpo6Ow/ejWwLR0Q1MPaxUZA17zt7Ezd73DVNUl8RqDf/mNzap79aOucOc53n0GXwY1HIQMLLNKI9w2va62SajFhrLFYMy+QtWN3w6EsnuWNOz0xQLKpKCw3HbloD2S6nYk1dg3fBWMhC2pyZ8xXES4l6nZXWzTsOnc=",
// "biz_response": "gG4WYaHXetiko/9nqvGPGDVIyY055WgIDQ3RxVEmX9xVRAO9m8rzO33G0lO8S3iQkfHnkjZhbiQhWP7Fm8x9LtEwm8GjnSl+6egPgORUazOAdKdbvRWr9ri18znCJLu5JBr9QH6J7NoPU5YV231fN4bCPRnpD603p96TPQ/Zw/k="
// }
// if (resp.encrypted) {
// let decrypted_res = RSADecrypt(resp.biz_response)
// console.log(JSON.parse(decrypted_res))
// if (verify(resp.biz_response_sign, decrypted_res)) {
// console.log('success')
// } else {
// console.log('error')
// }
// }
module.exports = {
sign,
verify,
RSAEncrypt,
RSADecrypt,
params2str,
str2params
}
const rp = require('request-promise'),
moment = require('moment'),
fs = require('fs'),
rsa = require('./rsa'),
orm = require('../orm'),
extend = require('extend'),
config = require('config'),
log = console.log.bind(console),
error = console.error.bind(console)
// const api_host = "https://zmopenapi.zmxy.com.cn/openapi.do" // 芝麻信用网关地址
// const private_key_file = "d:\\keys\\private_key.pem" // 商户私钥文件路径
// const zmPublic_key_file = "d:\\keys\\public_key.pem" // 芝麻公钥文件路径
// const app_id = "1000***" // 芝麻分配给商户的 appId
// params= URLEncode(Base64(RSAEncrypt(param1=URLEncode(param1value)&param2=URLEncode(param2value))))
class ZmopClient {
constructor() {
this.zmop_host = 'https://zmopenapi.zmxy.com.cn/openapi.do'
this.data = {
app_id: config.get("zmop_app_id"),
charset: 'UTF-8',
version: '1.0',
platform: 'zmop',
}
}
prepare(method, params) {
this.data.method = method
let extended = {
method: method,
params: rsa.RSAEncrypt(params),
sign: rsa.sign(params)
}
return extend(extended, this.data)
}
build_url(certNo, name, extras) {
try {
log(certNo)
log(extras)
let params = {
identity_type: 2,
identity_param: {"certNo": certNo.toString().toUpperCase(), "name": name, "certType": "IDENTITY_CARD"},
biz_params: {"auth_code": "M_H5", "channelType": "app", "state": extras}
}
let method = 'zhima.auth.info.authorize'
return this.zmop_host + '?' + rsa.params2str(this.prepare(method, params))
} catch (e) {
error(e)
throw e
}
}
// 查看是否授权
async authed(certNo, name) {
try {
let method = 'zhima.auth.info.authquery'
// let params = {
// auth_category: 'C2B',
// identity_type: '0',
// identity_param: {"openId": "268801234567890123456"}
// }
//使用身份证和姓名
let params = {
auth_category: 'C2B',
identity_type: '2',
identity_param: {"certNo": certNo.toString().toUpperCase(), "name": name, "certType": "IDENTITY_CARD"}
}
let resp = await rp.post({
url: this.zmop_host,
json: true,
form: this.prepare(method, params)
})
if (resp.encrypted) {
let decrypted_res = rsa.RSADecrypt(resp.biz_response)
if (rsa.verify(resp.biz_response_sign, decrypted_res)) {
return decrypted_res
} else {
throw new Error('api-authed 验签失败 resp')
}
} else {
return resp
}
} catch (e) {
throw e
}
}
async watch_list(open_id) {
let retry = 0
let self = this
async function get(transaction_id) {
try {
let method = 'zhima.credit.watchlistii.get'
let params = {
transaction_id: transaction_id,
product_code: 'w1010100100000000022',
open_id: open_id
}
let resp = await rp.post({
url: self.zmop_host,
json: true,
form: self.prepare(method, params)
})
let row = {
transaction_id: transaction_id,
resp: JSON.stringify(resp),
open_id: open_id,
platform: 'zhima',
method: 'watch_list'
}
log('zmop_score resp: ', resp)
await orm.create_api_task(row)
if (resp.encrypted) {
let decrypted_res = rsa.RSADecrypt(resp.biz_response)
if (rsa.verify(resp.biz_response_sign, decrypted_res)) {
return JSON.parse(decrypted_res)
} else {
error('api-score 验签失败: ', decrypted_res)
throw new Error('api-score 验签失败')
}
} else {
let biz_response = JSON.parse(resp.biz_response)
//{ encrypted: false, biz_response: '{"success":false,"error_code":"ZMCSP.zm_account_not_existed","error_message":"芝麻账户不存在"}' }
if (biz_response.error_code == 'ZMCREDIT.transaction_id_repeat' && retry < 3) {
retry++
let transaction_id = ZmopClient.build_transaction_id()
return await get(open_id, transaction_id)
} else {
return biz_response
}
}
} catch (e) {
throw e
}
}
let transaction_id = ZmopClient.build_transaction_id()
return await get(transaction_id)
}
// 查询芝麻分接口
async score(open_id) {
let retry = 0
let self = this
async function get(transaction_id) {
try {
let method = 'zhima.credit.score.get'
let params = {
transaction_id: transaction_id,
product_code: 'w1010100100000000001',
open_id: open_id
}
let resp = await rp.post({
url: self.zmop_host,
json: true,
form: self.prepare(method, params)
})
let row = {
transaction_id: transaction_id,
resp: JSON.stringify(resp),
open_id: open_id,
platform: 'zhima',
method: 'score'
}
log('zmop_score resp: ', resp)
await orm.create_api_task(row)
if (resp.encrypted) {
let decrypted_res = rsa.RSADecrypt(resp.biz_response)
if (rsa.verify(resp.biz_response_sign, decrypted_res)) {
return JSON.parse(decrypted_res)
} else {
error('api-score 验签失败: ', decrypted_res)
throw new Error('api-score 验签失败')
}
} else {
let biz_response = JSON.parse(resp.biz_response)
//{ encrypted: false, biz_response: '{"success":false,"error_code":"ZMCSP.zm_account_not_existed","error_message":"芝麻账户不存在"}' }
if (biz_response.error_code == 'ZMCREDIT.transaction_id_repeat' && retry < 3) {
retry++
let transaction_id = ZmopClient.build_transaction_id()
return await get(open_id, transaction_id)
} else {
return biz_response
}
}
} catch (e) {
throw e
}
}
let transaction_id = ZmopClient.build_transaction_id()
return await get(transaction_id)
}
static
build_transaction_id() {
let t = moment().format('YYYYMMDDHHmmssSSS')
let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
while (t.length < 32) {
t += str[Math.round(Math.random() * (str.length - 1))]
}
return t
}
}
// let t = ZmopClient.build_transaction_id()
// let open_id = '268806822853700342467205358'
// let zmop = new ZmopClient()
// setTimeout(async () => {
// console.log(await zmop.authed('421224199107090029', '吴莹'))
// })
module.exports = ZmopClient
/**
* Created by xaj on 2017/1/11.
*/
"use strict";
var config = require('config'),
log4js = require('log4js'),
log4jsConfig = require('./logger'),
basic = require('./basic');
module.exports = {
"config" : config,
"log4js" : log4js,
"log4jsConfig" : log4jsConfig,
"basic" : basic
};
\ No newline at end of file
var jwt = require('jsonwebtoken'),
moment = require('moment'),
extend = require('extend'),
fs = require('fs');
module.exports = function (options) {
var opts = extend({}, {
pub_cert_file: './rsa_public_key.pem',
pri_cert_file: './rsa_private_key.pem',
query_name: 'token',
data_name: 'phone',
//指定过期时间
expiresIn: moment().add(1, 'years').unix(),
//用于从请求信息中获取登录凭证,用户名、密码...
getCredentials: function () {
return {};
},
//用于登录验证,根据用户名密码验证用户是否有效
verifyIdentity: function () {
return true;
}
}, options);
//公钥
var pub_cert = fs.readFileSync(opts.pub_cert_file);
//私钥
var pri_cert = fs.readFileSync(opts.pri_cert_file);
return {
_create: function (data) {
var payload = {};
payload[opts.data_name] = data;
return jwt.sign(payload, pri_cert, {
expiresIn: opts.expiresIn,
algorithm: 'RS256',
noTimestamp: true
});
},
//第一次生成token
generateToken: function (req) {
var data = opts.verifyIdentity(opts.getCredentials(req));
if (!data) return '';
return this._create(data);
},
// 销毁token, 过期时间改为当前时间
destory: function () {
var payload = this.verify(req);
opts.expiresIn = moment().unix()
if (payload) return this._create(payload[opts.data_name]);
return '';
},
//刷新token
refreshToken: function (req) {
var payload = this.verify(req);
if (payload) return this._create(payload[opts.data_name]);
return '';
},
//从请求中获取token的字符串
_getReqToken: function (req) {
var token = '';
//获取token
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
token = req.headers.authorization.split(' ')[1];
} else if (req.query && req.query[opts.query_name]) {
token = req.query[opts.query_name];
}
return token;
},
//验证token并得到其中的payload
verify: function (req) {
var token = this._getReqToken(req);
if (!token) return false;
var payload = null;
try {
//验证token是否有效
payload = jwt.verify(token, pub_cert, {algorithms: 'RS256'});
} catch (err) {
console.log(err);
}
return payload;
},
//token解码
decode: function (token) {
var decoded = null;
try {
decoded = jwt.decode(token, {complete: true, json: true});
} catch (err) {
console.log(err);
}
return decoded;
},
//获得身份信息
getIdentity: function (req) {
var payload = this.verify(req);
return payload && payload[opts.data_name];
}
}
};
\ No newline at end of file
/**
* Created by xaj on 2017/1/11.
*
* Description: common methods such as get local ip, make muti-level directory, string format, and so on;
* common data&check methods which need to disclosure from constants.js.
*
*/
"use strict";
var path = require('path'),
os = require('os'),
fs = require('fs');
module.exports = {
/*
* iftype: 网卡类型 eth, lo, tunl
* family: IPv4 or IPv6
* default return: '127.0.0.1'
*
* Description: get ipv4 or ipv6 address of assigned interface
* eg: getLocalIP(eth, IPv4)
* */
"getLocalIP" : function (iftype, family) {
var ip = '127.0.0.1';
var ifs = os.networkInterfaces();
for (var dev in ifs) {
if (dev.toLowerCase().match(iftype.toLowerCase())) {
var devinfo = ifs[dev];
for (var i=0; i<devinfo.length; i++) {
if (devinfo[i].family.toLowerCase() === family.toLowerCase()) {
ip = devinfo[i].address;
break;
}
}
break;
}
}
return ip;
},
/*
* dirpath: absolute directory path
*
* Description: asynchronous make directory
* */
"mkdirs" : function mkdirs(dirpath, mode, callback) {
fs.exists(dirpath, function(exists){
if (exists) {
callback(dirpath);
} else {
mkdirs(path.dirname(dirpath), mode, function(){
fs.mkdir(dirpath, mode, callback);
});
}
});
},
/*
* dirpath: absolute directory path
*
* Description: synchronous make directory
* */
"mkdirsSync" : function mkdirsSync(dirpath, mode) {
if (fs.existsSync(dirpath))
{
return;
} else {
mkdirsSync(path.dirname(dirpath), mode);
fs.mkdirSync(dirpath, mode);
}
},
/*
* s: string
*
* Description: string format, change multi spaces to one space
* eg: tmp = trim(stdout).split(' '), then tmp is an array obj
* */
"trimSpaces" : function (s) {
return s.replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g,' ');
},
};
var config = require('config');
var fs = require('fs');
var log4js = require('log4js');
var basic = require('./basic');
var log4jsConfig;
if (config.has('log4jsConfig')) {
log4jsConfig = config.get('log4jsConfig');
}
if(log4jsConfig) {
let name = config.get('log4jsName');
log4jsConfig.appenders[1].category.unshift(name);
/* log日志的配置 */
var logDir = log4jsConfig.appenders[1].filename;
if(logDir) {
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir);
}
}
/* 给日志文件名加上IP地址 */
var IpAdress = basic.getLocalIP('eth', 'IPv4');
if(log4jsConfig.appenders) {
for (var i = 0; i < log4jsConfig.appenders.length; i++) {
if (log4jsConfig.appenders[i].pattern) {
/* 把IP和微服务名移到filename字符串前面 */
var serviceName = log4jsConfig.appenders[i].pattern.split("-", 1);
log4jsConfig.appenders[i].pattern = log4jsConfig.appenders[i].pattern.slice(serviceName[0].length);
log4jsConfig.appenders[i].filename = log4jsConfig.appenders[i].filename + IpAdress + '-' + name + serviceName[0];
}
}
}
log4js.configure(log4jsConfig);
/* 将uncaughtException异常截获打印到log */
process.on('uncaughtException',function(err){
console.error(err.stack);
process.emit('exit',1);
});
}
module.exports = log4jsConfig;
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "zmop",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"lib": "lib"
},
"scripts": {
"start": "cross-env NODE_ENV=production&&node kqyx.js",
"dev": "supervisor index"
},
"author": "xaj",
"license": "MIT",
"dependencies": {
"ali-oss": "^5.2.0",
"body-parser": "^1.17.2",
"co": "^4.6.0",
"config": "^1.28.1",
"connect-multiparty": "^2.1.0",
"cookie-parser": "^1.4.3",
"crypto": "0.0.3",
"express": "^4.16.2",
"express-ws": "^3.0.0",
"extend": "^3.0.1",
"hbs": "^4.0.1",
"https": "^1.0.0",
"iconv-lite": "^0.4.17",
"log4js": "0.6.27",
"moment": "^2.18.1",
"mysql": "^2.15.0",
"mysql2": "^1.5.3",
"node-rsa": "^0.4.2",
"node-schedule": "^1.2.3",
"nunjucks": "^3.1.2",
"request": "^2.83.0",
"request-promise": "^4.2.2",
"sequelize": "^4.37.6"
},
"devDependencies": {
"cross-env": "^5.1.4"
}
}
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>芝麻分接口文档</title>
<meta name="description" content="Description">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="vendor/themes/vue.css">
<style>
.markdown-section {
margin-left: 20px;
}
.field-support {
background: content-box;
font-size: 15px;
border: 1px solid #ddd;
padding: 6px 20px;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
<script>
window.$docsify = {
name: '芝麻分接口文档',
repo: '', themeColor: '#3F51B5'
}
</script>
<script src="vendor/docsify.js"></script>
<script src="vendor/themes/bash.js"></script>
<script src="vendor/themes/json_base.js"></script>
</html>
const express = require('express');
const http = require('http');
const path = require('path');
const config = require('config');
// middlewares
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const timeInterval = config.get('timeInterval');
const scheduleproc = require('./lib/scheduleproc');
var app = express();
var login = require('./routers/login');
var pay = require('./routers/pay');
var tools = require('./routers/tools');
var main = require('./routers/main');
var data_service = require('./routers/data_service');
//X-Frame-Options: Allow-From http://www.growingio.com
app.use('*', function (req, res, next) {
res.setHeader('X-Frame-Options', 'ALLOW-FROM https://www.growingio.com');
next();
})
// 给app配置bodyParser中间件
// 通过如下配置再路由种处理request时,可以直接获得post请求的body部分
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
const aes = require('./lib/aes');
const token = require('./lib/token')
app.use(function (req, res, next) {
if (req.body.data) {
try {
req.body = aes.aesDecrypt(req.body.data)
if (!req.body) {
return res.send({code: 199, msg: '系统错误'})
}
req.body = JSON.parse(req.body)
} catch (e) {
console.log(e)
return res.send({code: 199, msg: '系统错误'})
}
}
// if (!/login/.test(req.path)) {
// try {
// let test = token.decode(req.headers.authorization)
// if (test) {
// req.body.userId = test.userId
// }
// }catch(e) {
// return res.send({code: -1, msg: '无效的authorization token'})
// }
// }
console.log(req.path, ': ', req.body)
next()
})
// 注册路由
app.use('/login', login);
app.use('/tools', tools);
app.use('/data', main);
app.use('/pay', pay);
app.use('/dataService', data_service);
const httpPort = config.get('httpPort')
var Server = http.createServer(app);
Server.listen(httpPort, function () {
console.log((new Date()) + ' server start http server and listen on: ' + JSON.stringify(Server.address()));
});
// 定时清理日志任务
scheduleproc.BeginCleanLogWork(timeInterval);
\ No newline at end of file
This diff is collapsed.
(function(Prism) {
var insideString = {
variable: [
// Arithmetic Environment
{
pattern: /\$?\(\([\s\S]+?\)\)/,
inside: {
// If there is a $ sign at the beginning highlight $(( and )) as variable
variable: [{
pattern: /(^\$\(\([\s\S]+)\)\)/,
lookbehind: true
},
/^\$\(\(/,
],
number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/,
// Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,
// If there is no $ sign at the beginning highlight (( and )) as punctuation
punctuation: /\(\(?|\)\)?|,|;/
}
},
// Command Substitution
{
pattern: /\$\([^)]+\)|`[^`]+`/,
inside: {
variable: /^\$\(|^`|\)$|`$/
}
},
/\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i
],
};
Prism.languages.bash = {
'shebang': {
pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,
alias: 'important'
},
'comment': {
pattern: /(^|[^"{\\])#.*/,
lookbehind: true
},
'string': [
//Support for Here-Documents https://en.wikipedia.org/wiki/Here_document
{
pattern: /((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g,
lookbehind: true,
greedy: true,
inside: insideString
},
{
pattern: /(["'])(?:\\\\|\\?[^\\])*?\1/g,
greedy: true,
inside: insideString
}
],
'variable': insideString.variable,
// Originally based on http://ss64.com/bash/
'function': {
pattern: /(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/,
lookbehind: true
},
'keyword': {
pattern: /(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/,
lookbehind: true
},
'boolean': {
pattern: /(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/,
lookbehind: true
},
'operator': /&&?|\|\|?|==?|!=?|<<<?|>>|<=?|>=?|=~/,
'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];]/
};
var inside = insideString.variable[1].inside;
inside['function'] = Prism.languages.bash['function'];
inside.keyword = Prism.languages.bash.keyword;
inside.boolean = Prism.languages.bash.boolean;
inside.operator = Prism.languages.bash.operator;
inside.punctuation = Prism.languages.bash.punctuation;
})(Prism);
Prism.languages.json = {
'property': /"(?:\\.|[^\\"])*"(?=\s*:)/ig,
'string': /"(?!:)(?:\\.|[^\\"])*"(?!:)/g,
'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?)\b/g,
'punctuation': /[{}[\]);,]/g,
'operator': /:/g,
'boolean': /\b(true|false)\b/gi,
'null': /\bnull\b/gi
};
Prism.languages.jsonp = Prism.languages.json;
This diff is collapsed.
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>芝麻分接口文档</title>
<meta name="description" content="Description">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="vendor/themes/vue.css">
<style>
.markdown-section {
margin-left: 20px;
}
.field-support {
background: content-box;
font-size: 15px;
border: 1px solid #ddd;
padding: 6px 20px;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
<script>
window.$docsify = {
name: '芝麻分接口文档',
repo: '', themeColor: '#3F51B5'
}
</script>
<script src="vendor/docsify.js"></script>
<script src="vendor/themes/bash.js"></script>
<script src="vendor/themes/json_base.js"></script>
</html>
const express = require('express');
const http = require('http');
const path = require('path');
const config = require('config');
// middlewares
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const timeInterval = config.get('timeInterval');
const scheduleproc = require('./lib/scheduleproc');
var app = express();
var login = require('./routers/login');
var pay = require('./routers/pay');
var tools = require('./routers/tools');
var main = require('./routers/main');
var data_service = require('./routers/data_service');
//X-Frame-Options: Allow-From http://www.growingio.com
app.use('*', function (req, res, next) {
res.setHeader('X-Frame-Options', 'ALLOW-FROM https://www.growingio.com');
next();
})
// 给app配置bodyParser中间件
// 通过如下配置再路由种处理request时,可以直接获得post请求的body部分
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
const aes = require('./lib/aes');
const token = require('./lib/token')
app.use(function (req, res, next) {
if (req.body.data) {
try {
req.body = aes.aesDecrypt(req.body.data)
if (!req.body) {
return res.send({code: 199, msg: '系统错误'})
}
req.body = JSON.parse(req.body)
} catch (e) {
console.log(e)
return res.send({code: 199, msg: '系统错误'})
}
}
// if (!/login/.test(req.path)) {
// try {
// let test = token.decode(req.headers.authorization)
// if (test) {
// req.body.userId = test.userId
// }
// }catch(e) {
// return res.send({code: -1, msg: '无效的authorization token'})
// }
// }
console.log(req.path, ': ', req.body)
next()
})
// 注册路由
app.use('/login', login);
app.use('/tools', tools);
app.use('/data', main);
app.use('/pay', pay);
app.use('/dataService', data_service);
const httpPort = config.get('httpPort')
var Server = http.createServer(app);
Server.listen(httpPort, function () {
console.log((new Date()) + ' server start http server and listen on: ' + JSON.stringify(Server.address()));
});
// 定时清理日志任务
scheduleproc.BeginCleanLogWork(timeInterval);
\ No newline at end of file
This diff is collapsed.
(function(Prism) {
var insideString = {
variable: [
// Arithmetic Environment
{
pattern: /\$?\(\([\s\S]+?\)\)/,
inside: {
// If there is a $ sign at the beginning highlight $(( and )) as variable
variable: [{
pattern: /(^\$\(\([\s\S]+)\)\)/,
lookbehind: true
},
/^\$\(\(/,
],
number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/,
// Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,
// If there is no $ sign at the beginning highlight (( and )) as punctuation
punctuation: /\(\(?|\)\)?|,|;/
}
},
// Command Substitution
{
pattern: /\$\([^)]+\)|`[^`]+`/,
inside: {
variable: /^\$\(|^`|\)$|`$/
}
},
/\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i
],
};
Prism.languages.bash = {
'shebang': {
pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,
alias: 'important'
},
'comment': {
pattern: /(^|[^"{\\])#.*/,
lookbehind: true
},
'string': [
//Support for Here-Documents https://en.wikipedia.org/wiki/Here_document
{
pattern: /((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g,
lookbehind: true,
greedy: true,
inside: insideString
},
{
pattern: /(["'])(?:\\\\|\\?[^\\])*?\1/g,
greedy: true,
inside: insideString
}
],
'variable': insideString.variable,
// Originally based on http://ss64.com/bash/
'function': {
pattern: /(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/,
lookbehind: true
},
'keyword': {
pattern: /(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/,
lookbehind: true
},
'boolean': {
pattern: /(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/,
lookbehind: true
},
'operator': /&&?|\|\|?|==?|!=?|<<<?|>>|<=?|>=?|=~/,
'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];]/
};
var inside = insideString.variable[1].inside;
inside['function'] = Prism.languages.bash['function'];
inside.keyword = Prism.languages.bash.keyword;
inside.boolean = Prism.languages.bash.boolean;
inside.operator = Prism.languages.bash.operator;
inside.punctuation = Prism.languages.bash.punctuation;
})(Prism);
Prism.languages.json = {
'property': /"(?:\\.|[^\\"])*"(?=\s*:)/ig,
'string': /"(?!:)(?:\\.|[^\\"])*"(?!:)/g,
'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?)\b/g,
'punctuation': /[{}[\]);,]/g,
'operator': /:/g,
'boolean': /\b(true|false)\b/gi,
'null': /\bnull\b/gi
};
Prism.languages.jsonp = Prism.languages.json;
This diff is collapsed.
This diff is collapsed.
//document.documentElement.style.fontSize = document.documentElement.clientWidth/25 + 'px';
function getParams(data, key, default_value) {
if (data != undefined) {
return key in data ? data[key] : default_value;
}
return default_value;
}
function serializeParams(data) {
var serializedParams = '';
for (var pro in data) {
serializedParams += (serializedParams.length ? '&' : '') + pro + '=' + encodeURIComponent(data[pro]);
}
return serializedParams;
}
function getURLParams(url) {
var urlParts = url.split("?");
var result = {};
if (urlParts[1]) {
var params = urlParts[1].split("&");
for (var i = 0; i < params.length; ++i) {
var item = params[i].split("=");
var key = decodeURIComponent(item[0]);
var uri_encoded = item[1].replace(/%([^\da-fA-f].)/, "%25$1")
var val = decodeURIComponent(uri_encoded);
result[key] = val;
}
}
return result;
}
function doAjax(args) {
var request = new XMLHttpRequest(),
url = getParams(args, 'url', ''),
data = getParams(args, 'data', {}),
contentType = getParams(args, 'contentType', "application/x-www-form-urlencoded"),
type = getParams(args, 'type', 'get');
request.onreadystatechange = function () {
if (request.readyState == 4) {
if (request.status == 200) {
var dataType = null;
if ('dataType' in args) {
dataType = args.dataType;
} else {
if (/\bContent\-Type\s*:\s* ([^\n;]+)(?=\n|;)/i.test(request.getAllResponseHeaders())) {
var contentType = RegExp.$1;
if (/\bjson\b/i.test(contentType)) {
dataType = 'json';
} else {
dataType = 'text';
}
}
}
var data = null;
if (/^json$/i.test(dataType)) {
data = JSON.parse(request.responseText);
} else {
data = request.responseText;
}
try {
if (typeof args.success == 'function') {
args.success(data);
}
} catch (e) {
}
} else {
if (typeof args.error == 'function') {
args.error(request.status);
}
}
}
}
request.onloadstart = function () {
if (typeof args.loadstart == 'function') {
args.loadstart();
}
}
request.onprogress = function (event) {
if (typeof args.progress == 'function') {
args.progress(event);
}
}
request.timeout = getParams(args, 'timeout', 0);
if (/^post$/gi.test(type)) {
request.open("POST", url, true);
request.setRequestHeader("Content-Type", contentType);
if ("application/x-www-form-urlencoded" == contentType) {
var content = typeof data === 'string' ? data : serializeParams(data);
request.send(content);
} else if ("application/json" == contentType) {
var content = typeof data === 'string' ? data : JSON.stringify(data);
request.send(content);
}
} else {
url += (url.indexOf("?") >= 0 ? '&' : '?') + serializeParams(data);
request.open("GET", url, true);
request.send();
}
}
function doJsonAjax(url, data, success, failed, loadstart, progress) {
doAjax({
url: url,
type: 'post',
data: data,
contentType: 'application/json',
success: success,
error: failed,
loadstart: loadstart,
progress: progress
});
}
$.toast = function (text, delay) {
if (delay === undefined || +delay <= 0) {
delay = 3000;
}
var toast = $('#toast'), timer = 0;
if (toast.length === 0) {
toast = $('<div>', {'class': 'toast', id: 'toast'}).append($('<span>')).appendTo($('body'));
}
toast.find('span').html(text);
timer = toast.data('timer');
timer && clearTimeout(timer);
toast.show();
toast.data("timer", setTimeout(function () {
toast.detach().data("timer", 0);
}, delay));
}
function IdentityCodeValid(code) {
var city = {
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: "澳门",
91: "国外 "
};
var tip = "";
var pass = true;
if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
tip = "身份证号格式错误";
pass = false;
}
else if (!city[code.substr(0, 2)]) {
tip = "地址编码错误";
pass = false;
} else {
var t = code.substr(6, 4) + '-' + code.substr(10, 2) + '-' + code.substr(12, 2);
var ar = t.split(/-/);
t = new Date(t);
if (ar[0] != t.getFullYear() || ar[1] != t.getMonth() + 1 || ar[2] != t.getDate()) {
pass = false;
tip = "身份证号出生年月错误";
}
//18位身份证需要验证最后一位校验位
if (code.length == 18) {
code = code.split('');
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++) {
ai = code[i];
wi = factor[i];
sum += ai * wi;
}
if (parity[sum % 11] != code[17]) {
tip = "校验位错误";
pass = false;
}
}
}
if (!pass) console.log("youchu ID error:", code, tip);
return pass;
}
This diff is collapsed.
This diff is collapsed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>芝麻认证</title>
<meta charset="utf-8">
<meta http-equiv="pragma" content="no-cache">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<style>
.pannel {
margin-top: 10px;
padding-bottom: 32px;
background-color: #fff;
box-shadow: 0 0 2px rgba(0, 0, 0, .04)
}
.pannel .wrapper {
padding: 35px 0 1px
}
.pannel .wrapper .icon {
width: 72px;
height: 72px;
display: block;
margin: 0 auto;
background-image: url('/zmop/static/icon_rzsb2.png');
background-size: 100%
}
.pannel .wrapper .title {
display: block;
color: #14b25a;
font-size: 18px;
text-align: center;
margin-top: 20px
}
.pannel .wrapper p {
margin: 0;
color: #a6a6a6;
font-size: 14px;
padding: 16px 12px 0;
line-height: 20px;
text-align: center;
word-break: break-all
}
.pannel .wrapper p .red {
color: #ea6363
}
.pannel .wrapper.failed .icon {
background-image: url('/zmop/static/icon_rzsb2.png')
}
.pannel .wrapper .failed .title {
color: #fc8c28
}
</style>
</head>
<body>
<section>
<div class="pannel">
<div class="wrapper">
<div class="failed">
<div class="icon"></div>
<span class="title">{{ error_message }}</span></div>
</div>
</div>
</section>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>芝麻认证</title>
<meta charset="utf-8"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<script type="text/javascript" src="/zmop/js/zepto.js"></script>
<script type="text/javascript" src="/zmop/js/common.js"></script>
<script type="text/javascript" src="/zmop/js/asset.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
html {
background: white;
}
.container {
padding: 75px 28px 0;
}
input {
border: none;
outline: none;
height: 22px;
margin: 20px 0;
font-size: 16px;
border-bottom: 1px solid #C0C4CC;
}
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
color: #8E9091;
}
input:-moz-placeholder, textarea:-moz-placeholder {
color: #8E9091;
}
input::-moz-placeholder, textarea::-moz-placeholder {
color: #8E9091;
}
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
color: #8E9091;
}
.input-group {
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.btn {
padding-top: 50px;
font-size: 14px;
}
button {
height: 48px;
width: 100%;
border-radius: 4px;
border: none;
color: #FFFFFF;
background: #1195F7;
}
button[disabled] {
background: #8DC1F4;
}
input[placeholder] {
letter-spacing: 0;
opacity: 0.7;
}
.toast {
position: fixed;
top: 40px;
max-width: 80%;
border-radius: 10px;
text-align: center;
color: white;
background-color: rgba(0, 0, 0, 0.75);
font-size: 0;
display: inline-block;
left: 50%;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
z-index: 100;
}
.toast > * {
display: inline-block;
vertical-align: middle;
}
.toast span {
font-size: 14px;
padding: 10px 10px;
display: block;
height: auto;
word-wrap: break-word;
}
</style>
</head>
<body>
<div class="container">
<div class="input-group">
<input id="cert_no" name="身份证" type="text" placeholder="身份证" data-re="^([\dxX]{15,18})$">
<input id="cert_name" name="姓名" type="text" placeholder="姓名" data-re="[^\d\s]">
<input id="cert_phone" name="手机号" type="text" placeholder="手机号"
data-re="^(((13[0-9]{1})|(14[0-9]{1})|(17[0-9]{1})|(15[0-3]{1})|(15[4-9]{1})|(18[0-9]{1})|(199))+\d{8})$">
</div>
<div class="btn">
<button id="submit" disabled="disabled" onclick="submit()">进行授权</button>
</div>
</div>
<input id="query" hidden="hidden" value="{{ query }}">
<script>
function submit() {
var data = {cert_no: $('#cert_no').val(), cert_name: $('#cert_name').val(), cert_phone: $('#cert_phone').val()}
if (!valid_input(data)) {
return
}
var query = JSON.parse($('#query').val())
query.cert_no = data.cert_no
query.cert_name = data.cert_name
query.cert_phone = data.cert_phone
var url = '/zmop/auth'
if (query.channel == 'H5') {
url = '/zmop/auth?channel=H5'
}
doAjax({
url: url,
type: 'POST',
data: query,
success: function (resp) {
if (resp.code == 0) {
if (resp.channel == 'H5') {
window.location.href = resp.auth_url
} else if (resp.channel == 'APP') {
call_alipay(resp.auth_url)
}
} else {
$.toast(resp.msg)
}
},
error: function (err) {
$.toast('系统错误, 请稍后再试')
}
})
}
$('input').each(function (index, item) {
item.onkeyup = function () {
check_inputs()
};
item.onpaste = function (e) {
setTimeout(function () {
check_inputs()
}, 200)
}
});
function call_alipay(scheme) {
if ($('#callApp')) {
$('#callApp').remove()
}
var n = window.lib.env.os.name
if (n == 'Android') {
var ifa = document.createElement('iframe');
ifa.id = 'callApp';
ifa.style.display = 'none';
ifa.style.width = '0%';
ifa.style.height = '0%';
ifa.style.border = 'none';
ifa.style.margin = '0';
ifa.style.padding = '0';
ifa.src = scheme
document.body.appendChild(ifa);
//document.body.removeChild(ifa);
ifa = null
}
if (n == 'iPhone' || n == 'iPad') {
var a = document.createElement('a');
a.setAttribute('href', scheme);
a.id = 'callApp';
a.style.display = 'none';
document.body.appendChild(a);
var e = document.createEvent('HTMLEvents');
e.initEvent('click', false, false);
a.dispatchEvent(e);
}
document.getElementById('callApp').click()
}
function check_inputs() {
var inputs = $('input')
var ready = true;
inputs.each(function (index, item) {
if (item.value == '' || !item.value) {
ready = false
}
});
if (ready) {
$('#submit').removeAttr('disabled')
} else {
$('#submit').attr('disabled', 'disabled')
}
}
function valid_input(data) {
var rt = true;
$.each(data, function (key) {
if (key == 'cert_no') {
if (!IdentityCodeValid(data[key])) {
$.toast('无效的身份证号');
rt = false
return rt
}
}
var index = 'input[id="' + key + '"]';
if ($(index).attr('data-re')) {
var re = new RegExp($(index).attr('data-re'))
if (!re.test(data[key])) {
$.toast($(index).attr('name') + '格式不对');
rt = false;
return rt
}
}
});
return rt
}
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>芝麻认证</title>
<meta charset="utf-8"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="viewport"
content="width=device-width, initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<style>
* {
margin: 0;
padding: 0;
font-size: 14px;
text-align: center;
}
.container {
padding: 100px 28px 0;
}
img {
padding-bottom: 20px;
height: 66px;
}
.success {
color: #1195F7;
}
.fail {
color: #fc8c28;
}
button {
margin-top: 150px;
height: 60px;
width: 215px;
border: none;
color: #9B9B9B;
background: #F8F9FE;
}
</style>
</head>
<body>
<div class="container">
{% if success == 'true' %}
<div class="success">
<img src="/zmop/static/success.png">
<p>操作成功,请返回原app</p>
</div>
{% else %}
<div class="fail">
<img src="/zmop/static/fail.png">
<p>{{error_msg}}</p>
</div>
{% endif %}
<!--<div class="btn">-->
<!--<button type="submit" onclick="window.close()">关闭页面</button>-->
<!--</div>-->
</div>
</body>
</html>
\ No newline at end of file
const express = require('express');
const expressWs = require('express-ws');
const http = require('http');
const path = require('path');
const config = require('config');
const nunjucks = require('nunjucks');
// middlewares
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const timeInterval = config.get('timeInterval');
const scheduleproc = require('./lib/scheduleproc');
var app = express();
const httpPort = config.get('httpPort')
var Server = http.createServer(app);
Server.listen(httpPort, function () {
console.log((new Date()) + ' server start http server and listen on: ' + JSON.stringify(Server.address()));
});
expressWs(app, Server);
var index = require('./routers/index');
nunjucks.configure(path.join(__dirname, 'views'), { // 设置模板文件的目录,为views
autoescape: true,
express: app
});
app.set('view engine', 'html');
//X-Frame-Options: Allow-From http://www.growingio.com
app.use('*', function (req, res, next) {
res.setHeader('X-Frame-Options', 'ALLOW-FROM https://www.growingio.com');
next();
})
// 给app配置bodyParser中间件
// 通过如下配置再路由种处理request时,可以直接获得post请求的body部分
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json({limit: '1000kb'}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// 注册路由
app.use('/zmop', index);
// 定时清理日志任务
scheduleproc.BeginCleanLogWork(timeInterval);
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment