You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pgfqe6ch8/app/controllers/trainings_controller.rb

358 lines
9.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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, except: [:auth, :auth_callback, :pay_callback]
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
@training = current_training
if @training.blank?
redirect_to enroll_training_path(id: @tag_id)
return
end
# 防止重复支付,对于已支付过的,不应该再到这个页来
if @training.payed?
redirect_to result_training_path(id: @tag_id)
return
end
@training.training_payinfo ||= begin
payinfo = TrainingPayinfo.new
payinfo.fee = @training.registration_fee # 默认值价格不对
payinfo
end
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
@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!
flash[:message] = '提交成功'
redirect_to pay_training_path(id: @tag_id)
end
def update
@training = current_training
if @training.blank?
redirect_to enroll_training_path(id: @tag_id)
return
end
@training.assign_attributes(params)
if @training.training_type == 3
@training.research_field = params[:research_field].select(&:present?).uniq.join(",")
end
@training.save!
flash[:message] = '提交成功'
redirect_to pay_training_path(id: @tag_id)
end
# 对应两种情况的信息提交
# 1. 稍后支付
# 2. 立刻支付
# 采用ajax调用方式返回支付参数
def update_payinfo
@training = current_training
if @training.blank?
redirect_to enroll_training_path(id: @tag_id)
return
end
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[:enlistNum].to_i < 1 ? 1 : params[:enlistNum].to_i
training_info.fee = @training.registration_fee(training_info.num)
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'
Rails.logger.info("### start wechat pay => fee: #{training_info.fee}")
_pay_js(0.01 || 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, @training.pay_order_title)}
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 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}")
@_current_training ||= 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, title)
@config = {}
output = Wechat.pay.unifiedorder(title, (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