jieshun-parking 0.2.0 → 0.3.0
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 +4 -4
- data/lib/jieshun/parking/client.rb +98 -22
- data/lib/jieshun/parking/configuration.rb +7 -2
- data/lib/jieshun/parking/helpers/retry.rb +29 -0
- data/lib/jieshun/parking/http/http_client.rb +4 -0
- data/lib/jieshun/parking/http/standard_http_client.rb +24 -5
- data/lib/jieshun/parking/redis/redis_client.rb +40 -0
- data/lib/jieshun/parking/version.rb +1 -1
- data/lib/jieshun/parking.rb +4 -1
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c033ed285f339fd38e1dd803c8c2c61c32d10336043d24f5d4128435f4161cfb
|
4
|
+
data.tar.gz: 07b4e10db0470a94edfec44d6d7b97be9ba4c266deadaeee3fe3817dc60490d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6ef6744eb3bda44d4cc6c022002752c439a8af45ba5f392d75a85a14f3be63009eb5e5ba08090758d854c8d35c5f84d003f5b119fcd3634eb1e88ef4a0333fe
|
7
|
+
data.tar.gz: 5e9ea829f022a2fe9d3df947e6c105b36592284a2bb2d7dbdbfcab81752413dbe7da40abc3b704aee3cb912cf078925c28fcca96bc3e44f8fa2d231883b33b19
|
@@ -1,38 +1,114 @@
|
|
1
|
+
require_relative "./redis/redis_client"
|
2
|
+
require "json"
|
3
|
+
require 'digest'
|
4
|
+
|
1
5
|
module Jieshun
|
2
6
|
module Parking
|
3
7
|
|
4
8
|
class Client
|
5
9
|
|
10
|
+
REDIS_AUTH_KEY = 'jieshun.parking.auth.token'
|
11
|
+
@@max_notify_try_times = 10
|
12
|
+
|
6
13
|
def initialize(configuration, http_client = StandardHttpClient.new)
|
7
14
|
@configuration = configuration
|
8
15
|
@http_client = http_client
|
16
|
+
@redis_client = RedisClient.new(@configuration.redis_config)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def get_auth_token
|
21
|
+
@redis_client.redis_get(REDIS_AUTH_KEY)
|
22
|
+
end
|
23
|
+
|
24
|
+
def login_if_required
|
25
|
+
auth_token = get_auth_token
|
26
|
+
if Jieshun::Parking.always_login || auth_token.nil? || auth_token.empty?
|
27
|
+
hash = { cid: @configuration.cid, usr: @configuration.usr, psw: @configuration.psw }
|
28
|
+
@http_client.post_form("#{@configuration.server_url}/jsaims/login", {}, hash) do |result|
|
29
|
+
auth_token = result.body['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
|
+
end
|
33
|
+
else
|
34
|
+
yield(auth_token)
|
35
|
+
end
|
9
36
|
end
|
10
37
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
carNo: car_no
|
38
|
+
def create_order_by_car_no(park_code, car_no)
|
39
|
+
payload = {
|
40
|
+
"serviceId": "3c.pay.createorderbycarno",
|
41
|
+
"requestType": "DATA",
|
42
|
+
"attributes": {
|
43
|
+
"businesserCode": @configuration.businesser_code,
|
44
|
+
"parkCode": park_code,
|
45
|
+
"orderType": "VNP",
|
46
|
+
"carNo": car_no
|
21
47
|
}
|
22
|
-
}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
48
|
+
}.to_json
|
49
|
+
unify_call(payload) do |result|
|
50
|
+
# 0:正常,正常订单
|
51
|
+
# 1:安装验证失败,前端设备异常
|
52
|
+
# 2:未入场
|
53
|
+
# 5:非临时卡
|
54
|
+
# 6:未设置收费标准,前端停车场异常
|
55
|
+
# 9:已缴费,超时滞留时间内
|
56
|
+
# 10:正常免费时间段内
|
57
|
+
# 11:打折免费时间段内
|
58
|
+
# 12:打折全免时间段内
|
59
|
+
# 13:打折减免时间段内
|
60
|
+
# 20:超时收费不能使用卡券
|
61
|
+
# 3 1:已入场无需缴费
|
62
|
+
# 9999:其它未知错误
|
63
|
+
attributes = result.body['dataItems'].first['attributes']
|
64
|
+
retcode = attributes['retcode']
|
65
|
+
retmsg = attributes['retmsg']
|
66
|
+
raise RuntimeError.new(retmsg) if retcode != '0'
|
67
|
+
yield(result)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def unify_call(payload)
|
72
|
+
login_if_required do |auth_token|
|
73
|
+
sn = generate_signature("#{payload}#{@configuration.sign_key}")
|
74
|
+
|
75
|
+
hash = {
|
76
|
+
cid: @configuration.cid,
|
77
|
+
tn: auth_token,
|
78
|
+
v: 2,
|
79
|
+
sn: sn,
|
80
|
+
p: payload
|
81
|
+
}
|
82
|
+
|
83
|
+
@http_client.post_form("#{@configuration.server_url}/jsaims/as", { }, hash) do |result|
|
84
|
+
yield(result)
|
28
85
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
86
|
+
|
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)
|
34
111
|
end
|
35
|
-
yield(result)
|
36
112
|
end
|
37
113
|
end
|
38
114
|
|
@@ -3,11 +3,16 @@ module Jieshun
|
|
3
3
|
|
4
4
|
class Configuration
|
5
5
|
|
6
|
-
attr_reader :server_url, :businesser_code
|
6
|
+
attr_reader :server_url, :businesser_code, :cid, :usr, :psw, :sign_key, :redis_config
|
7
7
|
|
8
|
-
def initialize(server_url, businesser_code)
|
8
|
+
def initialize(server_url, businesser_code, cid, usr, psw, sign_key, redis_config)
|
9
9
|
@server_url = server_url
|
10
10
|
@businesser_code = businesser_code
|
11
|
+
@cid = cid
|
12
|
+
@usr = usr
|
13
|
+
@psw = psw
|
14
|
+
@sign_key = sign_key
|
15
|
+
@redis_config = redis_config
|
11
16
|
end
|
12
17
|
|
13
18
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Retry
|
2
|
+
|
3
|
+
def self.with_retries(options)
|
4
|
+
sleep_seconds = options[:sleep_seconds]
|
5
|
+
sleep_seconds ||= 1
|
6
|
+
max_tries = options[:max_tries]
|
7
|
+
max_tries ||= 10
|
8
|
+
tried_times = 0
|
9
|
+
begin
|
10
|
+
yield
|
11
|
+
rescue Exception => e
|
12
|
+
if Jieshun::Parking.logger
|
13
|
+
Jieshun::Parking.logger.error("Failed to execute operation, business_info: #{options[:business_info]}, error: #{e}")
|
14
|
+
end
|
15
|
+
if tried_times < max_tries
|
16
|
+
sleep(sleep_seconds)
|
17
|
+
tried_times = tried_times + 1
|
18
|
+
if Jieshun::Parking.logger
|
19
|
+
Jieshun::Parking.logger.info("Retrying operation, business_info: #{options[:business_info]}, tried_times: #{tried_times}")
|
20
|
+
end
|
21
|
+
retry
|
22
|
+
else
|
23
|
+
Jieshun::Parking.logger.error("Retried #{tried_times} times, aborted.")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
end
|
@@ -4,6 +4,10 @@ module Jieshun
|
|
4
4
|
|
5
5
|
class HttpClient
|
6
6
|
|
7
|
+
def post_form(server_url, headers, hash)
|
8
|
+
raise NotImplementedError.new("You must implement this method.")
|
9
|
+
end
|
10
|
+
|
7
11
|
def post_json(server_url, headers, hash)
|
8
12
|
raise NotImplementedError.new("You must implement this method.")
|
9
13
|
end
|
@@ -7,23 +7,42 @@ module Jieshun
|
|
7
7
|
require 'uri'
|
8
8
|
require 'json'
|
9
9
|
|
10
|
+
def post_form(server_url, headers, hash)
|
11
|
+
post(server_url, 'application/x-www-form-urlencoded', headers, hash) do |result|
|
12
|
+
yield(result)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
def post_json(server_url, headers, hash)
|
17
|
+
post(server_url, 'application/json', headers, hash) do |result|
|
18
|
+
yield(result)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def post(server_url, content_type, headers, hash)
|
11
23
|
uri = URI.parse(server_url)
|
12
24
|
req = Net::HTTP::Post.new(uri)
|
13
25
|
headers.each { |k, v| req[k] = v }
|
14
|
-
req["Content-Type"] =
|
26
|
+
req["Content-Type"] = content_type
|
15
27
|
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
16
28
|
if Jieshun::Parking.debug_mode && Jieshun::Parking.logger
|
17
|
-
Jieshun::Parking.logger.debug("Jieshun Parking Request #{hash}")
|
29
|
+
Jieshun::Parking.logger.debug("Jieshun Parking Request, url: #{server_url}, body: #{JSON.pretty_generate(hash)}")
|
18
30
|
end
|
19
|
-
|
31
|
+
if content_type == 'application/json'
|
32
|
+
req.body = hash.to_json
|
33
|
+
elsif content_type == 'application/x-www-form-urlencoded'
|
34
|
+
req.set_form_data(hash)
|
35
|
+
else
|
36
|
+
raise RuntimeError.new("Unsupported content type #{content_type}")
|
37
|
+
end
|
38
|
+
|
20
39
|
res = http.request(req)
|
21
40
|
if Jieshun::Parking.debug_mode && Jieshun::Parking.logger
|
22
|
-
Jieshun::Parking.logger.debug("Jieshun Parking Response #{res}")
|
41
|
+
Jieshun::Parking.logger.debug("Jieshun Parking Response #{JSON.pretty_generate(JSON.parse(res.body))}")
|
23
42
|
end
|
24
43
|
successful = res.kind_of?(Net::HTTPSuccess)
|
25
44
|
json = JSON.parse(res.body)
|
26
|
-
result = Jieshun::Parking::Result.new(successful,
|
45
|
+
result = Jieshun::Parking::Result.new(successful, json.to_hash)
|
27
46
|
yield result
|
28
47
|
end
|
29
48
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "redis"
|
2
|
+
|
3
|
+
module Jieshun
|
4
|
+
module Parking
|
5
|
+
class RedisClient
|
6
|
+
|
7
|
+
def initialize(redis_config)
|
8
|
+
unless $redis
|
9
|
+
$redis = Redis.new(redis_config)
|
10
|
+
end
|
11
|
+
$redis
|
12
|
+
end
|
13
|
+
|
14
|
+
def redis_client
|
15
|
+
$redis
|
16
|
+
end
|
17
|
+
|
18
|
+
def redis_set(key, value, expire_time = 60)
|
19
|
+
# Rails.logger.debug "redis_client #{redis_client}"
|
20
|
+
redis_client.set key, value
|
21
|
+
if expire_time > 0
|
22
|
+
redis_client.expire key, expire_time
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def redis_get(key)
|
27
|
+
redis_client.get key
|
28
|
+
end
|
29
|
+
|
30
|
+
def redis_del(key)
|
31
|
+
redis_client.del key
|
32
|
+
end
|
33
|
+
|
34
|
+
def redis_ttl(key)
|
35
|
+
redis_client.ttl key
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/jieshun/parking.rb
CHANGED
@@ -6,6 +6,8 @@ require_relative "parking/client"
|
|
6
6
|
require_relative "parking/result"
|
7
7
|
require_relative "parking/http/http_client"
|
8
8
|
require_relative "parking/http/standard_http_client"
|
9
|
+
require_relative "parking/redis/redis_client"
|
10
|
+
require_relative "parking/helpers/retry"
|
9
11
|
require 'logger'
|
10
12
|
|
11
13
|
|
@@ -13,8 +15,9 @@ module Jieshun
|
|
13
15
|
module Parking
|
14
16
|
@logger = Logger.new(STDOUT)
|
15
17
|
@debug_mode = true
|
18
|
+
@always_login = false
|
16
19
|
class<< self
|
17
|
-
attr_accessor :logger, :debug_mode
|
20
|
+
attr_accessor :logger, :debug_mode, :always_login
|
18
21
|
end
|
19
22
|
end
|
20
23
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- LCola
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: redis
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
27
41
|
description: 捷顺停车场 API, 非官方, Provided by 小可乐科技
|
28
42
|
email:
|
29
43
|
- james.wang.z81@gmail.com
|
@@ -36,8 +50,10 @@ files:
|
|
36
50
|
- lib/jieshun/parking.rb
|
37
51
|
- lib/jieshun/parking/client.rb
|
38
52
|
- lib/jieshun/parking/configuration.rb
|
53
|
+
- lib/jieshun/parking/helpers/retry.rb
|
39
54
|
- lib/jieshun/parking/http/http_client.rb
|
40
55
|
- lib/jieshun/parking/http/standard_http_client.rb
|
56
|
+
- lib/jieshun/parking/redis/redis_client.rb
|
41
57
|
- lib/jieshun/parking/result.rb
|
42
58
|
- lib/jieshun/parking/version.rb
|
43
59
|
homepage: http://rubygems.org/gems/jieshun-parking
|