haoyaoshi 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 870a2b40f7c34c4cc1454538bfd6d495967b6cda
4
+ data.tar.gz: 213193097eaa449555234ea184d0d4581414a14e
5
+ SHA512:
6
+ metadata.gz: af8d3e94368dc26e4ad38c5a6076340ac56a891d082aaff037a7c5e571593dbb73fd3b7847833b98a2ecc50fd21b5dfd6dd4efc532f7aee22260e406314d26bb
7
+ data.tar.gz: 9fcdb0964ad433e03c47e270b53fc4866193f5abfaf4536ef2f23c3d1e197c4f04c7f70a03b24af32674b70a8adf3b62d75985b0c55246aed0e86ef575019487
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,121 @@
1
+ require "haoyaoshi/version"
2
+ require "rest-client"
3
+
4
+ if defined? Yajl
5
+ require 'yajl/json_gem'
6
+ else
7
+ require "json"
8
+ end
9
+ require "erb"
10
+
11
+ require "haoyaoshi/config"
12
+ require "haoyaoshi/handler"
13
+ require "haoyaoshi/api"
14
+ require "haoyaoshi/client"
15
+
16
+ module Haoyaoshi
17
+
18
+
19
+ # token store
20
+ module Token
21
+ autoload(:Store, "haoyaoshi/token/store")
22
+ autoload(:ObjectStore, "haoyaoshi/token/object_store")
23
+ autoload(:RedisStore, "haoyaoshi/token/redis_store")
24
+ end
25
+
26
+ OK_MSG = "ok".freeze
27
+ OK_CODE = 0.freeze
28
+ GRANT_TYPE = "client_credentials".freeze
29
+ # 用于标记endpoint可以直接使用url作为完整请求API
30
+ CUSTOM_ENDPOINT = "custom_endpoint".freeze
31
+
32
+ class << self
33
+
34
+ def http_get_without_token(url, url_params={}, endpoint="plain")
35
+ get_api_url = endpoint_url(endpoint, url)
36
+ Rails.logger.info("====好药师order请求参数===>#{get_api_url}===#{url_params}===#{endpoint}")
37
+ load_json(resource(get_api_url).get(params: url_params))
38
+ end
39
+
40
+ def http_post_without_token(url, post_body={}, url_params={}, endpoint="plain")
41
+ post_api_url = endpoint_url(endpoint, url)
42
+ if endpoint == "plain" || endpoint == CUSTOM_ENDPOINT
43
+ post_body = JSON.dump(post_body)
44
+ else
45
+ post_body = JSON.dump(post_body)
46
+ end
47
+ Rails.logger.info("====好药师order请求参数===>#{post_api_url}===#{post_body}=======#{url_params}=#{endpoint}")
48
+ load_json(resource(post_api_url).post(post_body, params: url_params,raw_response: true,:content_type => :json))
49
+ end
50
+
51
+ def http_delete_without_token(url, delete_body={}, url_params={}, endpoint="plain")
52
+ delete_api_url = endpoint_url(endpoint, url)
53
+ if endpoint == "plain" || endpoint == CUSTOM_ENDPOINT
54
+ delete_body = JSON.dump(delete_body)
55
+ else
56
+ delete_body = JSON.dump(delete_body)
57
+ end
58
+ Rails.logger.info("====好药师order请求参数===>#{delete_api_url}===#{delete_body}=======#{url_params}=#{endpoint}")
59
+ load_json(resource(delete_api_url).delete(params: url_params,raw_response: true,:content_type => :json))
60
+ end
61
+
62
+ def resource(url)
63
+ RestClient::Resource.new(url, rest_client_options)
64
+ end
65
+
66
+ # return hash
67
+ def load_json(string)
68
+ result_hash = JSON.parse(string.force_encoding("UTF-8").gsub(/[\u0011-\u001F]/, ""))
69
+ if result_hash.present?
70
+ code = result_hash.delete("errcode")
71
+ en_msg = result_hash.delete("errmsg")
72
+ else
73
+ result_hash = {}
74
+ code = 0
75
+ en_msg = "请求成功"
76
+ end
77
+ ResultHandler.new(code, en_msg, result_hash)
78
+ end
79
+
80
+ def endpoint_url(endpoint, url)
81
+ # 此处为了应对第三方开发者如果自助对接接口时,URL不规范的情况下,可以直接使用URL当为endpoint
82
+ return url if endpoint == CUSTOM_ENDPOINT
83
+ Rails.logger.info("#{endpoint}_endpoint")
84
+ send("#{endpoint}_endpoint") + url
85
+ end
86
+
87
+ def plain_endpoint
88
+ "#{api_endpoint}"
89
+ end
90
+
91
+ def api_endpoint
92
+ api_base_url
93
+ end
94
+
95
+ def order_endpoint
96
+ order_base_url
97
+ end
98
+
99
+ def order_center_endpoint
100
+ order_center_base_url
101
+ end
102
+
103
+ def token_endpoint(url)
104
+ "#{api_endpoint}#{url}"
105
+ end
106
+
107
+ def open_endpoint
108
+ open_base_url
109
+ end
110
+
111
+ def img_endpoint(url)
112
+ "#{img_base_url}#{url}"
113
+ end
114
+
115
+ def calculate_expire(expires_in)
116
+ Time.now.to_i + expires_in.to_i - key_expired.to_i
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,3 @@
1
+ Dir["#{File.dirname(__FILE__)}/api/*.rb"].each do |path|
2
+ require path
3
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module Drug
5
+
6
+ def get_drug_list(params)
7
+ create_url = "#{goods_interface_base_url}/syncGoodsInfoBatchService"
8
+ http_drug_get(create_url,params,"syncGoodsInfoBatchService","open")
9
+ end
10
+
11
+ def get_drug_image(params)
12
+ create_url = "#{goods_interface_base_url}/syncGoodsImagesBatchService"
13
+ http_drug_get(create_url,params,"syncGoodsImagesBatchService","open")
14
+ end
15
+
16
+ def get_drug_price(params)
17
+ create_url = "#{goods_interface_base_url}/queryUpdateInfoBatchService"
18
+ http_drug_get(create_url,params,"queryUpdateInfoBatchService","open")
19
+ end
20
+
21
+ private
22
+
23
+ def goods_interface_base_url
24
+ "/goods-interface"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module EInvoice
5
+
6
+ def get_e_invoice_url(moblie,order_number)
7
+ create_url = "#{invoice_interface_base_url}/#{moblie}/#{order_number}"
8
+ http_get(create_url,{},"api")
9
+ end
10
+
11
+ private
12
+
13
+ def invoice_interface_base_url
14
+ "/invoice/v1.1/e-invoice"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module Image
5
+
6
+ def img_url(path)
7
+ Haoyaoshi.img_endpoint(path)
8
+ end
9
+
10
+ private
11
+
12
+ def image_interface_base_url
13
+ ""
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module Logistics
5
+
6
+ def get_company(params)
7
+ create_url = "#{logistics_interface_base_url}/company"
8
+ http_get(create_url,params,"order")
9
+ end
10
+
11
+ def get_deliveries_list(params)
12
+ create_url = "#{logistics_interface_base_url}/deliveries"
13
+ http_get(create_url,params,"order")
14
+ end
15
+
16
+ def get_deliveries(orderNumber)
17
+ create_url = "#{logistics_interface_base_url}/deliveries/#{orderNumber}"
18
+ http_get(create_url,{orderNumber: orderNumber},"order")
19
+ end
20
+
21
+ private
22
+
23
+ def logistics_interface_base_url
24
+ "/logistics/v1.1"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module Order
5
+
6
+ def get_order_rx(params)
7
+ create_url = "#{order_interface_base_url}/rx"
8
+ http_get(create_url,params,"order")
9
+ end
10
+
11
+ def post_order_rx(params)
12
+ create_url = "#{order_interface_base_url}/rx"
13
+ http_post(create_url,params,{},"order")
14
+ end
15
+
16
+ def post_order(params)
17
+ create_url = "#{order_interface_base_url}/orders"
18
+ http_post(create_url,params,{},"order")
19
+ end
20
+
21
+ def post_order_prescription_url(params)
22
+ create_url = "#{order_interface_base_url}/prescription/url"
23
+ http_post(create_url,params,{},"order")
24
+ end
25
+
26
+ def post_order_prescription_img(params)
27
+ create_url = "#{order_interface_base_url}/prescription/img"
28
+ http_post(create_url,params,{},"order")
29
+ end
30
+
31
+ def delete_order(order_number = nil ,params = {})
32
+ path_url = ""
33
+ params = {}
34
+ if order_number.present?
35
+ path_url = "/#{order_number}"
36
+ end
37
+ create_url = "#{order_interface_base_url}/orders#{path_url}"
38
+ http_delete(create_url,params,{},"order")
39
+ end
40
+
41
+ def delete_batch_order(order_number = nil,params = {})
42
+ if order_number.present?
43
+ params = params.merge({orderNumber: order_number})
44
+ end
45
+ create_url = "#{order_interface_base_url}/orders/batchdelete"
46
+ http_delete(create_url,params,"order")
47
+ end
48
+
49
+ private
50
+
51
+ def order_interface_base_url
52
+ "/order/v1.1"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module OrderCenter
5
+
6
+ def get_syn_stock_info(params)
7
+ create_url = "#{order_center_base_url}/syn-stock-info"
8
+ http_get(create_url,params,"order_center")
9
+ end
10
+
11
+ private
12
+
13
+ def order_center_base_url
14
+ "/ordercenter/v1/stock"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Api
4
+ module Stock
5
+
6
+ def get_stock(productIds = nil ,params = {})
7
+ create_url = "#{stock_interface_base_url}/stocks/#{productIds}"
8
+ http_get(create_url,params,"order")
9
+ end
10
+
11
+ def get_branch_stocks(productIds = nil ,branchStockType = "ALL",params = {})
12
+ create_url = "#{stock_interface_base_url}/branch-stocks/#{branchStockType}/#{productIds}"
13
+ http_get(create_url,params,"order")
14
+ end
15
+
16
+ private
17
+
18
+ def stock_interface_base_url
19
+ "/stock/v1.1"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+ require "monitor"
3
+ require "redis"
4
+ require 'digest/md5'
5
+ module Haoyaoshi
6
+
7
+ class Client
8
+
9
+ include MonitorMixin
10
+
11
+ include Api::Drug
12
+ include Api::Order
13
+ include Api::Logistics
14
+ include Api::Image
15
+ include Api::EInvoice
16
+ include Api::Stock
17
+ include Api::OrderCenter
18
+
19
+ attr_accessor :client_id, :client_secret, :channel, :parnterkey, :grant_type, :scope, :expired_at # Time.now + expires_in
20
+ attr_accessor :access_token, :token_type, :redis_key, :custom_access_token, :token_type_token
21
+
22
+ # options: redis_key, custom_access_token
23
+ def initialize(client_id, client_secret, channel , parnterkey, grant_type = "client_credentials" , scope = "order", options={})
24
+ @client_id = client_id
25
+ @client_secret = client_secret
26
+ @expired_at = Time.now.to_i
27
+ @channel = channel
28
+ @parnterkey = parnterkey
29
+ @grant_type = grant_type if grant_type.present?
30
+ @scope = scope
31
+ @redis_key = security_redis_key(options[:redis_key] || "haoyaoshi_#{client_id}")
32
+ @custom_access_token = options[:custom_access_token]
33
+ @custom_token_type = options[:custom_token_type]
34
+ super() # Monitor#initialize
35
+ end
36
+
37
+ # return token
38
+ def get_access_token
39
+ return custom_access_token if !custom_access_token.nil?
40
+ synchronize{ token_store.access_token }
41
+ end
42
+
43
+ # return token
44
+ def get_token_type
45
+ return custom_token_type if !custom_token_type.nil?
46
+ synchronize{ token_store.token_type }
47
+ end
48
+
49
+ # 检查appid和app_secret是否有效。
50
+ def is_valid?
51
+ return true if !custom_access_token.nil?
52
+ token_store.valid?
53
+ end
54
+
55
+ def token_store
56
+ Token::Store.init_with(self)
57
+ end
58
+
59
+ # 暴露出:http_get,http_post两个方法,方便第三方开发者扩展未开发的微信API。
60
+ def http_get(url, url_params={}, endpoint="plain")
61
+ url_params = url_params.merge(access_token_param)
62
+ Haoyaoshi.http_get_without_token(url, url_params, endpoint)
63
+ end
64
+
65
+ def http_post(url, post_body={}, url_params={}, endpoint="plain")
66
+ url_params = access_token_param.merge(url_params)
67
+ Haoyaoshi.http_post_without_token(url, post_body, url_params, endpoint)
68
+ end
69
+
70
+ def http_delete(url, delete_body={}, url_params={}, endpoint="plain")
71
+ url_params = access_token_param.merge(url_params)
72
+ url = "#{url}?access_token=#{get_access_token}"
73
+ Haoyaoshi.http_delete_without_token(url, delete_body, url_params, endpoint)
74
+ end
75
+
76
+ # 暴露出:http_get,http_post两个方法,方便第三方开发者扩展未开发的微信API。
77
+ def http_drug_get(url, url_params = {}, path = nil, endpoint="plain")
78
+ url_params = {channel: @channel}.merge(url_params)
79
+ tmp_option = url_params.deep_dup
80
+ url_params[:sign] = sign(tmp_option,path)
81
+ Rails.logger.info("#{url_params[:sign]}")
82
+ Haoyaoshi.http_get_without_token(url, url_params, endpoint)
83
+ end
84
+
85
+ private
86
+
87
+ def access_token_param
88
+ {access_token: get_access_token}
89
+ end
90
+
91
+ def security_redis_key(key)
92
+ Digest::MD5.hexdigest(key.to_s).upcase
93
+ end
94
+
95
+ #生成签名
96
+ def sign(params,path)
97
+ option = params.sort().collect{|key,value| "#{key}#{value.to_s}"}.join
98
+ Rails.logger.info("#{path}#{option.to_s}#{@parnterkey}")
99
+ Digest::SHA1.hexdigest("#{path}#{option.to_s}#{@parnterkey}")
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,73 @@
1
+ module Haoyaoshi
2
+
3
+ class << self
4
+
5
+ attr_accessor :config
6
+
7
+ def configure
8
+ yield self.config ||= Config.new
9
+ end
10
+
11
+ def haoyaoshi_redis
12
+ return nil if config.nil?
13
+ @redis ||= config.redis
14
+ end
15
+
16
+ def key_expired
17
+ if config.nil?
18
+ return 100
19
+ end
20
+ @key_expired ||= config.key_expired
21
+ end
22
+
23
+ def img_base_url
24
+ if config.nil?
25
+ return "http://img01.img.ehaoyao.com"
26
+ end
27
+ @img_base_url ||= config.img_base_url
28
+ end
29
+
30
+ def open_base_url
31
+ if config.nil?
32
+ return "http://api.goodscenter.ehaoyao.com"
33
+ end
34
+ @open_base_url ||= config.open_base_url
35
+ end
36
+
37
+ def api_base_url
38
+ if config.nil?
39
+ return "https://api.ehaoyao.com"
40
+ end
41
+ @api_base_url ||= config.api_base_url
42
+ end
43
+
44
+ def order_base_url
45
+ if config.nil?
46
+ return "https://api.ehaoyao.com"
47
+ end
48
+ @order_base_url ||= config.order_base_url
49
+ end
50
+
51
+ def order_center_base_url
52
+ if config.nil?
53
+ return "https://internal.api.ehaoyao.com"
54
+ end
55
+ @order_center_base_url ||= config.order_center_base_url
56
+ end
57
+
58
+ # 可选配置: RestClient timeout, etc.
59
+ # key 必须是符号
60
+ # 如果出现 RestClient::SSLCertificateNotVerified Exception: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
61
+ # 这个错,除了改 verify_ssl: true,请参考:http://www.extendi.it/blog/2015/5/23/47-sslv3-read-server-certificate-b-certificate-verify-failed
62
+ def rest_client_options
63
+ if config.nil?
64
+ return {timeout: 5, open_timeout: 5, verify_ssl: true}
65
+ end
66
+ @rest_client_options ||= config.rest_client_options
67
+ end
68
+ end
69
+
70
+ class Config
71
+ attr_accessor :redis, :rest_client_options, :key_expired, :img_base_url, :open_base_url,:api_base_url, :order_base_url, :order_center_base_url
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ require "haoyaoshi/handler/global_code"
2
+ require "haoyaoshi/handler/result_handler"
3
+ require "haoyaoshi/handler/exceptions"
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ class ValidAccessTokenException < RuntimeError;end
4
+ class MediaTypeException < RuntimeError;end
5
+ end
@@ -0,0 +1,128 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+
4
+ GLOBAL_CODES = {
5
+ -1 => "系统繁忙",
6
+ 0 => "请求成功",
7
+ 40001 => "获取access_token时AppSecret错误,或者access_token无效",
8
+ 40002 => "不合法的凭证类型",
9
+ 40003 => "不合法的OpenID",
10
+ 40004 => "不合法的媒体文件类型",
11
+ 40005 => "不合法的文件类型",
12
+ 40006 => "不合法的文件大小",
13
+ 40007 => "不合法的媒体文件id",
14
+ 40008 => "不合法的消息类型",
15
+ 40009 => "不合法的图片文件大小",
16
+ 40010 => "不合法的语音文件大小",
17
+ 40011 => "不合法的视频文件大小",
18
+ 40012 => "不合法的缩略图文件大小",
19
+ 40013 => "不合法的APPID",
20
+ 40014 => "不合法的access_token",
21
+ 40015 => "不合法的菜单类型",
22
+ 40016 => "不合法的按钮个数",
23
+ 40017 => "不合法的按钮个数",
24
+ 40018 => "不合法的按钮名字长度",
25
+ 40019 => "不合法的按钮KEY长度",
26
+ 40020 => "不合法的按钮URL长度",
27
+ 40021 => "不合法的菜单版本号",
28
+ 40022 => "不合法的子菜单级数",
29
+ 40023 => "不合法的子菜单按钮个数",
30
+ 40024 => "不合法的子菜单按钮类型",
31
+ 40025 => "不合法的子菜单按钮名字长度",
32
+ 40026 => "不合法的子菜单按钮KEY长度",
33
+ 40027 => "不合法的子菜单按钮URL长度",
34
+ 40028 => "不合法的自定义菜单使用用户",
35
+ 40029 => "不合法的oauth_code",
36
+ 40030 => "不合法的refresh_token",
37
+ 40031 => "不合法的openid列表",
38
+ 40032 => "不合法的openid列表长度",
39
+ 40033 => "不合法的请求字符,不能包含xxxx格式的字符",
40
+ 40035 => "不合法的参数",
41
+ 40038 => "不合法的请求格式",
42
+ 40039 => "不合法的URL长度",
43
+ 40050 => "不合法的分组id",
44
+ 40051 => "分组名字不合法",
45
+ 41001 => "缺少access_token参数",
46
+ 41002 => "缺少appid参数",
47
+ 41003 => "缺少refresh_token参数",
48
+ 41004 => "缺少secret参数",
49
+ 41005 => "缺少多媒体文件数据",
50
+ 41006 => "缺少media_id参数",
51
+ 41007 => "缺少子菜单数据",
52
+ 41008 => "缺少oauth code",
53
+ 41009 => "缺少openid",
54
+ 42001 => "access_token超时",
55
+ 42002 => "refresh_token超时",
56
+ 42003 => "oauth_code超时",
57
+ 43001 => "需要GET请求",
58
+ 43002 => "需要POST请求",
59
+ 43003 => "需要HTTPS请求",
60
+ 43004 => "需要接收者关注",
61
+ 43005 => "需要好友关系",
62
+ 44001 => "多媒体文件为空",
63
+ 44002 => "POST的数据包为空",
64
+ 44003 => "图文消息内容为空",
65
+ 44004 => "文本消息内容为空",
66
+ 45001 => "多媒体文件大小超过限制",
67
+ 45002 => "消息内容超过限制",
68
+ 45003 => "标题字段超过限制",
69
+ 45004 => "描述字段超过限制",
70
+ 45005 => "链接字段超过限制",
71
+ 45006 => "图片链接字段超过限制",
72
+ 45007 => "语音播放时间超过限制",
73
+ 45008 => "图文消息超过限制",
74
+ 45009 => "接口调用超过限制",
75
+ 45010 => "创建菜单个数超过限制",
76
+ 45015 => "回复时间超过限制",
77
+ 45016 => "系统分组,不允许修改",
78
+ 45017 => "分组名字过长",
79
+ 45018 => "分组数量超过上限",
80
+ 46001 => "不存在媒体数据",
81
+ 46002 => "不存在的菜单版本",
82
+ 46003 => "不存在的菜单数据",
83
+ 46004 => "不存在的用户",
84
+ 47001 => "解析JSON/XML内容错误",
85
+ 48001 => "api功能未授权",
86
+ 50001 => "用户未授权该api",
87
+ 50002 => "用户受限,可能是违规后接口被封禁",
88
+ 61451 => "参数错误(invalid parameter)",
89
+ 61452 => "无效客服账号(invalid kf_account)",
90
+ 61453 => "客服帐号已存在(kf_account exsited)",
91
+ 61454 => "客服帐号名长度超过限制(仅允许10个英文字符,不包括@及@后的公众号的微信号)(invalid kf_acount length)",
92
+ 61455 => "客服帐号名包含非法字符(仅允许英文+数字)(illegal character in kf_account)",
93
+ 61456 => "客服帐号个数超过限制(10个客服账号)(kf_account count exceeded)",
94
+ 61457 => "无效头像文件类型(invalid file type)",
95
+ 61450 => "系统错误(system error)",
96
+ 61500 => "日期格式错误",
97
+ 61501 => "日期范围错误",
98
+ 9001001 => "POST数据参数不合法",
99
+ 9001002 => "远端服务不可用",
100
+ 9001003 => "Ticket不合法",
101
+ 9001004 => "获取摇周边用户信息失败",
102
+ 9001005 => "获取商户信息失败",
103
+ 9001006 => "获取OpenID失败",
104
+ 9001007 => "上传文件缺失",
105
+ 9001008 => "上传素材的文件类型不合法",
106
+ 9001009 => "上传素材的文件尺寸不合法",
107
+ 9001010 => "上传失败",
108
+ 9001020 => "帐号不合法",
109
+ 9001021 => "已有设备激活率低于50%,不能新增设备",
110
+ 9001022 => "设备申请数不合法,必须为大于0的数字",
111
+ 9001023 => "已存在审核中的设备ID申请",
112
+ 9001024 => "一次查询设备ID数量不能超过50",
113
+ 9001025 => "设备ID不合法",
114
+ 9001026 => "页面ID不合法",
115
+ 9001027 => "页面参数不合法",
116
+ 9001028 => "一次删除页面ID数量不能超过10",
117
+ 9001029 => "页面已应用在设备中,请先解除应用关系再删除",
118
+ 9001030 => "一次查询页面ID数量不能超过50",
119
+ 9001031 => "时间区间不合法",
120
+ 9001032 => "保存设备与页面的绑定关系参数错误",
121
+ 9001033 => "门店ID不合法",
122
+ 9001034 => "设备备注信息过长",
123
+ 9001035 => "设备申请参数不合法",
124
+ 9001036 => "查询起始值begin不合法",
125
+ 1010001025 => "缺少请求参数:开始时间(startTime)或结束时间(endTime)!"
126
+ }unless defined?(GLOBAL_CODES)
127
+
128
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+
4
+ class ResultHandler
5
+
6
+ attr_accessor :code, :cn_msg, :en_msg, :result
7
+
8
+ def initialize(code, en_msg, result={})
9
+ @code = code || OK_CODE
10
+ @en_msg = en_msg || OK_MSG
11
+ @cn_msg = GLOBAL_CODES[@code.to_i]
12
+ @result = package_result(result)
13
+ end
14
+
15
+ # This method is to valid the current request if is true or is false
16
+ def is_ok?
17
+ code == OK_CODE
18
+ end
19
+ alias_method :ok?, :is_ok?
20
+
21
+ # e.g.:
22
+ # 45009: api freq out of limit(接口调用超过限制)
23
+ def full_message
24
+ "#{code}: #{en_msg}(#{cn_msg})."
25
+ end
26
+ alias_method :full_messages, :full_message
27
+
28
+ def full_error_message
29
+ full_message if !is_ok?
30
+ end
31
+ alias_method :full_error_messages, :full_error_message
32
+ alias_method :errors, :full_error_message
33
+
34
+ private
35
+
36
+ # if define Rails constant
37
+ # result = Haoyaoshi::ResultHandler.new("0", "success", {:ok => "true"})
38
+ # result.result["ok"] #=> true
39
+ # result.result[:ok] #=> true
40
+ # result.result['ok'] #=> true
41
+ def package_result(result)
42
+ return result if !result.is_a?(Hash)
43
+ if defined?(Rails)
44
+ ActiveSupport::HashWithIndifferentAccess.new(result)
45
+ else
46
+ result
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Token
4
+ class ObjectStore < Store
5
+
6
+ def valid?
7
+ super
8
+ end
9
+
10
+ def token_expired?
11
+ # 如果当前token过期时间小于现在的时间,则重新获取一次
12
+ client.expired_at <= Time.now.to_i
13
+ end
14
+
15
+ def refresh_token
16
+ super
17
+ end
18
+
19
+ def access_token
20
+ super
21
+ client.access_token
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Token
4
+ class RedisStore < Store
5
+
6
+ def valid?
7
+ haoyaoshi_redis.del(client.redis_key)
8
+ super
9
+ end
10
+
11
+ def token_expired?
12
+ haoyaoshi_redis.hvals(client.redis_key).empty?
13
+ end
14
+
15
+ def refresh_token
16
+ super
17
+ haoyaoshi_redis.hmset(
18
+ client.redis_key, "access_token",
19
+ client.access_token, "expired_at",
20
+ client.expired_at, "token_type",
21
+ client.token_type
22
+
23
+ )
24
+ haoyaoshi_redis.expireat(client.redis_key, client.expired_at.to_i)
25
+ end
26
+
27
+ def access_token
28
+ super
29
+ client.access_token = haoyaoshi_redis.hget(client.redis_key, "access_token")
30
+ client.expired_at = haoyaoshi_redis.hget(client.redis_key, "expired_at")
31
+ client.token_type = haoyaoshi_redis.hget(client.redis_key, "token_type")
32
+ client.access_token
33
+ end
34
+
35
+ def haoyaoshi_redis
36
+ Haoyaoshi.haoyaoshi_redis
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ module Haoyaoshi
3
+ module Token
4
+ class Store
5
+
6
+ attr_accessor :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def self.init_with(client)
13
+ if Haoyaoshi.haoyaoshi_redis.nil?
14
+ ObjectStore.new(client)
15
+ else
16
+ RedisStore.new(client)
17
+ end
18
+ end
19
+
20
+ def valid?
21
+ authenticate["valid"]
22
+ end
23
+
24
+ def authenticate
25
+ auth_result = http_get_access_token
26
+ auth = false
27
+ if auth_result.is_ok?
28
+ set_access_token(auth_result.result)
29
+ auth = true
30
+ end
31
+ {"valid" => auth, "handler" => auth_result}
32
+ end
33
+
34
+ def refresh_token
35
+ handle_valid_exception
36
+ set_access_token
37
+ end
38
+
39
+ def access_token
40
+ refresh_token if token_expired?
41
+ end
42
+
43
+ def token_expired?
44
+ raise NotImplementedError, "Subclasses must implement a token_expired? method"
45
+ end
46
+
47
+ def set_access_token(access_token_infos=nil)
48
+ token_infos = access_token_infos || http_get_access_token.result
49
+ client.access_token = token_infos["access_token"]
50
+ client.token_type = token_infos["token_type"]
51
+ client.expired_at = Haoyaoshi.calculate_expire(token_infos["expires_in"])
52
+ end
53
+
54
+ def http_get_access_token
55
+ Haoyaoshi.http_post_without_token("/auth/v1/oauth2/token", authenticate_headers,authenticate_headers)
56
+ end
57
+
58
+ def authenticate_headers
59
+ {grant_type: client.grant_type, client_id: client.client_id, client_secret: client.client_secret, scope: client.scope}
60
+ end
61
+
62
+ private
63
+
64
+ def handle_valid_exception
65
+ auth_result = authenticate
66
+ if !auth_result["valid"]
67
+ result_handler = auth_result["handler"]
68
+ raise ValidAccessTokenException, result_handler.full_error_message
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module Haoyaoshi
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haoyaoshi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - guoyoujin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-08-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: fakeweb
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1'
83
+ description: haoyaoshi drug api Ruby Server SDK.
84
+ email:
85
+ - guoyoujin123@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - Rakefile
91
+ - lib/haoyaoshi.rb
92
+ - lib/haoyaoshi/api.rb
93
+ - lib/haoyaoshi/api/drug.rb
94
+ - lib/haoyaoshi/api/e_invoice.rb
95
+ - lib/haoyaoshi/api/image.rb
96
+ - lib/haoyaoshi/api/logistics.rb
97
+ - lib/haoyaoshi/api/order.rb
98
+ - lib/haoyaoshi/api/order_center.rb
99
+ - lib/haoyaoshi/api/stock.rb
100
+ - lib/haoyaoshi/client.rb
101
+ - lib/haoyaoshi/config.rb
102
+ - lib/haoyaoshi/handler.rb
103
+ - lib/haoyaoshi/handler/exceptions.rb
104
+ - lib/haoyaoshi/handler/global_code.rb
105
+ - lib/haoyaoshi/handler/result_handler.rb
106
+ - lib/haoyaoshi/token/object_store.rb
107
+ - lib/haoyaoshi/token/redis_store.rb
108
+ - lib/haoyaoshi/token/store.rb
109
+ - lib/haoyaoshi/version.rb
110
+ homepage: https://github.com/guoyoujin/haoyaoshi
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.4.8
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: trycatch
134
+ test_files: []