|
|
#encoding: utf-8
|
|
|
require 'base64'
|
|
|
class TrainingsController < ApplicationController
|
|
|
wechat_responder
|
|
|
|
|
|
skip_before_filter :check_if_login_required
|
|
|
skip_before_filter :verify_signature, only: [:show, :create, :update, :test, :enroll]
|
|
|
|
|
|
ROOT_URL = ENV["wechat_url"] || "#{Setting.protocol}://#{Setting.host_name}"
|
|
|
|
|
|
before_filter :authenticate, except: [:auth, :auth_callback, :pay_callback]
|
|
|
|
|
|
before_filter :find_tag_id, only: [:show, :create, :update, :enroll, :test]
|
|
|
|
|
|
before_filter :find_training, only: [:show, :test]
|
|
|
|
|
|
before_filter :valid_training, only: [:pay, :result, :pay_js]
|
|
|
|
|
|
layout 'base_trainings'
|
|
|
|
|
|
|
|
|
# TAG_ID = 'bigdata_hnjcxy_2019'
|
|
|
|
|
|
def show
|
|
|
@training = current_training
|
|
|
|
|
|
url = nil
|
|
|
if @training && !@training.pay?
|
|
|
url = enroll_training_path(id: @tag_id)
|
|
|
elsif @training && @training.pay?
|
|
|
url = result_training_path(id: @tag_id)
|
|
|
else
|
|
|
url = enroll_training_path(id: @tag_id)
|
|
|
end
|
|
|
|
|
|
redirect_to url
|
|
|
end
|
|
|
|
|
|
def enroll
|
|
|
@training = current_training || Training.new
|
|
|
Rails.logger.info("##########training_type:#{@training_type}")
|
|
|
@training_title = @training_type == 3 ? "信息技术新工科产学研联盟师资培训班" : "工程教育认证"
|
|
|
Rails.logger.info("##########training_title:#{@training_title}")
|
|
|
end
|
|
|
|
|
|
def pay
|
|
|
_pay_params
|
|
|
|
|
|
@training = current_training
|
|
|
|
|
|
# 防止重复支付,对于已支付过的,不应该再到这个页来
|
|
|
if @training.payed?
|
|
|
redirect_to result_training_path(id: @tag_id)
|
|
|
return
|
|
|
end
|
|
|
|
|
|
@training.training_payinfo ||= TrainingPayinfo.new
|
|
|
|
|
|
end
|
|
|
|
|
|
def pay_callback
|
|
|
# {"xml"=>{"appid"=>"wx8c5bd82a8a584cf6", "bank_type"=>"CFT", "cash_fee"=>"1", "fee_type"=>"CNY",
|
|
|
# "is_subscribe"=>"Y", "mch_id"=>"1516303811", "nonce_str"=>"c462b28237d5e70261c3171319d86bf5",
|
|
|
# "openid"=>"o5fSc02LFi7LEGCk_ckp6YbegFWs", "out_trade_no"=>"2018101714093870",
|
|
|
# "result_code"=>"SUCCESS", "return_code"=>"SUCCESS", "sign"=>"155D16352B5F2287A32B3121175D8B0B",
|
|
|
# "time_end"=>"20181017140944", "total_fee"=>"1", "trade_type"=>"JSAPI",
|
|
|
# "transaction_id"=>"4200000166201810174468792543"}}
|
|
|
logger.info "pay_callback #{params}"
|
|
|
unless params["xml"]
|
|
|
logger.error "pay_callback error: not found xml"
|
|
|
end
|
|
|
|
|
|
pay = WechatPay.find_by_out_trade_no(params[:xml]["out_trade_no"])
|
|
|
pay.update_attributes!(params[:xml])
|
|
|
|
|
|
training = Training.find(pay.training_id)
|
|
|
training_payinfo = training.training_payinfo
|
|
|
training_payinfo.update_attributes!(status: TrainingPayinfo::Status_Payed,
|
|
|
out_trade_no: pay.out_trade_no)
|
|
|
|
|
|
# 报名成功发送短信
|
|
|
=begin
|
|
|
begin
|
|
|
Trustie::Sms.send(mobile: training.phone,
|
|
|
send_type: "training_pay",
|
|
|
user_name: training.name)
|
|
|
rescue => e
|
|
|
logger.error("pay_callback 短信发送失败: #{e}")
|
|
|
end
|
|
|
=end
|
|
|
|
|
|
render :xml => '' '
|
|
|
<xml>
|
|
|
<return_code><![CDATA[SUCCESS]]></return_code>
|
|
|
<return_msg><![CDATA[OK]]></return_msg>
|
|
|
</xml>
|
|
|
' ''
|
|
|
end
|
|
|
|
|
|
def result
|
|
|
_pay_params
|
|
|
@training = current_training
|
|
|
end
|
|
|
|
|
|
|
|
|
def create
|
|
|
@training = current_training || Training.new(params)
|
|
|
@training.training_type = @training_type
|
|
|
if @training_type == 3
|
|
|
@training.research_field = params[:research_field].select(&:present?).uniq.join(",")
|
|
|
end
|
|
|
@training.openid = session[:wechat_open_id]
|
|
|
@training.save!
|
|
|
|
|
|
redirect_to enroll_training_path(id: @tag_id)
|
|
|
# redirect_to pay_training_path(id: @tag_id)
|
|
|
end
|
|
|
|
|
|
|
|
|
def update
|
|
|
@training = current_training
|
|
|
unless @training
|
|
|
render_404
|
|
|
return
|
|
|
end
|
|
|
|
|
|
@training.assign_attributes(params)
|
|
|
if @training.training_type == 3
|
|
|
@training.research_field = params[:research_field].select(&:present?).uniq.join(",")
|
|
|
end
|
|
|
@training.save!
|
|
|
|
|
|
redirect_to enroll_training_path(id: @tag_id)
|
|
|
# redirect_to pay_training_path(id: @tag_id)
|
|
|
end
|
|
|
|
|
|
|
|
|
# 对应两种情况的信息提交
|
|
|
# 1. 稍后支付
|
|
|
# 2. 立刻支付
|
|
|
# 采用ajax调用方式,返回支付参数
|
|
|
def update_payinfo
|
|
|
@training = current_training
|
|
|
unless @training
|
|
|
render_404
|
|
|
return
|
|
|
end
|
|
|
|
|
|
_pay_params
|
|
|
|
|
|
attachment = nil
|
|
|
if params[:image]
|
|
|
attachment = Attachment.create!(file: params[:image], author: User.first)
|
|
|
end
|
|
|
|
|
|
#修改以前的订单信息
|
|
|
training_info = @training.training_payinfo
|
|
|
if training_info.present?
|
|
|
training_info.update_attributes(params)
|
|
|
else
|
|
|
training_info = TrainingPayinfo.new(params)
|
|
|
end
|
|
|
|
|
|
training_info.num = params[:enlistN].to_i
|
|
|
if training_info.num < 1
|
|
|
training_info.num = 1
|
|
|
end
|
|
|
|
|
|
training_info.fee = (training_info.num * @pay_fee).to_i
|
|
|
|
|
|
training_info.attachment = attachment if attachment.present?
|
|
|
|
|
|
if training_info.pay_type.to_i == TrainingPayinfo::PayType_Wechat
|
|
|
training_info.status = TrainingPayinfo::Status_None
|
|
|
else
|
|
|
training_info.status = TrainingPayinfo::Status_Wait
|
|
|
end
|
|
|
|
|
|
training_info.training_id = @training.id
|
|
|
|
|
|
training_info.save!
|
|
|
|
|
|
if params[:js] == 'true'
|
|
|
_pay_js(training_info.fee)
|
|
|
else
|
|
|
redirect_to url = result_training_path(id: @tag_id)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
|
|
|
### js function
|
|
|
def update_picture
|
|
|
@training = current_training
|
|
|
js_function_call do
|
|
|
attachment = Attachment.create!(file: params[:image], author: User.first)
|
|
|
training_payinfo = @training.training_payinfo
|
|
|
training_payinfo.attachment = attachment
|
|
|
training_payinfo.save!
|
|
|
render json: {status: 0}
|
|
|
end
|
|
|
end
|
|
|
|
|
|
|
|
|
def pay_js
|
|
|
@training = current_training
|
|
|
_pay_js(@training.training_payinfo.fee)
|
|
|
end
|
|
|
|
|
|
#js获取支付参数
|
|
|
def _pay_js(fee)
|
|
|
@training = current_training
|
|
|
js_function_call do
|
|
|
out_trade_no = Wechat.pay.gen_trade_no
|
|
|
#@training.training_payinfo.update_attribute(:out_trade_no, out_trade_no)
|
|
|
#
|
|
|
#
|
|
|
# 写入wechat_pay付费表
|
|
|
WechatPay.create!(training_id: @training.id, out_trade_no: out_trade_no)
|
|
|
render json: {status: 0, data: unifiedorder(out_trade_no, fee)}
|
|
|
end
|
|
|
end
|
|
|
|
|
|
|
|
|
# 用于权限跳转
|
|
|
def auth
|
|
|
state = params[:state]
|
|
|
url = CGI.escape("#{ROOT_URL}/trainings/auth_callback?return_url=#{params[:return_url]}")
|
|
|
authorize_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{url}&response_type=code&scope=snsapi_base&state=#{state}&connect_redirect=1#wechat_redirect"
|
|
|
redirect_to authorize_url
|
|
|
end
|
|
|
|
|
|
def auth_callback
|
|
|
path = Base64.urlsafe_decode64(params[:state])
|
|
|
open_id = get_openid_from_code(params[:code])
|
|
|
unless open_id
|
|
|
render 'wechats/open_wechat', layout: nil and return
|
|
|
end
|
|
|
|
|
|
session[:wechat_open_id] = open_id
|
|
|
|
|
|
redirect_to params[:return_url].present? ? params[:return_url] : '/'
|
|
|
end
|
|
|
|
|
|
def test
|
|
|
|
|
|
end
|
|
|
|
|
|
private
|
|
|
def _pay_params
|
|
|
@pay_fee = Redmine::Configuration['training_fee'].to_f || 5000
|
|
|
end
|
|
|
|
|
|
def authenticate
|
|
|
if Rails.env.development?
|
|
|
# session[:wechat_open_id] = "o5fSc0607iR3rp4-h_VnuBTp8CiM"
|
|
|
end
|
|
|
|
|
|
unless session[:wechat_open_id].present?
|
|
|
redirect_to auth_trainings_path(return_url: CGI.escape(request.path))
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def find_tag_id
|
|
|
@tag_id = params[:tag_id] || params[:id]
|
|
|
Rails.logger.info("##########TAG_ID:#{@tag_id}")
|
|
|
@training_type = @tag_id == "aeee0601_2019" ? 3 : @tag_id == "ceeaa06_2019" ? 4 : 0
|
|
|
render_404 if @training_type == 0
|
|
|
end
|
|
|
|
|
|
def find_training
|
|
|
if params[:id] == @tag_id
|
|
|
@training = current_training
|
|
|
else
|
|
|
render_404
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def current_training
|
|
|
Rails.logger.info("##########openid:#{session[:wechat_open_id]}, training_type: #{@training_type}")
|
|
|
Training.where(openid: session[:wechat_open_id], training_type: @training_type).first
|
|
|
end
|
|
|
|
|
|
def valid_training
|
|
|
unless current_training
|
|
|
redirect_to training_path(id: @tag_id)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def js_function_call
|
|
|
begin
|
|
|
yield if block_given?
|
|
|
rescue => e
|
|
|
render json: {status: 1, msg: e.message}
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def client_ip
|
|
|
request.headers['X-Real-IP'] || request.remote_ip || "127.0.0.1"
|
|
|
end
|
|
|
|
|
|
def get_openid_from_code(code)
|
|
|
openid = session[:wechat_open_id]
|
|
|
unless openid
|
|
|
if code
|
|
|
#不能联系调两次web_access_token 否则会提示请在微信客户端打开次链接
|
|
|
info = wechat.web_access_token(code)
|
|
|
openid = info["openid"]
|
|
|
access_token = info["access_token"]
|
|
|
if access_token
|
|
|
session[:access_token] = access_token
|
|
|
end
|
|
|
refresh_token = info["refresh_token"]
|
|
|
if refresh_token
|
|
|
session[:refresh_token] = refresh_token
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
if openid
|
|
|
session[:wechat_open_id] = openid
|
|
|
end
|
|
|
|
|
|
return openid
|
|
|
end
|
|
|
|
|
|
|
|
|
def unifiedorder(out_trade_no, fee)
|
|
|
@config = {}
|
|
|
|
|
|
output = Wechat.pay.unifiedorder('湖南警察学院大数据培训会-报名费',
|
|
|
(fee * 100).to_i,
|
|
|
session[:wechat_open_id],
|
|
|
client_ip,
|
|
|
out_trade_no)
|
|
|
data = output.fetch("xml")
|
|
|
if data.nil?
|
|
|
raise "获取微信统一单错误"
|
|
|
end
|
|
|
|
|
|
if data["return_code"] != 'SUCCESS'
|
|
|
raise "获取微信统一单错误:#{data["return_msg"]}"
|
|
|
end
|
|
|
|
|
|
|
|
|
@config[:appid] = data["appid"]
|
|
|
@config[:nonce] = data["nonce_str"]
|
|
|
@config[:prepay_id] = data["prepay_id"]
|
|
|
@config[:time] = Time.now.to_i
|
|
|
|
|
|
|
|
|
info = {
|
|
|
appId: @config[:appid],
|
|
|
timeStamp: @config[:time],
|
|
|
nonceStr: @config[:nonce],
|
|
|
package: "prepay_id=#{@config[:prepay_id]}",
|
|
|
signType: 'MD5'
|
|
|
}
|
|
|
@config[:sign] = Wechat.pay.sign(info)
|
|
|
|
|
|
@config
|
|
|
end
|
|
|
|
|
|
end
|