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

361 lines
8.7 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 :verify_signature, only: [:show, :create, :test]
ROOT_URL = ENV["wechat_url"] || "#{Setting.protocol}://#{Setting.host_name}"
before_filter :authenticate, 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
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::Training_Type
@training.openid = session[:wechat_open_id]
@training.save!
redirect_to pay_training_path(id: TAG_ID)
end
def update
@training = current_training
unless @training
render_404
return
end
@training.update_attributes(params)
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 = "#{ROOT_URL}/trainings/auth_callback"
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
# 考虑状态
# 1. 无记录或未支付
# 2. 已填写未付款
#
@training = current_training
url = ''
if !@training
url = training_path(id: TAG_ID)
elsif !@training.pay?
url = enroll_training_path(id: TAG_ID)
else
url = result_training_path(id: TAG_ID)
end
redirect_to 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
end
end
def find_training
if params[:id] == TAG_ID
@training = current_training
else
render_404
end
end
def current_training
Training.where(openid: session[:wechat_open_id], training_type: Training::Training_Type).first
end
def valid_training
unless current_training
redirect_to training_path(id: TAG_ID)
end
end
private
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