jieshun-parking 0.6.5 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f757e64ca65f7ec73d955625d1c052aa27b22e0af7977f2ad05bdc7f46b9f94c
|
4
|
+
data.tar.gz: 2cc8c9a4f32e449bccfb78bcdc14c1ba5a6769ab83da82a88569f0d2781d93a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5006b6816f38df63885b73823958fb7724e8fffe230c8a069a8a4030497f48862d957f0a371bbceef4c562e5538aa33c4cb910f1c8e5650f5a94e64de727ae96
|
7
|
+
data.tar.gz: 5222ccafbfec4b0547127a15d3fe7c65b4cb6e43374ad8120967bd1ad6260eb188a7e17cc61c472deb0f82800b1ee1540101907d17cd5488b3e47cb5cfba8885
|
@@ -1,119 +1,127 @@
|
|
1
1
|
require_relative "./redis/redis_client"
|
2
2
|
require "json"
|
3
3
|
require 'digest'
|
4
|
-
|
5
4
|
module Jieshun
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
5
|
+
module Parking
|
6
|
+
# 捷顺订单 API Client, 对应文档为 捷慧通云平台接口规范_2.1.doc 和 捷慧通云平台接口标准协议_http_V3.0.1.doc
|
7
|
+
class Client
|
8
|
+
REDIS_AUTH_KEY = 'jieshun.parking.auth.token'
|
9
|
+
@@max_notify_try_times = 10
|
10
|
+
|
11
|
+
def initialize(configuration, http_client = StandardHttpClient.new)
|
12
|
+
@configuration = configuration
|
13
|
+
@http_client = http_client
|
14
|
+
@redis_client = RedisClient.new(@configuration.redis_config)
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_auth_token
|
18
|
+
@redis_client.redis_get(REDIS_AUTH_KEY)
|
19
|
+
end
|
20
|
+
|
21
|
+
def login_if_required
|
22
|
+
auth_token = get_auth_token
|
23
|
+
if Jieshun::Parking.always_login || auth_token.nil? || auth_token.empty?
|
24
|
+
hash = { cid: @configuration.cid, usr: @configuration.usr, psw: @configuration.psw }
|
25
|
+
@http_client.post_form("#{@configuration.server_url}/jsaims/login",
|
26
|
+
{},
|
27
|
+
hash,
|
28
|
+
->(response) {
|
29
|
+
auth_token = response['token']
|
30
|
+
@redis_client.redis_set(REDIS_AUTH_KEY, auth_token, 2 * 60 * 60 - 60) # token will be expired after 2 hours
|
31
|
+
yield(auth_token)
|
32
|
+
},
|
33
|
+
->(error) { handle_failure(error) })
|
34
|
+
else
|
35
|
+
yield(auth_token)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_order_by_car_no(park_code, car_no)
|
40
|
+
payload = {
|
41
|
+
"serviceId": "3c.pay.createorderbycarno",
|
42
|
+
"requestType": "DATA",
|
43
|
+
"attributes": {
|
44
|
+
"businesserCode": @configuration.businesser_code,
|
45
|
+
"parkCode": park_code,
|
46
|
+
"orderType": "VNP",
|
47
|
+
"carNo": car_no
|
48
|
+
}
|
49
|
+
}.to_json
|
50
|
+
unify_call(payload) do |result|
|
51
|
+
# 0:正常,正常订单
|
52
|
+
# 1:安装验证失败,前端设备异常
|
53
|
+
# 2:未入场
|
54
|
+
# 5:非临时卡
|
55
|
+
# 6:未设置收费标准,前端停车场异常
|
56
|
+
# 9:已缴费,超时滞留时间内
|
57
|
+
# 10:正常免费时间段内
|
58
|
+
# 11:打折免费时间段内
|
59
|
+
# 12:打折全免时间段内
|
60
|
+
# 13:打折减免时间段内
|
61
|
+
# 20:超时收费不能使用卡券
|
62
|
+
# 3 1:已入场无需缴费
|
63
|
+
# 9999:其它未知错误
|
64
|
+
attributes = result.body['dataItems'].first['attributes']
|
65
|
+
retcode = attributes['retcode']
|
66
|
+
retmsg = attributes['retmsg']
|
67
|
+
raise RuntimeError.new(retmsg) if retcode != '0'
|
68
|
+
yield(result)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def unify_call(payload)
|
73
|
+
login_if_required do |auth_token|
|
74
|
+
sn = generate_signature("#{payload}#{@configuration.sign_key}")
|
75
|
+
hash = {
|
76
|
+
cid: @configuration.cid,
|
77
|
+
tn: auth_token,
|
78
|
+
v: 2,
|
79
|
+
sn: sn,
|
80
|
+
p: payload
|
81
|
+
}
|
82
|
+
@http_client.post_form("#{@configuration.server_url}/jsaims/as",
|
83
|
+
{},
|
84
|
+
hash,
|
85
|
+
->(response) { yield(response) },
|
86
|
+
->(error) { handle_failure(error) })
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def generate_signature(payload)
|
91
|
+
md5_string = Digest::MD5.hexdigest(payload)
|
92
|
+
md5_string.upcase
|
93
|
+
end
|
94
|
+
|
95
|
+
def notify_order_result(order_no, pay_type, pay_time, transaction_id)
|
96
|
+
Retry.with_retries(max_tries: 10, sleep_seconds: 1, business_info: { order_no: order_no }) do
|
97
|
+
payload = {
|
98
|
+
"serviceId": "3c.pay.notifyorderresult",
|
99
|
+
"requestType": "DATA",
|
100
|
+
"attributes": {
|
101
|
+
"orderNo": order_no,
|
102
|
+
"tradeStatus": 0,
|
103
|
+
"isCallBack": 0,
|
104
|
+
"payType": pay_type,
|
105
|
+
"payTime": pay_time.strftime('%Y-%m-%d %H:%M:%S'),
|
106
|
+
"transactionId": transaction_id
|
107
|
+
}
|
108
|
+
}.to_json
|
109
|
+
unify_call(payload) do |result|
|
110
|
+
yield(result)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# 捷慧通云平台接口规范_2.1.doc[4.7异常列表]
|
116
|
+
# 0:没有异常
|
117
|
+
# 6: 无效的令牌或令牌已过期
|
118
|
+
def handle_failure(error)
|
119
|
+
case error['resultCode']
|
120
|
+
when 6
|
121
|
+
@redis_client.redis_del(REDIS_AUTH_KEY)
|
122
|
+
end
|
123
|
+
raise RuntimeError.new("Unified error handling for client; resultCode:#{error['resultCode']}, message: #{error['message']}")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
119
127
|
end
|
@@ -49,12 +49,16 @@ module Jieshun
|
|
49
49
|
|
50
50
|
def refresh_token
|
51
51
|
hash = { pno: @configuration.pno, secret: @configuration.secret }
|
52
|
-
@http_client.post_json("#{@configuration.server_url}/api/login",
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
@http_client.post_json("#{@configuration.server_url}/api/login",
|
53
|
+
{},
|
54
|
+
hash,
|
55
|
+
->(response) {
|
56
|
+
auth_token = response['tn']
|
57
|
+
expire_time = response['timeOut'] > 7200 ? response['timeOut'] - 7200 : response['timeOut'] # the token will expire 2 hours in advance
|
58
|
+
@redis_client.redis_set(REDIS_AUTH_KEY, auth_token, expire_time)
|
59
|
+
yield(auth_token)
|
60
|
+
},
|
61
|
+
->(error) { handle_failure(error) })
|
58
62
|
end
|
59
63
|
|
60
64
|
def get_picture_base64(file_path)
|
@@ -91,10 +95,35 @@ module Jieshun
|
|
91
95
|
sn: sn,
|
92
96
|
dataItems: data_items
|
93
97
|
}
|
94
|
-
@http_client.post_json("#{@configuration.server_url}/#{api_path}",
|
95
|
-
|
96
|
-
|
98
|
+
@http_client.post_json("#{@configuration.server_url}/#{api_path}",
|
99
|
+
{},
|
100
|
+
hash,
|
101
|
+
->(response) { yield(response) },
|
102
|
+
->(error) { handle_failure(error) })
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
#0:成功
|
107
|
+
# 1:处理失败
|
108
|
+
# 100:参数为空
|
109
|
+
# 101:账号为空
|
110
|
+
# 102:密码为空
|
111
|
+
# 103:签名为空
|
112
|
+
# 104:令牌为空
|
113
|
+
# 105:dataItem为空
|
114
|
+
# 201:账号不存在
|
115
|
+
# 202:密码错误
|
116
|
+
# 203:令牌过期
|
117
|
+
# 204:格式错误
|
118
|
+
# 205:验签失败
|
119
|
+
#
|
120
|
+
# 301:IP未绑定
|
121
|
+
def handle_failure(error)
|
122
|
+
case error['resultCode']
|
123
|
+
when 203
|
124
|
+
@redis_client.redis_del(REDIS_AUTH_KEY)
|
97
125
|
end
|
126
|
+
raise RuntimeError.new("Unified error handling for data center clients; resultCode:#{error['resultCode']}, message: #{error['message']}")
|
98
127
|
end
|
99
128
|
|
100
129
|
def generate_signature(payload)
|
@@ -4,11 +4,11 @@ module Jieshun
|
|
4
4
|
|
5
5
|
class HttpClient
|
6
6
|
|
7
|
-
def post_form(server_url, headers, hash)
|
7
|
+
def post_form(server_url, headers, hash, success_callback, failure_callback)
|
8
8
|
raise NotImplementedError.new("You must implement this method.")
|
9
9
|
end
|
10
10
|
|
11
|
-
def post_json(server_url, headers, hash)
|
11
|
+
def post_json(server_url, headers, hash, success_callback, failure_callback)
|
12
12
|
raise NotImplementedError.new("You must implement this method.")
|
13
13
|
end
|
14
14
|
|
@@ -1,68 +1,68 @@
|
|
1
1
|
module Jieshun
|
2
|
-
|
2
|
+
module Parking
|
3
|
+
class StandardHttpClient < HttpClient
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
require 'json'
|
7
|
+
# 设置连接和读取的超时时间(以秒为单位)
|
8
|
+
TIMEOUT = 30 # 例如,30 秒超时
|
9
|
+
def post_form(server_url, headers, hash, success_callback, failure_callback)
|
10
|
+
post(server_url, 'application/x-www-form-urlencoded', headers, hash) do |result|
|
11
|
+
if result.successful
|
12
|
+
success_callback.call(result.body)
|
13
|
+
else
|
14
|
+
failure_callback.call(result.body)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
3
18
|
|
4
|
-
|
19
|
+
def post_json(server_url, headers, hash, success_callback, failure_callback)
|
20
|
+
post(server_url, 'application/json', headers, hash) do |result|
|
21
|
+
if result.successful
|
22
|
+
success_callback.call(result.body)
|
23
|
+
else
|
24
|
+
failure_callback.call(result.body)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
5
28
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
successful = res.kind_of?(Net::HTTPSuccess)
|
47
|
-
unless successful
|
48
|
-
message = "Got error response from jieshun #{res.status}"
|
49
|
-
Jieshun::Parking.logger.error(message)
|
50
|
-
raise RuntimeError.new(message)
|
51
|
-
end
|
52
|
-
json = JSON.parse(res.body)
|
53
|
-
result_code = json['resultCode']
|
54
|
-
unless result_code.zero?
|
55
|
-
message = "Got invalid result code jieshun resultCode: #{result_code}, message: #{json['message']}"
|
56
|
-
Jieshun::Parking.logger.error(message)
|
57
|
-
raise RuntimeError.new(json['message'])
|
58
|
-
end
|
59
|
-
|
60
|
-
result = Jieshun::Parking::Result.new(successful, json.to_hash)
|
61
|
-
yield result
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
29
|
+
def post(server_url, content_type, headers, hash)
|
30
|
+
uri = URI.parse(server_url)
|
31
|
+
req = Net::HTTP::Post.new(uri)
|
32
|
+
headers.each { |k, v| req[k] = v }
|
33
|
+
req["Content-Type"] = content_type
|
34
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', read_timeout: TIMEOUT, open_timeout: TIMEOUT) do |http|
|
35
|
+
if Jieshun::Parking.debug_mode && Jieshun::Parking.logger
|
36
|
+
Jieshun::Parking.logger.debug("Jieshun Parking Request, url: #{server_url}, body: #{JSON.pretty_generate(hash)}")
|
37
|
+
end
|
38
|
+
if content_type == 'application/json'
|
39
|
+
req.body = hash.to_json
|
40
|
+
elsif content_type == 'application/x-www-form-urlencoded'
|
41
|
+
req.set_form_data(hash)
|
42
|
+
else
|
43
|
+
raise RuntimeError.new("Unsupported content type #{content_type}")
|
44
|
+
end
|
45
|
+
res = http.request(req)
|
46
|
+
if Jieshun::Parking.debug_mode && Jieshun::Parking.logger
|
47
|
+
Jieshun::Parking.logger.debug("Jieshun Parking Response #{JSON.pretty_generate(JSON.parse(res.body))}")
|
48
|
+
end
|
49
|
+
successful = res.kind_of?(Net::HTTPSuccess)
|
50
|
+
unless successful
|
51
|
+
message = "Got error response from jieshun #{res.status}"
|
52
|
+
Jieshun::Parking.logger.error(message)
|
53
|
+
raise RuntimeError.new(message)
|
54
|
+
end
|
55
|
+
json = JSON.parse(res.body)
|
56
|
+
result_code = json['resultCode']
|
57
|
+
# unless result_code.zero?
|
58
|
+
# message = "Got invalid result code jieshun resultCode: #{result_code}, message: #{json['message']}"
|
59
|
+
# Jieshun::Parking.logger.error(message)
|
60
|
+
# raise RuntimeError.new(json)
|
61
|
+
# end
|
62
|
+
result = Jieshun::Parking::Result.new(result_code.zero?, json.to_hash)
|
63
|
+
yield result
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jieshun-parking
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LCola
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|