jieshun-parking 0.6.3 → 0.6.5.pre.BETA1

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: e62dbeac0ad063a0b1ccfd6c05f734d9eb029601db476a8902e76f90ccd020b2
4
- data.tar.gz: 4a74322b5e1e9736dd085019b5dc7b5757778d3cc0f4a23b047c4799767c2d45
3
+ metadata.gz: cf220d18875147478f68fb9785a90cf533897172825acb2af6ffb27081a508bf
4
+ data.tar.gz: 1c3d58e7d87669f31dba8c8e552b7cc073d90ce45cc89d71f5330ce72d4cc117
5
5
  SHA512:
6
- metadata.gz: 9eea2615ad75a03358adb76f297570df9f5ca3ce04f477ce48119c71fea806b7477123ee5d19b937d3e3af35c6ad3fe09252d3e84c802e451d64d4640aae2f24
7
- data.tar.gz: aee37bc88b551134697e7c8f5575d21c5f8282d0cc9ffe38ed0f461cdcdee735c3f1863ffe4d19d7490cc97c7a0a54c312a7d31cd5cd4c2322f5d7c6ed7d15d0
6
+ metadata.gz: 9e9e45eee33e79d764cbb8ad3b4501b9bbbd7f49ad82c73a26a46522a7a560c6ba7c10b87b3880af437b25e8b20656457d21d7b9f8526011fb818f0647035265
7
+ data.tar.gz: c5bc064b2598c3da370f6f11f2f2a1ba44920306b95ae74ceb4d2b0eb30ecddead038f02b4ee661acf64ca20dd30c922492109277d31fd98cfef5a5c6fcabd12
@@ -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
- module Parking
7
-
8
- # 捷顺订单 API Client, 对应文档为 捷慧通云平台接口规范_2.1.doc 和 捷慧通云平台接口标准协议_http_V3.0.1.doc
9
- class Client
10
-
11
- REDIS_AUTH_KEY = 'jieshun.parking.auth.token'
12
- @@max_notify_try_times = 10
13
-
14
- def initialize(configuration, http_client = StandardHttpClient.new)
15
- @configuration = configuration
16
- @http_client = http_client
17
- @redis_client = RedisClient.new(@configuration.redis_config)
18
- end
19
-
20
-
21
- def get_auth_token
22
- @redis_client.redis_get(REDIS_AUTH_KEY)
23
- end
24
-
25
- def login_if_required
26
- auth_token = get_auth_token
27
- if Jieshun::Parking.always_login || auth_token.nil? || auth_token.empty?
28
- hash = { cid: @configuration.cid, usr: @configuration.usr, psw: @configuration.psw }
29
- @http_client.post_form("#{@configuration.server_url}/jsaims/login", {}, hash) do |result|
30
- auth_token = result.body['token']
31
- @redis_client.redis_set(REDIS_AUTH_KEY, auth_token, 2 * 60 * 60 - 60) # token will be expired after 2 hours
32
- yield(auth_token)
33
- end
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
-
76
- hash = {
77
- cid: @configuration.cid,
78
- tn: auth_token,
79
- v: 2,
80
- sn: sn,
81
- p: payload
82
- }
83
-
84
- @http_client.post_form("#{@configuration.server_url}/jsaims/as", { }, hash) do |result|
85
- yield(result)
86
- end
87
-
88
- end
89
- end
90
-
91
- def generate_signature(payload)
92
- md5_string = Digest::MD5.hexdigest(payload)
93
- md5_string.upcase
94
- end
95
-
96
- def notify_order_result(order_no, pay_type, pay_time, transaction_id)
97
- Retry.with_retries(max_tries: 10, sleep_seconds: 1, business_info: { order_no: order_no }) do
98
- payload = {
99
- "serviceId": "3c.pay.notifyorderresult",
100
- "requestType":"DATA",
101
- "attributes":{
102
- "orderNo": order_no,
103
- "tradeStatus": 0,
104
- "isCallBack": 0,
105
- "payType": pay_type,
106
- "payTime": pay_time.strftime('%Y-%m-%d %H:%M:%S'),
107
- "transactionId": transaction_id
108
- }
109
- }.to_json
110
- unify_call(payload) do |result|
111
- yield(result)
112
- end
113
- end
114
- end
115
-
116
- end
117
-
118
- end
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
@@ -1,82 +1,135 @@
1
1
  module Jieshun
2
- module Parking
3
- # 捷顺数据中心 Client, 目前主要用来获取图片, 对应文档为 QX205_数据中心标准推送协议-1.1.6(1)
4
- class DataCenterClient
2
+ module Parking
3
+ # 捷顺数据中心 Client, 目前主要用来获取图片, 对应文档为 QX205_数据中心标准推送协议-1.1.6(1)
4
+ class DataCenterClient
5
+ REDIS_AUTH_KEY = 'jieshun.parking.datacenter.auth.token'
6
+ REDIS_AUTH_KEY_LOCK = 'jieshun.parking.datacenter.auth.token.lock'
7
+ MAX_RETRY_COUNT = 3 # 定义refresh_token 最大重试次数
8
+ def initialize(configuration, http_client = StandardHttpClient.new)
9
+ @configuration = configuration
10
+ @http_client = http_client
11
+ @redis_client = RedisClient.new(@configuration.redis_config)
12
+ end
5
13
 
6
- REDIS_AUTH_KEY = 'jieshun.parking.datacenter.auth.token'
14
+ def get_auth_token
15
+ @redis_client.redis_get(REDIS_AUTH_KEY)
16
+ end
7
17
 
8
- def initialize(configuration, http_client = StandardHttpClient.new)
9
- @configuration = configuration
10
- @http_client = http_client
11
- @redis_client = RedisClient.new(@configuration.redis_config)
12
- end
18
+ def login_if_required
19
+ auth_token = get_auth_token
20
+ if Jieshun::Parking.always_login || auth_token.nil? || auth_token.empty?
21
+ # 使用 Redis 锁来避免并发刷新
22
+ lock_key = REDIS_AUTH_KEY_LOCK
23
+ begin
24
+ # 设置一个5秒过期的锁
25
+ if @redis_client.redis_set_nx_lock(lock_key, 5)
26
+ # 重试机制
27
+ Retry.with_retries(max_tries: MAX_RETRY_COUNT, sleep_seconds: 1) do
28
+ # 过程中遇到错误重试时, 检查本地token是否存在
29
+ auth_token = get_auth_token
30
+ if auth_token
31
+ yield(auth_token)
32
+ else
33
+ refresh_token do |auth_token|
34
+ yield(auth_token)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ rescue StandardError => e
40
+ Jieshun::Parking.logger.info("Failed to refresh token;error: #{e.message}")
41
+ ensure
42
+ # 确保锁最终被释放
43
+ @redis_client.redis_del(lock_key)
44
+ end
45
+ else
46
+ yield(auth_token)
47
+ end
48
+ end
13
49
 
14
- def get_auth_token
15
- @redis_client.redis_get(REDIS_AUTH_KEY)
16
- end
50
+ def refresh_token
51
+ hash = { pno: @configuration.pno, secret: @configuration.secret }
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) })
62
+ end
17
63
 
18
- def login_if_required
19
- auth_token = get_auth_token
20
- if Jieshun::Parking.always_login || auth_token.nil? || auth_token.empty?
21
- hash = { pno: @configuration.pno, secret: @configuration.secret }
22
- @http_client.post_json("#{@configuration.server_url}/api/login", {}, hash) do |result|
23
- auth_token = result.body['tn']
24
- expire_time = result.body['timeOut'] - 1000
25
- @redis_client.redis_set(REDIS_AUTH_KEY, auth_token, expire_time) # token will be expired after 2 hours
26
- yield(auth_token)
27
- end
28
- else
29
- yield(auth_token)
30
- end
31
- end
64
+ def get_picture_base64(file_path)
65
+ data_items = []
66
+ data_items << { filePath: file_path }
67
+ unify_call("/api/pic/picSearch", data_items.to_json) do |result|
68
+ image = result.body['dataItems'].first['image']
69
+ mime_type = detect_mime_type(image)
70
+ yield({ mime_type_prefix: "data:#{mime_type};base64,", content: image })
71
+ end
72
+ end
32
73
 
33
- def get_picture_base64(file_path)
34
- data_items = []
35
- data_items << { filePath: file_path }
36
- unify_call("/api/pic/picSearch", data_items.to_json) do |result|
37
- image = result.body['dataItems'].first['image']
38
- mime_type = detect_mime_type(image)
39
- yield( { mime_type_prefix: "data:#{mime_type};base64,", content: image } )
40
- end
41
- end
74
+ def detect_mime_type(base64_content)
75
+ return "application/pdf" if content_matches?(base64_content, ['JVBERi0'])
76
+ return "image/gif" if content_matches?(base64_content, ['R0lGODdh', 'R0lGODlh'])
77
+ return "image/png" if content_matches?(base64_content, ['iVBORw0KGgo'])
78
+ return "image/jpg" if content_matches?(base64_content, ['/9j/'])
79
+ return "image/bmp" if content_matches?(base64_content, ['Qk'])
80
+ "application/octet-stream"
81
+ end
42
82
 
43
- def detect_mime_type(base64_content)
44
- return "application/pdf" if content_matches?(base64_content, ['JVBERi0'])
45
- return "image/gif" if content_matches?(base64_content, ['R0lGODdh', 'R0lGODlh'])
46
- return "image/png" if content_matches?(base64_content, ['iVBORw0KGgo'])
47
- return "image/jpg" if content_matches?(base64_content, ['/9j/'])
48
- return "image/bmp" if content_matches?(base64_content, ['Qk'])
49
- "application/octet-stream"
50
- end
83
+ def content_matches?(base64_content, prefixes)
84
+ prefixes.any? { |prefix| base64_content.start_with?(prefix) }
85
+ end
51
86
 
52
- def content_matches?(base64_content, prefixes)
53
- prefixes.any? { |prefix| base64_content.start_with?(prefix) }
54
- end
87
+ def unify_call(api_path, data_items)
88
+ login_if_required do |auth_token|
89
+ ts = Time.now.strftime("%Y%m%d%H%M%S%L")
90
+ sn = generate_signature("#{@configuration.secret}#{ts}#{data_items}")
91
+ hash = {
92
+ pno: @configuration.pno,
93
+ tn: auth_token,
94
+ ts: ts,
95
+ sn: sn,
96
+ dataItems: data_items
97
+ }
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
55
105
 
56
- def unify_call(api_path, data_items)
57
- login_if_required do |auth_token|
58
- ts = Time.now.strftime("%Y%m%d%H%M%S%L")
59
- sn = generate_signature("#{@configuration.secret}#{ts}#{data_items}")
60
- hash = {
61
- pno: @configuration.pno,
62
- tn: auth_token,
63
- ts: ts,
64
- sn: sn,
65
- dataItems: data_items
66
- }
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)
125
+ end
126
+ raise RuntimeError.new("Unified error handling for data center clients; resultCode:#{error['resultCode']}, message: #{error['message']}")
127
+ end
67
128
 
68
- @http_client.post_json("#{@configuration.server_url}/#{api_path}", { }, hash) do |result|
69
- yield(result)
70
- end
71
-
72
- end
73
- end
74
-
75
- def generate_signature(payload)
76
- md5_string = Digest::MD5.hexdigest(payload)
77
- md5_string.upcase
78
- end
79
-
80
- end
81
- end
129
+ def generate_signature(payload)
130
+ md5_string = Digest::MD5.hexdigest(payload)
131
+ md5_string.upcase
132
+ end
133
+ end
134
+ end
82
135
  end
@@ -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,65 +1,68 @@
1
1
  module Jieshun
2
- module Parking
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
- class StandardHttpClient < HttpClient
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
- require 'net/http'
7
- require 'uri'
8
- require 'json'
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
-
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)
23
- uri = URI.parse(server_url)
24
- req = Net::HTTP::Post.new(uri)
25
- headers.each { |k, v| req[k] = v }
26
- req["Content-Type"] = content_type
27
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
28
- if Jieshun::Parking.debug_mode && Jieshun::Parking.logger
29
- Jieshun::Parking.logger.debug("Jieshun Parking Request, url: #{server_url}, body: #{JSON.pretty_generate(hash)}")
30
- end
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
-
39
- res = http.request(req)
40
- if Jieshun::Parking.debug_mode && Jieshun::Parking.logger
41
- Jieshun::Parking.logger.debug("Jieshun Parking Response #{JSON.pretty_generate(JSON.parse(res.body))}")
42
- end
43
- successful = res.kind_of?(Net::HTTPSuccess)
44
- unless successful
45
- message = "Got error response from jieshun #{res.status}"
46
- Jieshun::Parking.logger.error(message)
47
- raise RuntimeError.new(message)
48
- end
49
- json = JSON.parse(res.body)
50
- result_code = json['resultCode']
51
- unless result_code.zero?
52
- message = "Got invalid result code jieshun resultCode: #{result_code}, message: #{json['message']}"
53
- Jieshun::Parking.logger.error(message)
54
- raise RuntimeError.new(json['message'])
55
- end
56
-
57
- result = Jieshun::Parking::Result.new(successful, json.to_hash)
58
- yield result
59
- end
60
- end
61
-
62
- end
63
-
64
- 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
65
68
  end
@@ -35,6 +35,10 @@ module Jieshun
35
35
  redis_client.ttl key
36
36
  end
37
37
 
38
+
39
+ def redis_set_nx_lock(lock_key, expire_time)
40
+ redis_client.set(lock_key, 1, nx: true, ex: expire_time)
41
+ end
38
42
  end
39
43
  end
40
44
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jieshun
4
4
  module Parking
5
- VERSION = "0.6.3"
5
+ VERSION = "0.6.5-BETA1"
6
6
  end
7
7
  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.3
4
+ version: 0.6.5.pre.BETA1
5
5
  platform: ruby
6
6
  authors:
7
7
  - LCola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-08 00:00:00.000000000 Z
11
+ date: 2024-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -76,11 +76,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
76
  version: 2.4.0
77
77
  required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
79
+ - - ">"
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: 1.3.1
82
82
  requirements: []
83
- rubygems_version: 3.0.9
83
+ rubygems_version: 3.2.3
84
84
  signing_key:
85
85
  specification_version: 4
86
86
  summary: 捷顺停车场 API