eric_weixin 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/eric_weixin/cms/weixin/customs_service_records_controller.rb +1 -1
  3. data/app/controllers/eric_weixin/cms/weixin/weixin_users_controller.rb +3 -1
  4. data/app/controllers/eric_weixin/wz/pays_controller.rb +24 -0
  5. data/app/models/eric_weixin/access_token.rb +1 -1
  6. data/app/models/eric_weixin/customs_service_record.rb +4 -0
  7. data/app/models/eric_weixin/jsapi_ticket.rb +67 -0
  8. data/app/models/eric_weixin/media_news.rb +26 -1
  9. data/app/models/eric_weixin/media_news_sent_record.rb +6 -0
  10. data/app/models/eric_weixin/public_account.rb +28 -0
  11. data/app/models/eric_weixin/redpack.rb +30 -0
  12. data/app/models/eric_weixin/redpack_order.rb +92 -0
  13. data/app/models/eric_weixin/reply_message_rule.rb +136 -34
  14. data/app/models/eric_weixin/weixin_user.rb +9 -3
  15. data/app/views/eric_weixin/cms/weixin/customs_service_records/index.html.erb +2 -1
  16. data/app/views/eric_weixin/cms/weixin/media_news/_select_article.html.erb +1 -1
  17. data/app/views/eric_weixin/cms/weixin/media_news/new.html.erb +2 -2
  18. data/app/views/eric_weixin/cms/weixin/reply_message_rules/index.html.erb +2 -2
  19. data/app/views/eric_weixin/cms/weixin/two_dimension_codes/_two_dimension_code_form.html.erb +1 -1
  20. data/app/views/eric_weixin/cms/weixin/weixin_users/index.html.erb +14 -1
  21. data/db/migrate/20150906064203_add_error_count_to_weixin_media_news.rb +5 -0
  22. data/db/migrate/20150906072855_create_weixin_media_news_sent_records.rb +15 -0
  23. data/db/migrate/20150908023239_add_phone_to_weixin_users.rb +5 -0
  24. data/db/migrate/20150910024059_create_weixin_customs_service_records.rb +16 -0
  25. data/db/migrate/20150911023948_create_weixin_redpack_orders.rb +21 -0
  26. data/db/migrate/20150911062057_create_weixin_redpacks.rb +13 -0
  27. data/db/migrate/20150914061051_create_jsapi_tickets.rb +10 -0
  28. data/lib/eric_weixin/modules/mult_customer.rb +6 -4
  29. data/lib/eric_weixin/modules/pay.rb +84 -0
  30. data/lib/eric_weixin/version.rb +1 -1
  31. metadata +15 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f6d9f69457b61be06879a23c862aaf030b12f8d
4
- data.tar.gz: cbe07f22927fce38bc6d5fef9e9bf0202206d928
3
+ metadata.gz: f051bb6d4db95b0b0dc05755a37b0cb58cac07ec
4
+ data.tar.gz: e7d315eb8728a9e5b76dffa7f1b88e381f0ddf80
5
5
  SHA512:
6
- metadata.gz: 91c9d6965d3414cb46467164e89bde9affc068c75d2cc4597e3b152e551e98b6897076ec2d34ec88efa80d3303be4f78194bfb673ccb9b46b3082078e149049f
7
- data.tar.gz: bbfb01d2e6cced5b28168e27ada9ee03439ced65463bfcfba86ccf774df888c08167bc515fc4e374560ffa69b67c992e96d87b314fbd534bf47b0006f58b1487
6
+ metadata.gz: 3bcbd2c1d0bbf1de98ecaa786e0e5ee495aacbc25712d8577061e608e79c756501183b5a565f79b4187dca1a883bb1b9d559503f57dbfe354815a3ca615a8cc1
7
+ data.tar.gz: 7ff65051d3508cd2632e26972e94017180610045656c2e054d6a8efaf4f68a8f447183a8622ff45905ccc1b6df45b3c88ca6b3753fefb4ea65ceeeabc8732083
@@ -3,6 +3,6 @@ class EricWeixin::Cms::Weixin::CustomsServiceRecordsController < EricWeixin::Cms
3
3
  def index
4
4
  options = params.permit(:public_account_id, :opercode, :chat_date, :chat_content, :worker, :nick_name)
5
5
  @customs_service_records = ::EricWeixin::CustomsServiceRecord.common_query options
6
- @customs_service_records = @customs_service_records.paginate(page: params[:page], per_page:20)
6
+ @customs_service_records = @customs_service_records.order(:time).paginate(page: params[:page], per_page:20)
7
7
  end
8
8
  end
@@ -9,7 +9,9 @@ class EricWeixin::Cms::Weixin::WeixinUsersController < EricWeixin::Cms::BaseCont
9
9
  :province,
10
10
  :weixin_public_account_id,
11
11
  :start_date,
12
- :end_date)).
12
+ :end_date,
13
+ :first_register_channel,
14
+ :last_register_channel)).
13
15
  order(id: :desc).
14
16
  paginate(page: params[:page]||1, per_page: params[:per_page]||10) unless public_account.blank?
15
17
  end
@@ -12,4 +12,28 @@ class EricWeixin::Wz::PaysController < ApplicationController
12
12
  render text: '您支付失败,请返回重新尝试,谢谢。'
13
13
  end
14
14
 
15
+ # wxappid
16
+ # re_openid
17
+ # total_amount
18
+ # wishing
19
+ # client_ip
20
+ # act_name
21
+ # remark
22
+ # def sendredpack
23
+ # pp "******************* params *********************"
24
+ # pp params
25
+ # weixin_user = ::Weixin::WeixinUser.find_by_openid(params[:openid])
26
+ # public_account = weixin_user.weixin_public_account
27
+ # options = {}
28
+ # options[:wxappid] = public_account.weixin_app_id
29
+ # options[:re_openid] = params[:openid]
30
+ # options[:total_amount] = params[:total_fee]
31
+ # options[:wishing] = "恭喜发财"
32
+ # options[:client_ip] = get_ip
33
+ # options[:act_name] = "送福利"
34
+ # options[:remark] = "第一次送"
35
+ # EricWeixin::Pay.sendredpack options
36
+ # render text: 'ok'
37
+ # end
38
+
15
39
  end
@@ -1,7 +1,7 @@
1
1
  module EricWeixin
2
2
  class AccessToken < ActiveRecord::Base
3
3
 
4
- belongs_to :public_account, :class_name => '::EricWeixin::PublicAccount', foreign_key: :experience_center_id
4
+ belongs_to :public_account, :class_name => '::EricWeixin::PublicAccount', foreign_key: :public_account_id
5
5
 
6
6
  self.table_name = "weixin_access_tokens"
7
7
 
@@ -71,6 +71,10 @@ class EricWeixin::CustomsServiceRecord < ActiveRecord::Base
71
71
  ::EricWeixin::WeixinUser.find_by_openid(self.openid).nickname rescue ''
72
72
  end
73
73
 
74
+ def wixin_user
75
+ ::EricWeixin::WeixinUser.find_by_openid(self.openid)
76
+ end
77
+
74
78
  def self.common_query options
75
79
  records = self.all
76
80
 
@@ -0,0 +1,67 @@
1
+ module EricWeixin
2
+ class JsapiTicket < ActiveRecord::Base
3
+
4
+ belongs_to :public_account, :class_name => '::EricWeixin::PublicAccount', foreign_key: :public_account_id
5
+
6
+ self.table_name = "weixin_jsapi_tickets"
7
+
8
+
9
+ # 获取 jsapi ticket 方法一。根据 APPID 查到微信公众号 PublicAccount.id ,然后
10
+ # 调用 ::EricWeixin::JsapiTicket.get_valid_ticket 获取 jsapi ticket 并作为返回值返回.
11
+ # ===参数说明
12
+ # * app_id #微信公众号的 app_id
13
+ # ===调用示例
14
+ # ::EricWeixin::JsapiTicket.get_valid_jsapi_ticket_by_app_id app_id: 'wx51729870d9012531'
15
+ def self.get_valid_jsapi_ticket_by_app_id options
16
+ pa = ::EricWeixin::PublicAccount.find_by_weixin_app_id options[:app_id]
17
+ ::EricWeixin::JsapiTicket.get_valid_ticket public_account_id: pa.id
18
+ end
19
+
20
+ # 获取 jsapi ticket 方法二。根据微信公众号 PublicAccount.id 获取 jsapi ticket .
21
+ # 若微信公众号未存在 jsapi ticket 或者 jsapi ticket 过期都立即获取新的并返回。
22
+ # ===参数说明
23
+ # * public_account_id #公众账号 ID
24
+ # ===调用示例
25
+ # ::EricWeixin::JsapiTicket.get_valid_ticket public_account_id: 1
26
+ def self.get_valid_ticket options
27
+ self.transaction do
28
+ ticket = ::EricWeixin::JsapiTicket.find_by_public_account_id options[:public_account_id]
29
+ if ticket.blank?
30
+ public_account = ::EricWeixin::PublicAccount.find_by_id options[:public_account_id]
31
+ ticket = ::EricWeixin::JsapiTicket.new jsapi_ticket: get_new_ticket(public_account.id),
32
+ expired_at: Time.now.to_i + 2*60*60,
33
+ public_account_id: public_account.id
34
+ ticket.save!
35
+ end
36
+
37
+ if Time.now.to_i > (ticket.expired_at.to_i - 30)
38
+ ticket.jsapi_ticket = get_new_ticket options[:public_account_id]
39
+ ticket.expired_at = Time.now.to_i + 2*60*60
40
+ ticket.save!
41
+ end
42
+ ticket.reload
43
+ ticket.jsapi_ticket
44
+ end
45
+ end
46
+
47
+ # 根据微信公众号从微信服务器获取最新的 AccessToken.
48
+ # ===参数说明
49
+ # * public_account_id #公众账号 ID
50
+ # ===调用示例
51
+ # ::EricWeixin::AccessToken.get_new_token '5e3b98ca0000959946657212739fd535'
52
+ # https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=12&secret=23
53
+ def self.get_new_ticket public_account_id
54
+ account = ::EricWeixin::PublicAccount.find_by_id public_account_id
55
+ BusinessException.raise 'account 不存在' if account.blank?
56
+ # url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{account.weixin_app_id}&secret=#{account.weixin_secret_key}"
57
+ access_token = ::EricWeixin::AccessToken.get_valid_access_token public_account_id: account.id
58
+ url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=#{access_token}&type=jsapi"
59
+ response = RestClient.get url
60
+ pp response
61
+ JSON.parse(response)["ticket"]
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+
@@ -2,6 +2,7 @@ class EricWeixin::MediaNews < ActiveRecord::Base
2
2
  self.table_name = 'weixin_media_news'
3
3
  has_many :media_article_news, foreign_key: 'weixin_media_news_id'
4
4
  has_many :media_articles, through: :media_article_news
5
+ has_many :media_messages, foreign_key: 'media_news_id'
5
6
  # def upload_news_old
6
7
  #
7
8
  # EricWeixin::MediaNews.transaction do
@@ -77,6 +78,7 @@ class EricWeixin::MediaNews < ActiveRecord::Base
77
78
 
78
79
  def delete_server_news
79
80
  EricWeixin::MediaNews.transaction do
81
+ BusinessException.raise '该图文已经发送出去,不可以删除。' if self.status == 1
80
82
  token = ::EricWeixin::AccessToken.get_valid_access_token public_account_id: self.public_account_id
81
83
  url = "https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=#{token}"
82
84
 
@@ -101,7 +103,7 @@ class EricWeixin::MediaNews < ActiveRecord::Base
101
103
  end
102
104
 
103
105
  def send_to_openids
104
- BusinessException.raise '' if self.media_id.blank?
106
+ BusinessException.raise 'media_id不可以为空。' if self.media_id.blank?
105
107
  EricWeixin::MediaNews.transaction do
106
108
  openids = ::Weixin::Process.__send__ self.user_group_name
107
109
  pp "****************** 将要发送的openids *********************"
@@ -125,7 +127,12 @@ class EricWeixin::MediaNews < ActiveRecord::Base
125
127
  pp response
126
128
  response_json = JSON.parse(response)
127
129
  BusinessException.raise response_json["errmsg"] unless response_json["errcode"] == 0
130
+ media_message = ::EricWeixin::MediaNewsSentRecord.new
131
+ media_message.msg_id = response_json["msg_id"]
132
+ media_message.media_news = self
133
+ media_message.save!
128
134
  end
135
+ self.send_time = Time.now
129
136
  self.status = 1
130
137
  self.save!
131
138
  self.reload
@@ -213,4 +220,22 @@ class EricWeixin::MediaNews < ActiveRecord::Base
213
220
  end
214
221
  end
215
222
 
223
+ def self.update_media_news_after_sending receive_message
224
+ self.transaction do
225
+ msg = EricWeixin::MediaNewsSentRecord.find_by_msg_id(receive_message[:MsgID]||receive_message[:MsgId])
226
+ return if msg.blank?
227
+ msg.update sent_count: receive_message[:SentCount],
228
+ total_count: receive_message[:TotalCount],
229
+ filter_count: receive_message[:FilterCount],
230
+ error_count: receive_message[:ErrorCount],
231
+ status: receive_message[:Status]
232
+ news = msg.media_news
233
+ news.filter_count = (news.filter_count.blank? ? 0 : news.filter_count) + msg.filter_count
234
+ news.total_count = (news.total_count.blank? ? 0 : news.total_count) + msg.total_count
235
+ news.sent_count = (news.sent_count.blank? ? 0 : news.sent_count) + msg.sent_count
236
+ news.error_count = (news.error_count.blank? ? 0 : news.error_count) + msg.error_count
237
+ news.save!
238
+ end
239
+ end
240
+
216
241
  end
@@ -0,0 +1,6 @@
1
+ class EricWeixin::MediaNewsSentRecord < ActiveRecord::Base
2
+ self.table_name = 'weixin_media_news_sent_records'
3
+ belongs_to :media_news, foreign_key: 'media_news_id'
4
+
5
+
6
+ end
@@ -6,6 +6,7 @@ class EricWeixin::PublicAccount < ActiveRecord::Base
6
6
  has_many :two_dimension_codes, :class_name => 'TwoDimensionCode', foreign_key: "weixin_public_account_id"
7
7
  has_one :access_token, :class_name => 'AccessToken', foreign_key: "public_account_id"
8
8
  has_many :customs_service_records, class_name: 'CustomsServiceRecord', foreign_key: "weixin_public_account_id"
9
+ has_many :redpacks, foreign_key: "weixin_public_account_id"
9
10
 
10
11
  #根据微信号名称获取微信账号相关信息
11
12
  # ::EricWeixin::PublicAccount.get_public_account_by_name 'dfxt'
@@ -118,6 +119,33 @@ class EricWeixin::PublicAccount < ActiveRecord::Base
118
119
  end
119
120
  end
120
121
 
122
+ # 获取用户列表,并把最新的用户信息存到数据库.
123
+ # ===参数说明
124
+ # * next_openid #拉取列表的后一个用户的 next_openid,用户列表未拉取完时存在。
125
+ # ===调用示例
126
+ # ::EricWeixin::PublicAccount.first.rebuild_users_simple
127
+ def rebuild_users_simple next_openid = nil
128
+ token = ::EricWeixin::AccessToken.get_valid_access_token public_account_id: self.id
129
+ response = if next_openid.blank?
130
+ RestClient.get "https://api.weixin.qq.com/cgi-bin/user/get?access_token=#{token}"
131
+ else
132
+ RestClient.get "https://api.weixin.qq.com/cgi-bin/user/get?access_token=#{token}&next_openid=#{next_openid}"
133
+ end
134
+ response = JSON.parse response.body
135
+ if response["count"].to_i > 0
136
+ response["data"]["openid"].each do |openid|
137
+ users = ::EricWeixin::WeixinUser.where openid: openid
138
+ if users.blank?
139
+
140
+ ::EricWeixin::WeixinUser.create_weixin_user self.id, openid
141
+
142
+ end
143
+ end
144
+ tmp_next_openid = response["next_openid"]
145
+ self.rebuild_users tmp_next_openid unless tmp_next_openid.blank?
146
+ end
147
+ end
148
+
121
149
 
122
150
  GLOBAL_CODES = {
123
151
  -1 => "系统繁忙",
@@ -0,0 +1,30 @@
1
+ class EricWeixin::Redpack < ActiveRecord::Base
2
+ self.table_name = 'weixin_redpacks'
3
+
4
+ belongs_to :redpack_order, foreign_key: 'weixin_redpack_order_id'
5
+
6
+ STATUS = {
7
+ "SENDING" => "发放中",
8
+ "SENT" => "已发放待领取",
9
+ "FAILED" => "发放失败",
10
+ "RECEIVED" => "已领取",
11
+ "REFUND" => "已退款"
12
+ }
13
+
14
+ def self.create_redpack options
15
+ self.transaction do
16
+ packs = EricWeixin::Redpack.where weixin_redpack_order_id: options[:weixin_redpack_order_id],
17
+ openid: options[:openid]
18
+ return packs[0] unless packs.blank?
19
+
20
+ redpack = self.new status: options[:status],
21
+ openid: options[:openid],
22
+ amount: options[:amount],
23
+ rcv_time: options[:rcv_time],
24
+ weixin_redpack_order_id: options[:weixin_redpack_order_id]
25
+ redpack.save!
26
+ redpack
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,92 @@
1
+ class EricWeixin::RedpackOrder < ActiveRecord::Base
2
+ self.table_name = 'weixin_redpack_orders'
3
+ belongs_to :public_account, foreign_key: "weixin_public_account_id"
4
+ has_many :redpacks, foreign_key: 'weixin_redpack_order_id'
5
+
6
+ SENDTYPE = {
7
+ "API" => "通过API接口发放",
8
+ "UPLOAD" => "通过上传文件方式发放",
9
+ "ACTIVITY" => "通过活动方式发放"
10
+ }
11
+ HBTYPE = {
12
+ "GROUP" => "裂变红包",
13
+ "NORMAL" => "普通红包"
14
+ }
15
+
16
+ validates_presence_of :mch_billno, message: '商户订单号必填。'
17
+
18
+ # ================必填参数===================
19
+ # re_openid
20
+ # total_amount
21
+ # wishing
22
+ # client_ip
23
+ # act_name
24
+ # remark
25
+ # send_name
26
+ # ================选填参数===================
27
+ # wxappid
28
+ # mch_id
29
+ # mch_key
30
+ # total_num
31
+ def self.create_redpack_order options
32
+ self.transaction do
33
+ weixin_user = ::Weixin::WeixinUser.find_by_openid(options[:re_openid])
34
+ public_account = weixin_user.weixin_public_account||EricWeixin::PublicAccount.find_by_weixin_app_id(params[:wxappid])
35
+ BusinessException.raise '查找不到对应的公众号。' if public_account.blank?
36
+ options[:wxappid] = options[:wxappid]||public_account.weixin_app_id
37
+ options[:mch_id] = options[:mch_id]||public_account.mch_id
38
+ options[:total_num] ||= 1
39
+ options[:mch_key] = options[:mch_key]||public_account.mch_key
40
+ result = EricWeixin::Pay.sendredpack options
41
+ pp "*********************** 发红包结果 **************************"
42
+ pp result
43
+ return result['err_code'] if result['return_code'] == 'FAIL'
44
+ redpack_order = self.new
45
+ redpack_order.mch_billno = result['mch_billno']
46
+ redpack_order.weixin_public_account_id = public_account.id
47
+ redpack_order.save!
48
+ redpack_order
49
+ end
50
+ end
51
+
52
+ def get_info
53
+ return unless self.redpacks.blank?
54
+ EricWeixin::RedpackOrder.transaction do
55
+ options = {}
56
+ options[:mch_billno] = self.mch_billno
57
+ options[:mch_id] = self.public_account.mch_id
58
+ options[:appid] = self.public_account.weixin_app_id
59
+ options[:mch_key] = self.public_account.mch_key
60
+ result = EricWeixin::Pay.gethbinfo options
61
+ pp "************************ 查询红包结果 *****************************"
62
+ pp result
63
+ return result['err_code'] if result['return_code'] == 'FAIL'
64
+ self.detail_id = result['detail_id']
65
+ self.send_type = result['send_type']
66
+ self.hb_type = result['hb_type']
67
+ self.total_num = result['total_num']
68
+ self.total_amount = result['total_amount']
69
+ self.reason = result['reason']
70
+ self.send_time = result['send_time']
71
+ self.refund_time = result['refund_time']
72
+ self.refund_amount = result['refund_amount']
73
+ self.wishing = result['wishing']
74
+ self.remark = result['emark']
75
+ self.act_name = result['act_name']
76
+ self.save!
77
+ hbinfo = (result['hblist']['hbinfo'] rescue '')
78
+
79
+ unless hbinfo.blank?
80
+ options[:status] = hbinfo['status']
81
+ options[:openid] = hbinfo['openid']
82
+ options[:amount] = hbinfo['amount']
83
+ options[:rcv_time] = hbinfo['rcv_time']
84
+ options[:weixin_redpack_order_id] = self.id
85
+ EricWeixin::Redpack.create_redpack options
86
+ end
87
+
88
+
89
+ end
90
+ end
91
+
92
+ end
@@ -10,13 +10,13 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
10
10
  validates_presence_of :key_word, message: "关键词不能为空。"
11
11
  validates_presence_of :reply_message, message: "回复信息不能为空。"
12
12
  validates_presence_of :weixin_public_account, message: "对应的微信公众账号不能为空。"
13
- validates_inclusion_of :reply_type, in: REPLY_TYPE_LABEL.collect{|r| r.first}, message: "不正确的回复类型。"
14
- validates_inclusion_of :key_word_type, in: KEY_WORD_TYPE_LABEL.collect{|r| r.first}, message: "不正确的关键词类型。"
15
-
13
+ validates_inclusion_of :reply_type, in: REPLY_TYPE_LABEL.collect { |r| r.first }, message: "不正确的回复类型。"
14
+ validates_inclusion_of :key_word_type, in: KEY_WORD_TYPE_LABEL.collect { |r| r.first }, message: "不正确的关键词类型。"
16
15
 
17
16
 
18
17
  class << self
19
18
 
19
+ #创建匹配规则
20
20
  def create_reply_message_rule options
21
21
  options = get_arguments_options options, [:weixin_public_account_id, :key_word, :reply_message, :key_word_type, :order, :reply_type], is_valid: true
22
22
  ::EricWeixin::ReplyMessageRule.transaction do
@@ -26,6 +26,7 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
26
26
  end
27
27
  end
28
28
 
29
+ # 更新匹配规则
29
30
  def update_reply_message_rule(rule_id, options)
30
31
  options = get_arguments_options options, [:weixin_public_account_id, :key_word, :reply_message, :key_word_type, :order, :reply_type, :is_valid]
31
32
  ::EricWeixin::ReplyMessageRule.transaction do
@@ -37,8 +38,10 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
37
38
  end
38
39
 
39
40
 
40
- #todo xiameng 注释 勾子使用方法
41
+ #处理来自微信端客户所有的处理。
41
42
  def process_rule(receive_message, public_account)
43
+ receive_message_log = receive_message.clone
44
+ receive_message_log[:Content] = CGI::escape(receive_message_log[:Content]) if not receive_message_log[:Content].blank?
42
45
  business_type = "#{receive_message[:MsgType]}~#{receive_message[:Event]}"
43
46
 
44
47
  #兼容腾讯的一个坑....有的是MsgId, 有的是MsgID
@@ -49,7 +52,7 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
49
52
  weixin_public_account_id: public_account.id,
50
53
  message_type: receive_message[:MsgType],
51
54
  message_id: receive_message[:MsgId] || receive_message[:MsgID],
52
- data: receive_message.to_json,
55
+ data: receive_message_log.to_json,
53
56
  process_status: 0, #在这里假设都处理完毕,由业务引起的更新请在工程的Process中进行修改。
54
57
  event_name: receive_message[:Event],
55
58
  event_key: receive_message[:EventKey], #事件值
@@ -59,10 +62,10 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
59
62
  reply_message = case business_type
60
63
  #订阅
61
64
  when /event~subscribe/
62
- ::EricWeixin::WeixinUser.create_weixin_user public_account.id, receive_message[:FromUserName],receive_message[:EventKey]
63
- result = ::Weixin::Process.subscribe receive_message
65
+ user, is_new = ::EricWeixin::WeixinUser.create_weixin_user public_account.id, receive_message[:FromUserName], receive_message[:EventKey]
66
+ result = ::Weixin::Process.subscribe receive_message, is_new
64
67
  if result == true
65
- match_key_words 'subscribe', public_account.id, receive_message
68
+ match_key_words 'subscribe', public_account.id, receive_message, false
66
69
  else
67
70
  result
68
71
  end
@@ -77,16 +80,18 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
77
80
  result
78
81
  end
79
82
 
80
- #点击消息
83
+ #点击消息,点击菜单时响应。
81
84
  when /event~CLICK/
82
85
  result = ::Weixin::Process.click_event receive_message[:EventKey], receive_message
83
86
  if result == true
84
- match_key_words receive_message[:EventKey], public_account.id, receive_message
87
+ match_key_words receive_message[:EventKey], public_account.id, receive_message, false
85
88
  else
86
89
  result
87
90
  end
88
91
 
89
- #点击消息
92
+ #扫描带参数二维码
93
+
94
+
90
95
  when /event~SCAN/
91
96
  result = ::Weixin::Process.scan_event receive_message[:EventKey], receive_message
92
97
  if result == true
@@ -151,11 +156,21 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
151
156
  when /text~/
152
157
  result = ::Weixin::Process.text_event receive_message[:Content], receive_message
153
158
  if result == true
159
+ # if receive_message[:Content] == "我要找客服"
160
+ # ::EricWeixin::ReplyMessage::transfer_mult_customer_service ToUserName: receive_message[:FromUserName],
161
+ # FromUserName: receive_message[:ToUserName]
162
+ # else
154
163
  match_key_words receive_message[:Content], public_account.id, receive_message
164
+ # end
155
165
  else
156
166
  result
157
167
  end
158
168
 
169
+ when /image~/
170
+ result = ::Weixin::Process.image_event receive_message[:Content], receive_message
171
+ if result == true
172
+ ''
173
+ end
159
174
  when /link~/
160
175
  result = ::Weixin::Process.link_event receive_message
161
176
  if result == true
@@ -164,6 +179,11 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
164
179
  result
165
180
  end
166
181
 
182
+ # 群发发送图文推送后,微信服务器返回的结果
183
+ when /event~MASSSENDJOBFINISH/
184
+ ::EricWeixin::MediaNews.update_media_news_after_sending receive_message
185
+ ::Weixin::Process.message_send_job_finish receive_message
186
+ ''
167
187
  #暂时识别不了的消息
168
188
  else
169
189
  "暂时未处理的场景".to_logger
@@ -186,34 +206,116 @@ class EricWeixin::ReplyMessageRule < ActiveRecord::Base
186
206
  reply_message
187
207
  end
188
208
 
189
- def match_key_words wx_key_word, public_account_id, receive_message,need_to_mult_service=true
190
- matched_rule = ::EricWeixin::ReplyMessageRule.order(order: :desc).
191
- where(:key_word => wx_key_word, :weixin_public_account_id => public_account_id, :key_word_type=>(receive_message[:MsgType]||"text")).first
192
- if matched_rule.nil?
193
- # todo 处理正则表达式
194
209
 
195
- if need_to_mult_service
196
- return ::EricWeixin::ReplyMessage::transfer_mult_customer_service ToUserName: receive_message[:FromUserName],
197
- FromUserName: receive_message[:ToUserName]
198
- else
199
- return '' #当匹配不上,也不需要去多客服的时候,就直接返回。
200
- end
210
+ # 用户发送的关键字、 事件关键字匹配处理。
211
+ # 关键字处理分三类: 事件关键字、 正则表达式关键字、 文本严格匹配关键字
212
+ # 关键字匹配好以后,返回类型有三种: 文本、 图文、以及动态运行。
213
+ #
214
+ # need_to_mult_service 如果匹配不到,是否提示转客服。
215
+ def match_key_words wx_key_word, public_account_id, receive_message, need_to_mult_service=true
201
216
 
217
+ message_type = receive_message[:MsgType]||"text"
218
+ reply_message_rule = nil
219
+ case message_type
220
+ when 'event'
221
+ # event类型关键字 event类型关键字不需要匹配正则表达式。
222
+ reply_message_rule = ::EricWeixin::ReplyMessageRule.order(order: :desc).valid.
223
+ where(weixin_public_account_id: public_account_id, key_word_type: 'event', key_word: wx_key_word).first
224
+ else
225
+ # 对于非event类型的关键字, 按照order 的优先级,逐条比对。 如果order相同,文本类型优先。 匹配成功就停止。
226
+ rules = ::EricWeixin::ReplyMessageRule.order(order: :desc).valid.
227
+ where(weixin_public_account_id: public_account_id, key_word_type: ['regularexpr', 'text'])
228
+ rules.each do |rule|
229
+ if rule.key_word_type == 'text'
230
+ if wx_key_word == rule.key_word
231
+ reply_message_rule = rule
232
+ break
233
+ end
234
+ end
235
+ if rule.key_word_type = 'regularexpr'
236
+ regexp = Regexp.new rule.key_word
237
+ result = regexp.match wx_key_word
238
+ unless result.blank?
239
+ reply_message_rule = rule
240
+ break
241
+ end
242
+ end
243
+ end
202
244
  end
203
- reply_msg = case matched_rule.reply_type
204
- when "text"
205
- ::EricWeixin::ReplyMessage.get_reply_user_message_text ToUserName: receive_message[:FromUserName],
206
- FromUserName: receive_message[:ToUserName],
207
- Content: matched_rule.reply_message
208
- when "news"
209
- weixin_news = ::EricWeixin::News.find_by_match_key matched_rule.reply_message
210
- ::EricWeixin::ReplyMessage::get_reply_user_message_image_text ToUserName: receive_message[:FromUserName],
211
- FromUserName: receive_message[:ToUserName],
212
- news: weixin_news.weixin_articles
213
- when "wx_function"
214
- ::Weixin::WeixinAutoReplyFunctions.send(matched_rule.reply_message, ({:key_word => wx_key_word, :receive_message => receive_message}))
245
+
246
+
247
+ # if need_to_mult_service
248
+ # return ::EricWeixin::ReplyMessage::transfer_mult_customer_service ToUserName: receive_message[:FromUserName],
249
+ # FromUserName: receive_message[:ToUserName]
250
+ # else
251
+ # return '' #当匹配不上,也不需要去多客服的时候,就直接返回。
252
+ # end
253
+
254
+
255
+ reply_msg = if reply_message_rule.blank?
256
+ if need_to_mult_service
257
+ # 返回给用户,如何唤醒客服。
258
+ message = ::EricWeixin::ReplyMessageRule.get_contact_customer_notice public_account_id
259
+ if message.blank?
260
+ ''
261
+ else
262
+ ::EricWeixin::ReplyMessage.get_reply_user_message_text ToUserName: receive_message[:FromUserName],
263
+ FromUserName: receive_message[:ToUserName],
264
+ Content: message
265
+ end
266
+ else
267
+ ''
268
+ end
269
+
270
+ else
271
+
272
+ if reply_message_rule.reply_message == 'CONTACT_CUSTOMER_NOTICE'
273
+ ::EricWeixin::ReplyMessage::transfer_mult_customer_service ToUserName: receive_message[:FromUserName],
274
+ FromUserName: receive_message[:ToUserName]
275
+ else
276
+ case reply_message_rule.reply_type
277
+ when "text"
278
+ ::EricWeixin::ReplyMessage.get_reply_user_message_text ToUserName: receive_message[:FromUserName],
279
+ FromUserName: receive_message[:ToUserName],
280
+ Content: reply_message_rule.reply_message
281
+ when "news"
282
+ weixin_news = ::EricWeixin::News.find_by_match_key reply_message_rule.reply_message
283
+ ::EricWeixin::ReplyMessage::get_reply_user_message_image_text ToUserName: receive_message[:FromUserName],
284
+ FromUserName: receive_message[:ToUserName],
285
+ news: weixin_news.weixin_articles
286
+ when "wx_function"
287
+ ::Weixin::WeixinAutoReplyFunctions.send(reply_message_rule.reply_message, ({:key_word => wx_key_word, :receive_message => receive_message}))
288
+ end
289
+ end
215
290
  end
216
291
  reply_msg
217
292
  end
293
+
294
+
295
+ # 获取提示找客服的语句。
296
+ def get_contact_customer_notice public_account_id
297
+ rules = ::EricWeixin::ReplyMessageRule.valid.where weixin_public_account_id: public_account_id,
298
+ key_word_type: 'text',
299
+ key_word: 'CONTACT_CUSTOMER_NOTICE'
300
+ if rules.blank?
301
+ ::EricWeixin::ReplyMessageRule.create_reply_message_rule weixin_public_account_id: public_account_id,
302
+ key_word: 'CONTACT_CUSTOMER_NOTICE',
303
+ reply_message: '请发送:"芝麻开门"来联系客服',
304
+ key_word_type: 'text',
305
+ order: 1,
306
+ reply_type: "text"
307
+
308
+ ::EricWeixin::ReplyMessageRule.create_reply_message_rule weixin_public_account_id: public_account_id,
309
+ key_word: '芝麻开门',
310
+ reply_message: 'CONTACT_CUSTOMER_NOTICE',
311
+ key_word_type: 'text',
312
+ order: 1,
313
+ reply_type: "text"
314
+
315
+ return ::EricWeixin::ReplyMessageRule.get_contact_customer_notice public_account_id
316
+ else
317
+ rules.first.reply_message
318
+ end
319
+ end
218
320
  end
219
321
  end
@@ -37,7 +37,7 @@ class EricWeixin::WeixinUser < ActiveRecord::Base
37
37
  end
38
38
 
39
39
  def nickname
40
- CGI::unescape(self.attributes["nickname"])
40
+ CGI::unescape(self.attributes["nickname"]) rescue '无法正常显示'
41
41
  end
42
42
 
43
43
  ##
@@ -54,7 +54,7 @@ class EricWeixin::WeixinUser < ActiveRecord::Base
54
54
  response.to_debug
55
55
  response = JSON.parse response.body
56
56
  if response["errcode"].to_i == 0
57
- response = ::EricWeixin::WeixinUser.create_weixin_user self.weixin_public_account_id, self.openid
57
+ ::EricWeixin::WeixinUser.create_weixin_user self.weixin_public_account_id, self.openid
58
58
 
59
59
  else
60
60
  BusinessException.raise "设置备注名报错,错误代码为#{response["errcode"]}"
@@ -76,13 +76,17 @@ class EricWeixin::WeixinUser < ActiveRecord::Base
76
76
  # ====返回
77
77
  # 正常情况下返回当前微信用户 <tt>::EricWeixin::WeixinUser</tt>,抛出异常时错误查看异常信息。
78
78
  def create_weixin_user(public_account_id, openid, channel=nil)
79
+ is_new = false
79
80
  public_account = ::EricWeixin::PublicAccount.find_by_id(public_account_id)
80
81
  ::EricWeixin::ReplyMessageRule.transaction do
82
+ is_new = false
81
83
  weixin_user = ::EricWeixin::WeixinUser.where(openid: openid, weixin_public_account_id: public_account.id).first
82
84
  if weixin_user.blank?
85
+ is_new = true
83
86
  weixin_user = ::EricWeixin::WeixinUser.new openid: openid,
84
87
  weixin_public_account_id: public_account.id
85
88
  weixin_user.save!
89
+ is_new = true
86
90
  end
87
91
  wx_user_data = public_account.get_user_data_from_weixin_api openid
88
92
  weixin_user.update_attributes(wx_user_data.select{|k,v| ["subscribe", "openid", "nickname", "sex", "language", "city", "province", "country", "headimgurl", "subscribe_time", "remark"].include? k })
@@ -91,7 +95,7 @@ class EricWeixin::WeixinUser < ActiveRecord::Base
91
95
  weixin_user.last_register_channel = channel
92
96
  weixin_user.save!
93
97
  end
94
- weixin_user
98
+ return weixin_user, is_new
95
99
  end
96
100
  end
97
101
 
@@ -162,6 +166,8 @@ class EricWeixin::WeixinUser < ActiveRecord::Base
162
166
  users = users.where(weixin_public_account_id: options[:weixin_public_account_id]) unless options[:weixin_public_account_id].blank?
163
167
  users = users.where("subscribe_time >= ?", options[:start_date].to_date.to_time.to_i) unless options[:start_date].blank?
164
168
  users = users.where("subscribe_time <= ?", (options[:end_date].to_date+1.day).to_time.to_i) unless options[:end_date].blank?
169
+ users = users.where("last_register_channel = ?", options[:last_register_channel]) unless options[:last_register_channel].blank?
170
+ users = users.where("first_register_channel = ?", options[:first_register_channel]) unless options[:first_register_channel].blank?
165
171
  users
166
172
  end
167
173
  end
@@ -47,12 +47,13 @@
47
47
  <% end %>
48
48
  <table>
49
49
  <thead>
50
- <th width="100">用户</th><th>客服</th><th>聊天类型</th><th>日期时间</th><th>公众号</th><th>聊天内容</th>
50
+ <th width="100">用户</th><th>头像</th><th>客服</th><th>聊天类型</th><th>日期时间</th><th>公众号</th><th>聊天内容</th>
51
51
  </thead>
52
52
  <tbody>
53
53
  <% @customs_service_records.each do |record| %>
54
54
  <tr>
55
55
  <td><%= record.nick_name %></td>
56
+ <td><%= image_tag((record.weixin_user.headimgurl rescue ''), height: '32', width: '32') %></td>
56
57
  <td><%= record.worker %></td>
57
58
  <td><%= ::EricWeixin::CustomsServiceRecord::OPERCODE[record.opercode.to_i] %></td>
58
59
  <td><%= Time.at( record.time.to_i ).chinese_format %></td>
@@ -5,7 +5,7 @@
5
5
  <td><%= media_article.title %></td>
6
6
  <td><img src="<%= media_article.media_resource.local_link %>" width="20" height="20"></td>
7
7
  <td><%= media_article.is_first_article ? '首图文' : '' %></td>
8
- <td><%= link_to '选中️', "javascript:select_this_to_target_news(#{media_article.id})" %></td>
8
+ <td><%= link_to '选中', "javascript:select_this_to_target_news(#{media_article.id})" %></td>
9
9
  </tr>
10
10
  <% end %>
11
11
  </table>
@@ -80,14 +80,14 @@
80
80
  <label class="inline">其他</label>
81
81
  </div>
82
82
  <div class="columns small-6 text-left">
83
- <%= check_box_tag 'do_send[fix_time]', true, false %><label class="inline">定时发送(分钟数请设置为5分钟的整数倍:如10点05分,10点10分)</label>
83
+ <%= check_box_tag 'do_send[fix_time]', true, false %><label class="inline">定时发送(分钟数请设置为5分钟的整数倍)</label>
84
84
  </div>
85
85
  </div>
86
86
  <div class="row">
87
87
  <div class="columns small-offset-6 small-6">
88
88
  <div class="row">
89
89
  <div class="columns small-4">
90
- <label class="inline">定时发送时间:()</label>
90
+ <label class="inline">定时发送时间:</label>
91
91
  </div>
92
92
  <div class="columns small-4">
93
93
  <%= date_field_tag 'send[fix_date]' %>
@@ -13,10 +13,10 @@
13
13
  <td>
14
14
  <%= rule.weixin_public_account_name %>
15
15
  </td>
16
- <td>
16
+ <td style="WORD-BREAK: break-all; WORD-WRAP: break-word">
17
17
  <%= rule.key_word %>
18
18
  </td>
19
- <td>
19
+ <td style="WORD-BREAK: break-all; WORD-WRAP: break-word">
20
20
  <%= rule.reply_message %>
21
21
  </td>
22
22
  <td>
@@ -1,6 +1,6 @@
1
1
  <% @two_dimension_codes.each do |two_dimension_code|%>
2
2
  <tr>
3
- <td><img style="width:60px;height:60px;" src="https://mp.weixin.qq.com/cgi-bin/ showqrcode?ticket=<%= two_dimension_code.ticket %>" %></td>
3
+ <td><img style="width:60px;height:60px;" src="https://mp.weixin.qq.com/cgi-bin/ showqrcode?ticket=<%= two_dimension_code.ticket %>" ></td>
4
4
  <td><%= two_dimension_code.action_info %></td>
5
5
  <td><%= two_dimension_code.scene_str %></td>
6
6
  <td>
@@ -34,7 +34,20 @@
34
34
  <%= text_field_tag :province, params[:province] ,placeholder:"ALL" %>
35
35
  </div>
36
36
 
37
-
37
+ </div>
38
+ <div class="row">
39
+ <div class="columns small-2 text-right">
40
+ <label class="inline">首次关注渠道</label>
41
+ </div>
42
+ <div class="columns small-2">
43
+ <%= text_field_tag :first_register_channel, params[:first_register_channel], placeholder: "ALL" %>
44
+ </div>
45
+ <div class="columns small-2 text-right">
46
+ <label class="inline">最后关注渠道</label>
47
+ </div>
48
+ <div class="columns small-2 end">
49
+ <%= text_field_tag :last_register_channel, params[:last_register_channel], placeholder: "ALL" %>
50
+ </div>
38
51
  </div>
39
52
  <div class="row">
40
53
  <div class="columns small-2 text-right">
@@ -0,0 +1,5 @@
1
+ class AddErrorCountToWeixinMediaNews < ActiveRecord::Migration
2
+ def change
3
+ add_column :weixin_media_news, :error_count, :integer
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class CreateWeixinMediaNewsSentRecords < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_media_news_sent_records do |t|
4
+ t.integer :media_news_id
5
+ t.string :msg_id
6
+ t.integer :sent_count
7
+ t.integer :total_count
8
+ t.integer :filter_count
9
+ t.integer :error_count
10
+ t.string :status
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ class AddPhoneToWeixinUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :weixin_users, :phone, :string
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ class CreateWeixinCustomsServiceRecords < ActiveRecord::Migration
2
+ def change
3
+ execute 'CREATE TABLE `weixin_customs_service_records` (
4
+ `id` int(11) NOT NULL AUTO_INCREMENT,
5
+ `openid` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
6
+ `opercode` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
7
+ `text` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
8
+ `time` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
9
+ `worker` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
10
+ `created_at` datetime DEFAULT NULL,
11
+ `updated_at` datetime DEFAULT NULL,
12
+ `weixin_public_account_id` int(11) DEFAULT NULL,
13
+ PRIMARY KEY (`id`)
14
+ ) ENGINE=InnoDB AUTO_INCREMENT=88 DEFAULT CHARSET=utf8;'
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ class CreateWeixinRedpackOrders < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_redpack_orders do |t|
4
+ t.integer :weixin_public_account_id
5
+ t.string :mch_billno
6
+ t.string :detail_id
7
+ t.string :send_type
8
+ t.string :hb_type
9
+ t.integer :total_num
10
+ t.integer :total_amount
11
+ t.string :reason
12
+ t.datetime :send_time
13
+ t.datetime :refund_time
14
+ t.integer :refund_amount
15
+ t.string :wishing
16
+ t.string :remark
17
+ t.string :act_name
18
+ t.timestamps
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ class CreateWeixinRedpacks < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_redpacks do |t|
4
+ t.integer :weixin_redpack_order_id
5
+ t.string :openid
6
+ t.integer :amount
7
+ t.datetime :rcv_time
8
+ t.string :status
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ class CreateJsapiTickets < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_jsapi_tickets do |t|
4
+ t.string :jsapi_ticket
5
+ t.string :expired_at
6
+ t.integer :public_account_id
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -84,15 +84,17 @@ module EricWeixin::MultCustomer
84
84
  end
85
85
  BusinessException.raise '公众账号未查询到' if pa.blank?
86
86
  token = ::EricWeixin::AccessToken.get_valid_access_token_by_app_id app_id: options[:app_id]
87
-
88
-
87
+ t_options = {}
88
+ options[:data].each do |k,v|
89
+ t_options[k] = CGI::escape(v.gsub("\"","'"))
90
+ end
89
91
  post_data = {
90
92
  :touser => options[:openid],
91
93
  :msgtype => options[:message_type],
92
- options[:message_type] => options[:data]
94
+ options[:message_type] => t_options
93
95
  }
94
96
  url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=#{token}"
95
- response = RestClient.post url, post_data.to_json
97
+ response = RestClient.post url, CGI::unescape(post_data.to_json)
96
98
  response = JSON.parse response.body
97
99
  ::EricWeixin::MessageLog.transaction do
98
100
  message = ::EricWeixin::MessageLog.where(message_id: options[:message_id]).first
@@ -23,9 +23,93 @@ module EricWeixin::Pay
23
23
  end
24
24
 
25
25
  def self.generate_sign options, api_key
26
+ pp "**************** 签名参数 *********************"
27
+ pp options
28
+ pp "**************** api_key *********************"
29
+ pp api_key
26
30
  query = options.sort.map do |k,v|
27
31
  "#{k.to_s}=#{v.to_s}"
28
32
  end.join('&')
29
33
  Digest::MD5.hexdigest("#{query}&key=#{api_key}").upcase
30
34
  end
35
+
36
+ # 参数
37
+ # wxappid
38
+ # re_openid
39
+ # total_amount
40
+ # wishing
41
+ # client_ip
42
+ # act_name
43
+ # remark
44
+ # mch_id
45
+ # send_name
46
+ # total_num
47
+ # mch_key
48
+ def self.sendredpack options
49
+ required_field = %i(wxappid re_openid total_amount wishing client_ip act_name remark mch_id send_name total_num mch_key)
50
+ required_field.each do |p|
51
+ BusinessException.raise "缺少参数:#{p.to_s},且值不可以为空白字符串。" if options[p.to_sym].blank?
52
+ end
53
+
54
+ options[:nonce_str] = SecureRandom.uuid.tr('-', '')
55
+ options[:mch_billno] = options[:mch_id] + Time.now.strftime("%Y%m%d") + Time.now.strftime("%H%M%S") + EricTools.generate_random_string(4,1).to_s
56
+ # 生成签名
57
+ api_key = options[:mch_key]
58
+ options.delete(:mch_key)
59
+ sign = generate_sign options, api_key
60
+ options[:sign] = sign
61
+ # 生成xml数据包
62
+ pay_load = "<xml>#{options.map { |k, v| "<#{k.to_s}>#{v.to_s}</#{k.to_s}>" }.join}</xml>"
63
+ require 'rest-client'
64
+ ca_path = Rails.root.join("ca/").to_s
65
+ Dir.mkdir ca_path unless Dir.exist? ca_path
66
+ BusinessException.raise '请下载证书' unless File.exist?(ca_path+"apiclient_cert.pem") && File.exist?(ca_path+"apiclient_key.pem")
67
+ response = RestClient::Request.execute(method: :post, url: 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack',
68
+ ssl_client_cert: OpenSSL::X509::Certificate.new(File.read(ca_path+"apiclient_cert.pem")),
69
+ ssl_client_key: OpenSSL::PKey::RSA.new(File.read(ca_path+"apiclient_key.pem"), "passphrase, if any"),
70
+ ssl_ciphers: 'AESGCM:!aNULL',
71
+ payload: pay_load)
72
+
73
+ # 分析请求结果
74
+ pp "********************** 发红包 请求结果 ******************************"
75
+ pp response.force_encoding("UTF-8")
76
+ result = Hash.from_xml(response.force_encoding("UTF-8"))
77
+ result['xml']
78
+ end
79
+
80
+ # mch_billno
81
+ # mch_id
82
+ # appid
83
+ # mch_key
84
+ def self.gethbinfo options
85
+ BusinessException.raise '请提供商户订单号。' if options[:mch_billno].blank?
86
+ BusinessException.raise '请提供商户号。' if options[:mch_id].blank?
87
+ BusinessException.raise '请提供公众账号ID。' if options[:appid].blank?
88
+ BusinessException.raise '请提供mch_key。' if options[:mch_key].blank?
89
+ options[:nonce_str] = SecureRandom.uuid.tr('-', '')
90
+ options[:bill_type] = 'MCHT'
91
+
92
+ api_key = options[:mch_key]
93
+ options.delete(:mch_key)
94
+ sign = generate_sign options, api_key
95
+ # sign = generate_sign options, options[:mch_key]
96
+ options[:sign] = sign
97
+
98
+ pay_load = "<xml>#{options.map { |k, v| "<#{k.to_s}>#{v.to_s}</#{k.to_s}>" }.join}</xml>"
99
+ require 'rest-client'
100
+ ca_path = Rails.root.join("ca/").to_s
101
+ Dir.mkdir ca_path unless Dir.exist? ca_path
102
+ BusinessException.raise '请下载证书' unless File.exist?(ca_path+"apiclient_cert.pem") && File.exist?(ca_path+"apiclient_key.pem")
103
+ response = RestClient::Request.execute(method: :post, url: 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo',
104
+ ssl_client_cert: OpenSSL::X509::Certificate.new(File.read(ca_path+"apiclient_cert.pem")),
105
+ ssl_client_key: OpenSSL::PKey::RSA.new(File.read(ca_path+"apiclient_key.pem"), "passphrase, if any"),
106
+ ssl_ciphers: 'AESGCM:!aNULL',
107
+ payload: pay_load)
108
+ # 分析查询红包结果
109
+ pp "********************** 红包查询 结果 ******************************"
110
+ pp response.force_encoding("UTF-8")
111
+ result = Hash.from_xml(response.force_encoding("UTF-8"))
112
+ result['xml']
113
+ end
114
+
31
115
  end
@@ -1,3 +1,3 @@
1
1
  module EricWeixin
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eric_weixin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - 刘晓琦
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-05 00:00:00.000000000 Z
11
+ date: 2015-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 4.1.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.1.4
27
27
  description: 快速开发微信公众账号
@@ -61,13 +61,17 @@ files:
61
61
  - app/models/eric_weixin/article.rb
62
62
  - app/models/eric_weixin/article_news.rb
63
63
  - app/models/eric_weixin/customs_service_record.rb
64
+ - app/models/eric_weixin/jsapi_ticket.rb
64
65
  - app/models/eric_weixin/media_article.rb
65
66
  - app/models/eric_weixin/media_article_news.rb
66
67
  - app/models/eric_weixin/media_news.rb
68
+ - app/models/eric_weixin/media_news_sent_record.rb
67
69
  - app/models/eric_weixin/media_resource.rb
68
70
  - app/models/eric_weixin/message_log.rb
69
71
  - app/models/eric_weixin/news.rb
70
72
  - app/models/eric_weixin/public_account.rb
73
+ - app/models/eric_weixin/redpack.rb
74
+ - app/models/eric_weixin/redpack_order.rb
71
75
  - app/models/eric_weixin/reply_message_rule.rb
72
76
  - app/models/eric_weixin/report/interface_data.rb
73
77
  - app/models/eric_weixin/report/msg_data.rb
@@ -150,6 +154,13 @@ files:
150
154
  - db/migrate/20150818095654_create_weixin_media_news.rb
151
155
  - db/migrate/20150818100348_create_weixin_media_articles_news.rb
152
156
  - db/migrate/20150904045253_add_host_name_to_public_account.rb
157
+ - db/migrate/20150906064203_add_error_count_to_weixin_media_news.rb
158
+ - db/migrate/20150906072855_create_weixin_media_news_sent_records.rb
159
+ - db/migrate/20150908023239_add_phone_to_weixin_users.rb
160
+ - db/migrate/20150910024059_create_weixin_customs_service_records.rb
161
+ - db/migrate/20150911023948_create_weixin_redpack_orders.rb
162
+ - db/migrate/20150911062057_create_weixin_redpacks.rb
163
+ - db/migrate/20150914061051_create_jsapi_tickets.rb
153
164
  - lib/eric_weixin.rb
154
165
  - lib/eric_weixin/engine.rb
155
166
  - lib/eric_weixin/modules/analyze_data.rb