mirror of
https://github.com/kongyuebin1/dongfeng-pay.git
synced 2024-11-13 14:09:20 +08:00
修改网关代码的结构,调整了逻辑,删除了许多无用的代码
This commit is contained in:
parent
706a95317d
commit
2a98cbd9ac
@ -1,6 +1,6 @@
|
||||
appname = jhgateway
|
||||
httpport = 12309
|
||||
runmode = dev
|
||||
runmode = pro
|
||||
|
||||
sessionon = true
|
||||
|
||||
|
@ -16,3 +16,97 @@ const (
|
||||
DB_PASSWORD = "Kyb^15273031604"
|
||||
DB_BASE = "juhe_pay"
|
||||
)
|
||||
|
||||
const (
|
||||
ACTIVE = "active"
|
||||
UNACTIVE = "unactive"
|
||||
DELETE = "delete"
|
||||
REFUND = "refund"
|
||||
ORDERROLL = "order_roll"
|
||||
WAIT = "wait"
|
||||
SUCCESS = "success"
|
||||
FAIL = "fail"
|
||||
YES = "yes"
|
||||
NO = "no"
|
||||
ZERO = 0.0 //0元手续费
|
||||
VERIFY_CODE_LEN = 4 //验证码的长度
|
||||
PAYFOR_FEE = 2.00 //代付手续费
|
||||
PAYFOR_INTERVAL = 5 //每过5分钟执行一次代付
|
||||
|
||||
PLUS_AMOUNT = "plus_amount" //加款操作
|
||||
SUB_AMOUNT = "sub_amount" //减款操作
|
||||
FREEZE_AMOUNT = "freeze_amount" //冻结操作
|
||||
UNFREEZE_AMOUNT = "unfreeze_amount" //解冻操作
|
||||
|
||||
PAYFOR_COMFRIM = "payfor_confirm" //下发带审核
|
||||
PAYFOR_SOLVING = "payfor_solving" //发下处理中
|
||||
PAYFOR_HANDING = "payfor_handing" //手动打款中
|
||||
PAYFOR_BANKING = "payfor_banking" //银行处理中
|
||||
PAYFOR_FAIL = "payfor_fail" //代付失败
|
||||
PAYFOR_SUCCESS = "payfor_success" //代付成功
|
||||
|
||||
PAYFOR_ROAD = "payfor_road" //通道打款
|
||||
PAYFOR_HAND = "payfor_hand" //手动打款
|
||||
PAYFOR_REFUSE = "payfor_refuse" // 拒绝打款
|
||||
|
||||
SELF_API = "self_api" //自助api系统下发
|
||||
SELF_MERCHANT = "self_merchant" //管理手动处理商户下发
|
||||
SELF_HELP = "self_help" //管理自己提现
|
||||
|
||||
PUBLIC = "public" //对公卡
|
||||
PRIVATE = "private" //对私卡
|
||||
)
|
||||
|
||||
const (
|
||||
ICBC = "ICBC"
|
||||
ABC = "ABC"
|
||||
BOC = "BOC"
|
||||
CCB = "CCB"
|
||||
BOCOM = "BOCOM"
|
||||
CNCB = "CNCB"
|
||||
CEB = "CEB"
|
||||
HXB = "HXB"
|
||||
CMBC = "CMBC"
|
||||
GDB = "GDB"
|
||||
CMB = "CMB"
|
||||
CIB = "CIB"
|
||||
SPDB = "SPDB"
|
||||
PSBC = "PSBC"
|
||||
PAB = "PAB"
|
||||
NJCB = "NJCB"
|
||||
NBCB = "NBCB"
|
||||
WZCB = "WZCB"
|
||||
CSCB = "CSCB"
|
||||
CZCB = "CZCB"
|
||||
CCQTGB = "CCQTGB"
|
||||
SHRCB = "SHRCB"
|
||||
BJRCB = "BJRCB"
|
||||
SDB = "SDB"
|
||||
)
|
||||
|
||||
var bankInfo = map[string]string{
|
||||
ICBC: "中国工商银行",
|
||||
ABC: "中国农业银行",
|
||||
BOC: "中国银行",
|
||||
CCB: "中国建设银行",
|
||||
BOCOM: "交通银行",
|
||||
CNCB: "中信银行",
|
||||
CEB: "中国光大银行",
|
||||
HXB: "华夏银行",
|
||||
CMBC: "中国民生银行",
|
||||
GDB: "广发银行",
|
||||
CMB: "招商银行",
|
||||
CIB: "兴业银行",
|
||||
SPDB: "浦发银行",
|
||||
PSBC: "中国邮政储蓄银行",
|
||||
PAB: "平安银行",
|
||||
NJCB: "南京银行",
|
||||
NBCB: "宁波银行",
|
||||
WZCB: "温州市商业银行",
|
||||
CSCB: "长沙银行",
|
||||
CZCB: "浙江稠州商业银行",
|
||||
CCQTGB: "重庆三峡银行",
|
||||
SHRCB: "上海农村商业银行",
|
||||
BJRCB: "北京农商行",
|
||||
SDB: "深圳发展银行",
|
||||
}
|
||||
|
25
gateway/conf/mq_config.go
Normal file
25
gateway/conf/mq_config.go
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/11/6 11:37
|
||||
** @Author : yuebin
|
||||
** @File : mq_config
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/6 11:37
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package conf
|
||||
|
||||
import "net"
|
||||
|
||||
const (
|
||||
mqHost = "127.0.0.1"
|
||||
mqPort = "61613"
|
||||
|
||||
MqOrderQuery = "order_query"
|
||||
MQ_PAYFOR_QUERY = "payfor_query"
|
||||
MqOrderNotify = "order_notify"
|
||||
)
|
||||
|
||||
func GetMQAddress() string {
|
||||
return net.JoinHostPort(mqHost, mqPort)
|
||||
}
|
99
gateway/conf/pay_way_code.go
Normal file
99
gateway/conf/pay_way_code.go
Normal file
@ -0,0 +1,99 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/29 15:01
|
||||
** @Author : yuebin
|
||||
** @File : pay_way_code
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/29 15:01
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package conf
|
||||
|
||||
var ScanPayWayCodes = []string{
|
||||
"WEIXIN_SCAN",
|
||||
"UNION_SCAN",
|
||||
"ALI_SCAN",
|
||||
"BAIDU_SCAN",
|
||||
"JD_SCAN",
|
||||
"QQ_SCAN",
|
||||
}
|
||||
|
||||
var H5PayWayCodes = []string{
|
||||
"WEIXIN_H5",
|
||||
"ALI_H5",
|
||||
"QQ_H5",
|
||||
"UNION_H5",
|
||||
"BAIDU_H5",
|
||||
"JD_H5",
|
||||
}
|
||||
|
||||
var SytPayWayCodes = []string{
|
||||
"WEIXIN_SYT",
|
||||
"ALI_SYT",
|
||||
"QQ_SYT",
|
||||
"UNION_SYT",
|
||||
"BAIDU_SYT",
|
||||
"JD_SYT",
|
||||
}
|
||||
|
||||
var FastPayWayCodes = []string{
|
||||
"UNION-FAST",
|
||||
}
|
||||
|
||||
var WebPayWayCode = []string{
|
||||
"UNION-WAP",
|
||||
}
|
||||
|
||||
func GetScanPayWayCodes() []string {
|
||||
return ScanPayWayCodes
|
||||
}
|
||||
|
||||
func GetNameByPayWayCode(code string) string {
|
||||
switch code {
|
||||
case "WEIXIN_SCAN":
|
||||
return "微信扫码"
|
||||
case "UNION_SCAN":
|
||||
return "银联扫码"
|
||||
case "ALI_SCAN":
|
||||
return "支付宝扫码"
|
||||
case "BAIDU_SCAN":
|
||||
return "百度扫码"
|
||||
case "JD_SCAN":
|
||||
return "京东扫码"
|
||||
case "QQ_SCAN":
|
||||
return "QQ扫码"
|
||||
|
||||
case "WEIXIN_H5":
|
||||
return "微信H5"
|
||||
case "UNION_H5":
|
||||
return "银联H5"
|
||||
case "ALI_H5":
|
||||
return "支付宝H5"
|
||||
case "BAIDU_H5":
|
||||
return "百度H5"
|
||||
case "JD_H5":
|
||||
return "京东H5"
|
||||
case "QQ_H5":
|
||||
return "QQ-H5"
|
||||
|
||||
case "WEIXIN_SYT":
|
||||
return "微信收银台"
|
||||
case "UNION_SYT":
|
||||
return "银联收银台"
|
||||
case "ALI_SYT":
|
||||
return "支付宝收银台"
|
||||
case "BAIDU_SYT":
|
||||
return "百度收银台"
|
||||
case "JD_SYT":
|
||||
return "京东收银台"
|
||||
case "QQ_SYT":
|
||||
return "QQ-收银台"
|
||||
|
||||
case "UNION_FAST":
|
||||
return "银联快捷"
|
||||
case "UNION_WAP":
|
||||
return "银联web"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
48
gateway/controllers/gateway/base_controller.go
Normal file
48
gateway/controllers/gateway/base_controller.go
Normal file
@ -0,0 +1,48 @@
|
||||
/***************************************************
|
||||
** @Desc : 处理下游请求的一些公用的逻辑
|
||||
** @Time : 2019/10/28 18:09
|
||||
** @Author : yuebin
|
||||
** @File : base_gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/28 18:09
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"gateway/response"
|
||||
"gateway/service"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BaseGateway struct {
|
||||
web.Controller
|
||||
}
|
||||
|
||||
//获取商户请求过来的基本参数参数
|
||||
func (c *BaseGateway) PayPrepare() *response.PayBaseResp {
|
||||
params := make(map[string]string)
|
||||
//获取客户端的ip
|
||||
clientIp := c.Ctx.Input.IP()
|
||||
params["orderNo"] = strings.TrimSpace(c.GetString("orderNo"))
|
||||
params["productName"] = strings.TrimSpace(c.GetString("productName"))
|
||||
params["orderPeriod"] = strings.TrimSpace(c.GetString("orderPeriod"))
|
||||
params["orderPrice"] = strings.TrimSpace(c.GetString("orderPrice"))
|
||||
params["payWayCode"] = strings.TrimSpace(c.GetString("payWayCode"))
|
||||
params["osType"] = strings.TrimSpace(c.GetString("osType"))
|
||||
params["notifyUrl"] = strings.TrimSpace(c.GetString("notifyUrl"))
|
||||
//c.Params["returnUrl"] = strings.TrimSpace(c.GetString("returnUrl"))
|
||||
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
p := service.GetMerchantInfo(params)
|
||||
p.ClientIp = clientIp
|
||||
p = service.JudgeParams(p)
|
||||
|
||||
if p.Code != -1 {
|
||||
p.Code = 200
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
@ -1,367 +0,0 @@
|
||||
/***************************************************
|
||||
** @Desc : 处理下游请求的一些公用的逻辑
|
||||
** @Time : 2019/10/28 18:09
|
||||
** @Author : yuebin
|
||||
** @File : base_gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/28 18:09
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/common"
|
||||
"gateway/models"
|
||||
controller "gateway/supplier"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/rs/xid"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BaseGateway struct {
|
||||
beego.Controller
|
||||
Params map[string]string //请求的基本参数
|
||||
ClientIp string //商户ip
|
||||
MerchantInfo models.MerchantInfo //商户信息
|
||||
Msg string //信息
|
||||
Code int //状态码 200正常
|
||||
RoadInfo models.RoadInfo
|
||||
RoadPoolInfo models.RoadPoolInfo
|
||||
OrderAmount float64
|
||||
PayWayCode string
|
||||
PlatformRate float64
|
||||
AgentRate float64
|
||||
}
|
||||
|
||||
//获取商户请求过来的基本参数参数
|
||||
func (c *BaseGateway) PayPrepare() {
|
||||
c.Params = make(map[string]string)
|
||||
//获取客户端的ip
|
||||
c.ClientIp = c.Ctx.Input.IP()
|
||||
c.Params["orderNo"] = strings.TrimSpace(c.GetString("orderNo"))
|
||||
c.Params["productName"] = strings.TrimSpace(c.GetString("productName"))
|
||||
c.Params["orderPeriod"] = strings.TrimSpace(c.GetString("orderPeriod"))
|
||||
c.Params["orderPrice"] = strings.TrimSpace(c.GetString("orderPrice"))
|
||||
c.Params["payWayCode"] = strings.TrimSpace(c.GetString("payWayCode"))
|
||||
c.Params["osType"] = strings.TrimSpace(c.GetString("osType"))
|
||||
c.Params["notifyUrl"] = strings.TrimSpace(c.GetString("notifyUrl"))
|
||||
//c.Params["returnUrl"] = strings.TrimSpace(c.GetString("returnUrl"))
|
||||
c.Params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
|
||||
c.Params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
c.GetMerchantInfo()
|
||||
c.JudgeParams()
|
||||
|
||||
if c.Code != -1 {
|
||||
c.Code = 200
|
||||
}
|
||||
}
|
||||
|
||||
//判断参数的
|
||||
func (c *BaseGateway) JudgeParams() {
|
||||
//c.ReturnUrlIsValid()
|
||||
c.OrderIsValid()
|
||||
c.NotifyUrlIsValid()
|
||||
c.OsTypeIsValid()
|
||||
c.PayWayCodeIsValid()
|
||||
c.ProductIsValid()
|
||||
c.OrderPeriodIsValid()
|
||||
c.IpIsWhite()
|
||||
c.OrderPriceIsValid()
|
||||
}
|
||||
|
||||
func (c *BaseGateway) ReturnUrlIsValid() {
|
||||
if c.Params["returnUrl"] == "" || len(c.Params["returnUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功后跳转地址不能为空"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) NotifyUrlIsValid() {
|
||||
if c.Params["notifyUrl"] == "" || len(c.Params["notifyUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功订单回调地址不能空位"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) OsTypeIsValid() {
|
||||
if c.Params["osType"] == "" || len(c.Params["osType"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付设备系统类型不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) PayWayCodeIsValid() {
|
||||
if c.Params["payWayCode"] == "" || len(c.Params["payWayCode"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付类型字段不能为空"
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.Contains(c.Params["payWayCode"], "SCAN") {
|
||||
c.Code = -1
|
||||
c.Msg = "扫码支付不支持这种支付类型"
|
||||
} else {
|
||||
scanPayWayCodes := common.GetScanPayWayCodes()
|
||||
for _, v := range scanPayWayCodes {
|
||||
if c.Params["payWayCode"] == v {
|
||||
c.PayWayCode = strings.Replace(c.Params["payWayCode"], "-", "_", -1)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Code = -1
|
||||
c.Msg = "不存在这种支付类型,请仔细阅读对接文档"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) ProductIsValid() {
|
||||
if c.Params["productName"] == "" || len(c.Params["productName"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商品描述信息字段不能为空"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) OrderPeriodIsValid() {
|
||||
if c.Params["orderPeriod"] == "" || len(c.Params["orderPeriod"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单过期时间不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
}
|
||||
|
||||
//获取商户信息
|
||||
func (c *BaseGateway) GetMerchantInfo() {
|
||||
merchantInfo := models.GetMerchantByPaykey(c.Params["payKey"])
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户不存在,或者paykey有误,请联系管理员"
|
||||
} else if merchantInfo.Status != common.ACTIVE {
|
||||
c.Code = -1
|
||||
c.Msg = "商户状态已经被冻结或者被删除,请联系管理员!"
|
||||
} else {
|
||||
c.MerchantInfo = merchantInfo
|
||||
}
|
||||
}
|
||||
|
||||
//判断订单金额
|
||||
func (c *BaseGateway) OrderPriceIsValid() {
|
||||
if c.Params["orderPrice"] == "" || len(c.Params["orderPrice"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额不能为空"
|
||||
return
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(c.Params["orderPrice"], 64)
|
||||
if err != nil {
|
||||
logs.Error("order price is invalid: ", c.Params["orderPrice"])
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额非法"
|
||||
}
|
||||
c.OrderAmount = a
|
||||
}
|
||||
|
||||
//判断金额订单号是否为空或者有重复
|
||||
func (c *BaseGateway) OrderIsValid() {
|
||||
if c.Params["orderNo"] == "" || len(c.Params["orderNo"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号不能为空"
|
||||
return
|
||||
}
|
||||
if models.OrderNoIsEixst(c.Params["orderNo"]) {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号重复"
|
||||
}
|
||||
}
|
||||
|
||||
//判断ip是否在白名单中
|
||||
func (c *BaseGateway) IpIsWhite() bool {
|
||||
//TODO
|
||||
return true
|
||||
}
|
||||
|
||||
//选择通道
|
||||
func (c *BaseGateway) ChooseRoad() {
|
||||
payWayCode := c.Params["payWayCode"]
|
||||
merchantUid := c.MerchantInfo.MerchantUid
|
||||
//通道配置信息
|
||||
deployInfo := models.GetMerchantDeployByUidAndPayType(merchantUid, payWayCode)
|
||||
if deployInfo.MerchantUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置"
|
||||
return
|
||||
}
|
||||
|
||||
singleRoad := models.GetRoadInfoByRoadUid(deployInfo.SingleRoadUid)
|
||||
c.RoadPoolInfo = models.GetRoadPoolByRoadPoolCode(deployInfo.RollRoadCode)
|
||||
if c.RoadIsValid(singleRoad) {
|
||||
c.RoadInfo = singleRoad
|
||||
c.PlatformRate = deployInfo.SingleRoadPlatformRate
|
||||
c.AgentRate = deployInfo.SingleRoadAgentRate
|
||||
return
|
||||
}
|
||||
//如果单通道没有有效的,那么寻找通道池里面的通道
|
||||
if c.RoadPoolInfo.RoadPoolCode == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道"
|
||||
return
|
||||
}
|
||||
roadUids := strings.Split(c.RoadPoolInfo.RoadUidPool, "||")
|
||||
roadInfos := models.GetRoadInfosByRoadUids(roadUids)
|
||||
for _, roadInfo := range roadInfos {
|
||||
if c.RoadIsValid(roadInfo) {
|
||||
c.RoadInfo = roadInfo
|
||||
c.PlatformRate = deployInfo.RollRoadPlatformRate
|
||||
c.AgentRate = deployInfo.RollRoadAgentRate
|
||||
return
|
||||
}
|
||||
}
|
||||
if c.RoadInfo.RoadUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道或者通道不可用"
|
||||
}
|
||||
}
|
||||
|
||||
//判断通道是否是合法的
|
||||
func (c *BaseGateway) RoadIsValid(roadInfo models.RoadInfo) bool {
|
||||
if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 {
|
||||
return false
|
||||
}
|
||||
FORMAT := fmt.Sprintf("该通道:%s;", roadInfo.RoadName)
|
||||
if roadInfo.Status != "active" {
|
||||
logs.Notice(FORMAT + "不是激活状态")
|
||||
return false
|
||||
}
|
||||
hour := time.Now().Hour()
|
||||
s := roadInfo.StarHour
|
||||
e := roadInfo.EndHour
|
||||
if hour < s || hour > e {
|
||||
logs.Notice(FORMAT)
|
||||
return false
|
||||
}
|
||||
minAmount := roadInfo.SingleMinLimit
|
||||
maxAmount := roadInfo.SingleMaxLimit
|
||||
if minAmount > c.OrderAmount || maxAmount < c.OrderAmount {
|
||||
logs.Error(FORMAT + "订单金额超限制")
|
||||
return false
|
||||
}
|
||||
todayLimit := roadInfo.TodayLimit
|
||||
totalLimit := roadInfo.TotalLimit
|
||||
todayIncome := roadInfo.TodayIncome
|
||||
totalIncome := roadInfo.TotalIncome
|
||||
if (todayIncome + c.OrderAmount) > todayLimit {
|
||||
logs.Error(FORMAT + "达到了每天金额上限")
|
||||
return false
|
||||
}
|
||||
if (totalIncome + c.OrderAmount) > totalLimit {
|
||||
logs.Error(FORMAT + "达到了总量限制")
|
||||
return false
|
||||
}
|
||||
//如果通道被选中,那么总请求数+1
|
||||
roadInfo.RequestAll = roadInfo.RequestAll + 1
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
models.UpdateRoadInfo(roadInfo)
|
||||
return true
|
||||
}
|
||||
|
||||
//获取基本订单记录
|
||||
func (c *BaseGateway) GetOrderInfo() models.OrderInfo {
|
||||
//6666是自己系统订单号
|
||||
bankOrderNo := "6666" + xid.New().String()
|
||||
//获取支付类型的名称,例如支付宝扫码等
|
||||
payTypeName := common.GetNameByPayWayCode(c.Params["payWayCode"])
|
||||
orderInfo := models.OrderInfo{
|
||||
MerchantUid: c.MerchantInfo.MerchantUid, MerchantName: c.MerchantInfo.MerchantName, MerchantOrderId: c.Params["orderNo"],
|
||||
BankOrderId: bankOrderNo, OrderAmount: c.OrderAmount, FactAmount: c.OrderAmount, ShowAmount: c.OrderAmount,
|
||||
RollPoolCode: c.RoadPoolInfo.RoadPoolCode, RollPoolName: c.RoadPoolInfo.RoadPoolName, RoadUid: c.RoadInfo.RoadUid,
|
||||
RoadName: c.RoadInfo.RoadName, PayProductName: c.RoadInfo.ProductName, ShopName: c.Params["productName"], Freeze: common.NO,
|
||||
Refund: common.NO, Unfreeze: common.NO, PayProductCode: c.RoadInfo.ProductUid, PayTypeCode: c.PayWayCode, PayTypeName: payTypeName,
|
||||
OsType: c.Params["osType"], Status: common.WAIT, NotifyUrl: c.Params["notifyUrl"], ReturnUrl: c.Params["returnUrl"],
|
||||
OrderPeriod: c.Params["orderPeriod"], UpdateTime: utils.GetBasicDateTime(), CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > common.ZERO {
|
||||
orderInfo.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderInfo.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderInfo
|
||||
}
|
||||
|
||||
//计算收益,平台利润,代理利润
|
||||
func (c *BaseGateway) GetOrderProfit(orderInfo models.OrderInfo) models.OrderProfitInfo {
|
||||
//因为所有的手续费率都是百分率,所以需要除以100
|
||||
payTypeName := common.GetNameByPayWayCode(c.PayWayCode)
|
||||
supplierProfit := c.OrderAmount / 100 * c.RoadInfo.BasicFee
|
||||
platformProfit := c.OrderAmount / 100 * c.PlatformRate
|
||||
agentProfit := c.OrderAmount / 100 * c.AgentRate
|
||||
//如果用户没有设置代理,那么代理利润为0.000
|
||||
if c.MerchantInfo.BelongAgentUid == "" || len(c.MerchantInfo.BelongAgentUid) == 0 {
|
||||
agentProfit = common.ZERO
|
||||
}
|
||||
allProfit := supplierProfit + platformProfit + agentProfit
|
||||
|
||||
if allProfit >= c.OrderAmount {
|
||||
logs.Error("手续费已经超过订单金额,bankOrderId = %s", orderInfo.BankOrderId)
|
||||
c.Msg = "手续费已经超过了订单金额"
|
||||
c.Code = -1
|
||||
}
|
||||
orderProfit := models.OrderProfitInfo{
|
||||
PayProductCode: c.RoadInfo.ProductUid, PayProductName: c.RoadInfo.ProductName, PayTypeCode: c.PayWayCode, PayTypeName: payTypeName,
|
||||
Status: common.WAIT, MerchantOrderId: c.Params["orderNo"], BankOrderId: orderInfo.BankOrderId, OrderAmount: c.OrderAmount,
|
||||
FactAmount: c.OrderAmount, ShowAmount: c.OrderAmount, AllProfit: allProfit, UserInAmount: c.OrderAmount - allProfit,
|
||||
SupplierProfit: supplierProfit, PlatformProfit: platformProfit, AgentProfit: agentProfit, UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(), MerchantUid: c.MerchantInfo.MerchantUid, MerchantName: orderInfo.MerchantName,
|
||||
SupplierRate: c.RoadInfo.BasicFee, PlatformRate: c.PlatformRate, AgentRate: c.AgentRate, AgentName: orderInfo.AgentName, AgentUid: orderInfo.AgentUid,
|
||||
}
|
||||
|
||||
//如果该条订单设置了代理利率,并且设置了代理
|
||||
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > common.ZERO {
|
||||
orderProfit.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderProfit.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderProfit
|
||||
}
|
||||
|
||||
/*
|
||||
* 生成订单一系列的记录
|
||||
*/
|
||||
func (c *BaseGateway) GenerateRecord() (models.OrderInfo, models.OrderProfitInfo) {
|
||||
//生成订单记录,订单利润利润
|
||||
orderInfo := c.GetOrderInfo()
|
||||
orderProfit := c.GetOrderProfit(orderInfo)
|
||||
if c.Code == -1 {
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
if !controller.InsertOrderAndOrderProfit(orderInfo, orderProfit) {
|
||||
c.Code = -1
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
logs.Info("插入支付订单记录和支付利润记录成功")
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
|
||||
func (c *BaseGateway) GenerateSuccessData(scanData controller.ScanData) *ScanSuccessData {
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = scanData.OrderNo
|
||||
params["orderPrice"] = scanData.OrderPrice
|
||||
params["payKey"] = c.MerchantInfo.MerchantKey
|
||||
params["payURL"] = scanData.PayUrl
|
||||
params["statusCode"] = "00"
|
||||
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, c.MerchantInfo.MerchantSecret)
|
||||
scanSuccessData := new(ScanSuccessData)
|
||||
|
||||
scanSuccessData.StatusCode = "00"
|
||||
scanSuccessData.PayKey = c.MerchantInfo.MerchantKey
|
||||
scanSuccessData.OrderNo = scanData.OrderNo
|
||||
scanSuccessData.OrderPrice = scanData.OrderPrice
|
||||
scanSuccessData.PayUrl = scanData.PayUrl
|
||||
scanSuccessData.PayKey = c.MerchantInfo.MerchantKey
|
||||
scanSuccessData.Msg = "请求成功"
|
||||
scanSuccessData.Sign = sign
|
||||
|
||||
return scanSuccessData
|
||||
}
|
@ -10,14 +10,14 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
type ErrorGatewayController struct {
|
||||
beego.Controller
|
||||
web.Controller
|
||||
}
|
||||
|
||||
func (c *ErrorGatewayController) ErrorParams() {
|
||||
beego.ReadFromRequest(&c.Controller)
|
||||
web.ReadFromRequest(&c.Controller)
|
||||
c.TplName = "err/params.html"
|
||||
}
|
100
gateway/controllers/gateway/payfor_controller.go
Normal file
100
gateway/controllers/gateway/payfor_controller.go
Normal file
@ -0,0 +1,100 @@
|
||||
/***************************************************
|
||||
** @Desc : 代付、下发金额处理逻辑
|
||||
** @Time : 2019/12/5 14:05
|
||||
** @Author : yuebin
|
||||
** @File : payfor_gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/5 14:05
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/pay_for"
|
||||
"gateway/response"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PayForGateway struct {
|
||||
web.Controller
|
||||
}
|
||||
|
||||
/*
|
||||
* 接受下游商户的代付请求
|
||||
*/
|
||||
func (c *PayForGateway) PayFor() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["realname"] = strings.TrimSpace(c.GetString("realname"))
|
||||
params["cardNo"] = strings.TrimSpace(c.GetString("cardNo"))
|
||||
//params["bankCode"] = strings.TrimSpace(c.GetString("bankCode"))
|
||||
params["accType"] = strings.TrimSpace(c.GetString("accType"))
|
||||
//params["province"] = strings.TrimSpace(c.GetString("province"))
|
||||
//params["city"] = strings.TrimSpace(c.GetString("city"))
|
||||
//params["bankAccountAddress"] = strings.TrimSpace(c.GetString("bankAccountAddress"))
|
||||
params["amount"] = strings.TrimSpace(c.GetString("amount"))
|
||||
//params["mobileNo"] = strings.TrimSpace(c.GetString("mobileNo"))
|
||||
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
payForResponse := new(response.PayForResponse)
|
||||
res, msg := checkParams(params)
|
||||
if !res {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = msg
|
||||
} else {
|
||||
|
||||
payForResponse = pay_for.AutoPayFor(params, conf.SELF_API)
|
||||
}
|
||||
|
||||
c.Data["json"] = payForResponse
|
||||
_ = c.ServeJSON()
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 代付结果查询,
|
||||
*/
|
||||
func (c *PayForGateway) PayForQuery() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp"))
|
||||
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
c.Data["json"] = pay_for.PayForResultQuery(params)
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
/*
|
||||
* 商户查找余额
|
||||
*/
|
||||
func (c *PayForGateway) Balance() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
balanceResponse := new(response.BalanceResponse)
|
||||
res, msg := checkParams(params)
|
||||
if !res {
|
||||
balanceResponse.ResultCode = "-1"
|
||||
balanceResponse.ResultMsg = msg
|
||||
c.Data["json"] = balanceResponse
|
||||
} else {
|
||||
c.Data["json"] = pay_for.BalanceQuery(params)
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
func checkParams(params map[string]string) (bool, string) {
|
||||
for k, v := range params {
|
||||
if v == "" || len(v) == 0 {
|
||||
return false, fmt.Sprintf("字段: %s 为必填!", k)
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/12/5 14:05
|
||||
** @Author : yuebin
|
||||
** @File : payfor_gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/5 14:05
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gateway/common"
|
||||
"gateway/models"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/rs/xid"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PayForGateway struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
type PayForResponse struct {
|
||||
ResultCode string `json:"resultCode,omitempty"`
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
MerchantOrderId string `json:"merchantOrderId,omitempty"`
|
||||
SettAmount string `json:"settAmount,omitempty"`
|
||||
SettFee string `json:"settFee,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
type PayForQueryResponse struct {
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
MerchantOrderId string `json:"merchantOrderId,omitempty"`
|
||||
SettAmount string `json:"settAmount,omitempty"`
|
||||
SettFee string `json:"settFee,omitempty"`
|
||||
SettStatus string `json:"settStatus,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
type BalanceResponse struct {
|
||||
resultCode string `json:"resultCode,omitempty"`
|
||||
balance string `json:"balance,omitempty"`
|
||||
availableAmount string `json:"availableAmount,omitempty"`
|
||||
freezeAmount string `json:"freezeAmount,omitempty"`
|
||||
waitAmount string `json:"waitAmount,omitempty"`
|
||||
loanAmount string `json:"loanAmount,omitempty"`
|
||||
payforAmount string `json:"payforAmount,omitempty"`
|
||||
resultMsg string `json:"resultMsg,omitempty"`
|
||||
sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* 接受下游商户的代付请求
|
||||
*/
|
||||
func (c *PayForGateway) PayFor() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["realname"] = strings.TrimSpace(c.GetString("realname"))
|
||||
params["cardNo"] = strings.TrimSpace(c.GetString("cardNo"))
|
||||
params["bankCode"] = strings.TrimSpace(c.GetString("bankCode"))
|
||||
params["accType"] = strings.TrimSpace(c.GetString("accType"))
|
||||
params["province"] = strings.TrimSpace(c.GetString("province"))
|
||||
params["city"] = strings.TrimSpace(c.GetString("city"))
|
||||
params["bankAccountAddress"] = strings.TrimSpace(c.GetString("bankAccountAddress"))
|
||||
params["amount"] = strings.TrimSpace(c.GetString("amount"))
|
||||
params["moblieNo"] = strings.TrimSpace(c.GetString("moblieNo"))
|
||||
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
payForResponse := new(PayForResponse)
|
||||
res, msg := c.checkParams(params)
|
||||
if !res {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = msg
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
merchantInfo := models.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
logs.Error(fmt.Sprintf("下游商户代付请求,签名失败,商户信息: %+v", merchantInfo))
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "下游商户代付请求,签名失败。"
|
||||
} else {
|
||||
res, msg = c.checkSettAmount(params["amount"])
|
||||
if !res {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = msg
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
exist := models.IsExistPayForByMerchantOrderId(params["merchantOrderId"])
|
||||
if exist {
|
||||
logs.Error(fmt.Sprintf("代付订单号重复:merchantOrderId = %s", params["merchantOrderId"]))
|
||||
payForResponse.ResultMsg = "商户订单号重复"
|
||||
payForResponse.ResultCode = "01"
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
settAmount, _ := strconv.ParseFloat(params["amount"], 64)
|
||||
payFor := models.PayforInfo{PayforUid: "pppp" + xid.New().String(), MerchantUid: merchantInfo.MerchantUid, MerchantName: merchantInfo.MerchantName,
|
||||
MerchantOrderId: params["merchantOrderId"], BankOrderId: "4444" + xid.New().String(), PayforAmount: settAmount, Status: common.PAYFOR_COMFRIM,
|
||||
BankCode: params["bankCode"], BankName: params["bankAccountAddress"], BankAccountName: params["realname"], BankAccountNo: params["cardNo"],
|
||||
BankAccountType: params["accType"], City: params["city"], Ares: params["province"] + params["city"], PhoneNo: params["mobileNo"], Type: common.SELF_API,
|
||||
UpdateTime: utils.GetBasicDateTime(), CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if !models.InsertPayfor(payFor) {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "代付记录插入失败"
|
||||
} else {
|
||||
payForResponse.ResultMsg = "代付订单已生成"
|
||||
payForResponse.ResultCode = "00"
|
||||
payForResponse.SettAmount = params["amount"]
|
||||
payForResponse.MerchantOrderId = params["MerchantOrderId"]
|
||||
|
||||
tmp := make(map[string]string)
|
||||
tmp["resultCode"] = payForResponse.ResultCode
|
||||
tmp["resultMsg"] = payForResponse.ResultMsg
|
||||
tmp["merchantOrderId"] = payForResponse.MerchantOrderId
|
||||
tmp["settAmount"] = payForResponse.SettAmount
|
||||
keys := utils.SortMap(tmp)
|
||||
sign := utils.GetMD5Sign(params, keys, merchantInfo.MerchantSecret)
|
||||
tmp["sign"] = sign
|
||||
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PayForGateway) checkSettAmount(settAmount string) (bool, string) {
|
||||
_, err := strconv.ParseFloat(settAmount, 64)
|
||||
if err != nil {
|
||||
logs.Error(fmt.Sprintf("代付金额有误,settAmount = %s", settAmount))
|
||||
return false, "代付金额有误"
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (c *PayForGateway) checkParams(params map[string]string) (bool, string) {
|
||||
for k, v := range params {
|
||||
if v == "" || len(v) == 0 {
|
||||
return false, fmt.Sprintf("字段: %s 为必填!", k)
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
/*
|
||||
* 代付结果查询,
|
||||
*/
|
||||
func (c *PayForGateway) PayForQuery() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp"))
|
||||
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
query := make(map[string]string)
|
||||
query["merchantOrderId"] = params["merchantOrderId"]
|
||||
merchantInfo := models.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
query["resultMsg"] = "签名错误"
|
||||
query["settStatus"] = "03"
|
||||
query["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
} else {
|
||||
payForInfo := models.GetPayForByMerchantOrderId(params["merchantOrderId"])
|
||||
if payForInfo.BankOrderId == "" {
|
||||
query["resultMsg"] = "不存在这样的代付订单"
|
||||
query["settStatus"] = "03"
|
||||
query["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
} else {
|
||||
switch payForInfo.Status {
|
||||
case common.PAYFOR_BANKING:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case common.PAYFOR_SOLVING:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case common.PAYFOR_COMFRIM:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case common.PAYFOR_SUCCESS:
|
||||
query["resultMsg"] = "打款成功"
|
||||
query["settStatus"] = "00"
|
||||
query["settAmount"] = strconv.FormatFloat(payForInfo.PayforAmount, 'f', 2, 64)
|
||||
query["settFee"] = strconv.FormatFloat(payForInfo.PayforFee, 'f', 2, 64)
|
||||
case common.PAYFOR_FAIL:
|
||||
query["resultMsg"] = "打款失败"
|
||||
query["settStatus"] = "01"
|
||||
}
|
||||
query["sign"] = utils.GetMD5Sign(query, utils.SortMap(query), merchantInfo.MerchantSecret)
|
||||
}
|
||||
}
|
||||
|
||||
mJson, err := json.Marshal(query)
|
||||
if err != nil {
|
||||
logs.Error("PayForQuery json marshal fail:", err)
|
||||
}
|
||||
|
||||
c.Data["json"] = string(mJson)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
/*
|
||||
* 商户查找余额
|
||||
*/
|
||||
func (c *PayForGateway) Balance() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
balanceResponse := new(BalanceResponse)
|
||||
res, msg := c.checkParams(params)
|
||||
if !res {
|
||||
balanceResponse.resultCode = "-1"
|
||||
balanceResponse.resultMsg = msg
|
||||
c.Data["json"] = balanceResponse
|
||||
} else {
|
||||
merchantInfo := models.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
balanceResponse.resultCode = "-1"
|
||||
balanceResponse.resultMsg = "签名错误"
|
||||
c.Data["json"] = balanceResponse
|
||||
} else {
|
||||
accountInfo := models.GetAccountByUid(merchantInfo.MerchantUid)
|
||||
tmp := make(map[string]string)
|
||||
tmp["resultCode"] = "00"
|
||||
tmp["balance"] = strconv.FormatFloat(accountInfo.Balance, 'f', 2, 64)
|
||||
tmp["availableAmount"] = strconv.FormatFloat(accountInfo.SettleAmount, 'f', 2, 64)
|
||||
tmp["freezeAmount"] = strconv.FormatFloat(accountInfo.FreezeAmount, 'f', 2, 64)
|
||||
tmp["waitAmount"] = strconv.FormatFloat(accountInfo.WaitAmount, 'f', 2, 64)
|
||||
tmp["loanAmount"] = strconv.FormatFloat(accountInfo.LoanAmount, 'f', 2, 64)
|
||||
tmp["payforAmount"] = strconv.FormatFloat(accountInfo.PayforAmount, 'f', 2, 64)
|
||||
tmp["resultMsg"] = "查询成功"
|
||||
tmp["sign"] = utils.GetMD5Sign(tmp, utils.SortMap(tmp), merchantInfo.MerchantSecret)
|
||||
mJson, _ := json.Marshal(tmp)
|
||||
c.Data["json"] = string(mJson)
|
||||
}
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
73
gateway/controllers/gateway/scan_controller.go
Normal file
73
gateway/controllers/gateway/scan_controller.go
Normal file
@ -0,0 +1,73 @@
|
||||
/***************************************************
|
||||
** @Desc : 下游请求扫码支付的处理逻辑
|
||||
** @Time : 2019/10/24 11:15
|
||||
** @Author : yuebin
|
||||
** @File : gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/24 11:15
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"gateway/response"
|
||||
"gateway/service"
|
||||
"gateway/supplier/third_party"
|
||||
"gateway/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ScanController struct {
|
||||
BaseGateway
|
||||
}
|
||||
|
||||
//处理错误的返回
|
||||
func (c *ScanController) SolveFailJSON(p *response.PayBaseResp) {
|
||||
scanFailJSON := new(response.ScanFailData)
|
||||
scanFailJSON.StatusCode = "01"
|
||||
scanFailJSON.PayKey = p.Params["payKey"]
|
||||
scanFailJSON.Msg = p.Msg
|
||||
c.Data["json"] = scanFailJSON
|
||||
_ = c.ServeJSON()
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
//处理扫码的请求
|
||||
func (c *ScanController) Scan() {
|
||||
|
||||
p := c.PayPrepare()
|
||||
|
||||
if p.Code == -1 {
|
||||
c.SolveFailJSON(p)
|
||||
}
|
||||
//签名验证
|
||||
p.Params["returnUrl"] = strings.TrimSpace(c.GetString("returnUrl"))
|
||||
paySecret := p.MerchantInfo.MerchantSecret
|
||||
if !utils.Md5Verify(p.Params, paySecret) {
|
||||
p.Code = -1
|
||||
p.Msg = "签名异常"
|
||||
c.SolveFailJSON(p)
|
||||
}
|
||||
//选择通道
|
||||
p = service.ChooseRoad(p)
|
||||
if p.Code == -1 {
|
||||
c.SolveFailJSON(p)
|
||||
}
|
||||
//生成订单记录
|
||||
orderInfo, _ := service.GenerateRecord(p)
|
||||
if p.Code == -1 {
|
||||
c.SolveFailJSON(p)
|
||||
}
|
||||
//获取到对应的上游
|
||||
supplierCode := p.RoadInfo.ProductUid
|
||||
supplier := third_party.GetPaySupplierByCode(supplierCode)
|
||||
scanData := supplier.Scan(orderInfo, p.RoadInfo, p.MerchantInfo)
|
||||
if scanData.Status == "00" {
|
||||
scanSuccessData := service.GenerateSuccessData(scanData, p)
|
||||
c.Data["json"] = scanSuccessData
|
||||
_ = c.ServeJSON()
|
||||
} else {
|
||||
p.Msg = scanData.Msg
|
||||
c.SolveFailJSON(p)
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/***************************************************
|
||||
** @Desc : 下游请求扫码支付的处理逻辑
|
||||
** @Time : 2019/10/24 11:15
|
||||
** @Author : yuebin
|
||||
** @File : gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/24 11:15
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
controller "gateway/supplier"
|
||||
"gateway/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ScanController struct {
|
||||
BaseGateway
|
||||
}
|
||||
|
||||
type ScanSuccessData struct {
|
||||
OrderNo string `json:"orderNo"`
|
||||
Sign string `json:"sign"`
|
||||
OrderPrice string `json:"orderPrice"`
|
||||
PayKey string `json:"payKey"`
|
||||
PayUrl string `json:"payURL"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
type ScanFailData struct {
|
||||
PayKey string `json:"payKey"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
//处理错误的返回
|
||||
func (c *ScanController) SolveFailJSON() {
|
||||
scanFailJSON := new(ScanFailData)
|
||||
scanFailJSON.StatusCode = "01"
|
||||
scanFailJSON.PayKey = c.Params["payKey"]
|
||||
scanFailJSON.Msg = c.Msg
|
||||
c.Data["json"] = scanFailJSON
|
||||
c.ServeJSON()
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
//处理扫码的请求
|
||||
func (c *ScanController) Scan() {
|
||||
|
||||
c.PayPrepare()
|
||||
|
||||
if c.Code == -1 {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//签名验证
|
||||
c.Params["returnUrl"] = strings.TrimSpace(c.GetString("returnUrl"))
|
||||
paySecret := c.MerchantInfo.MerchantSecret
|
||||
if !utils.Md5Verify(c.Params, paySecret) {
|
||||
c.Code = -1
|
||||
c.Msg = "签名异常"
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//选择通道
|
||||
c.ChooseRoad()
|
||||
if c.Code == -1 {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//升级订单记录
|
||||
orderInfo, _ := c.GenerateRecord()
|
||||
if c.Code == -1 {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//获取到对应的上游
|
||||
supplierCode := c.RoadInfo.ProductUid
|
||||
supplier := controller.GetPaySupplierByCode(supplierCode)
|
||||
scanData := supplier.Scan(orderInfo, c.RoadInfo, c.MerchantInfo)
|
||||
if scanData.Status == "00" {
|
||||
scanSuccessData := c.GenerateSuccessData(scanData)
|
||||
c.Data["json"] = scanSuccessData
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
}
|
43
gateway/message/init.go
Normal file
43
gateway/message/init.go
Normal file
@ -0,0 +1,43 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/11/6 11:43
|
||||
** @Author : yuebin
|
||||
** @File : active_mq
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/6 11:43
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package message
|
||||
|
||||
import (
|
||||
"gateway/conf"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/go-stomp/stomp"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
//解决第一个问题的代码
|
||||
var activeConn *stomp.Conn
|
||||
|
||||
var options = []func(*stomp.Conn) error{
|
||||
//设置读写超时,超时时间为1个小时
|
||||
stomp.ConnOpt.HeartBeat(7200*time.Second, 7200*time.Second),
|
||||
stomp.ConnOpt.HeartBeatError(360 * time.Second),
|
||||
}
|
||||
|
||||
func init() {
|
||||
address := conf.GetMQAddress()
|
||||
|
||||
conn, err := stomp.Dial("tcp", address, options...)
|
||||
if err != nil {
|
||||
logs.Error("链接active mq 失败:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
activeConn = conn
|
||||
}
|
||||
|
||||
func GetActiveMQConn() *stomp.Conn {
|
||||
return activeConn
|
||||
}
|
33
gateway/message/send_message.go
Normal file
33
gateway/message/send_message.go
Normal file
@ -0,0 +1,33 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/11/21 15:53
|
||||
** @Author : yuebin
|
||||
** @File : send_message
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/21 15:53
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"os"
|
||||
)
|
||||
|
||||
func SendMessage(topic, message string) {
|
||||
|
||||
conn := GetActiveMQConn()
|
||||
|
||||
if conn == nil {
|
||||
logs.Error("send message get Active mq fail")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err := conn.Send(topic, "text/plain", []byte(message))
|
||||
|
||||
if err != nil {
|
||||
logs.Error("发送消息给activeMQ失败, message=", message)
|
||||
} else {
|
||||
logs.Info("发送消息给activeMQ成功,message=", message)
|
||||
}
|
||||
}
|
119
gateway/models/accounts/account.go
Normal file
119
gateway/models/accounts/account.go
Normal file
@ -0,0 +1,119 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/16 11:11
|
||||
** @Author : yuebin
|
||||
** @File : account
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/16 11:11
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type AccountInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
AccountUid string
|
||||
AccountName string
|
||||
Balance float64 //账户总余额
|
||||
SettleAmount float64 //已经结算的金额
|
||||
LoanAmount float64 //账户押款金额
|
||||
FreezeAmount float64 //账户冻结金额
|
||||
WaitAmount float64 //待结算资金
|
||||
PayforAmount float64 //代付在途金额
|
||||
//AbleBalance float64 //账户可用金额
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ACCOUNT_INFO = "account_info"
|
||||
|
||||
func InsetAcount(account AccountInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&account)
|
||||
if err != nil {
|
||||
logs.Error("insert account fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetAccountByUid(accountUid string) AccountInfo {
|
||||
o := orm.NewOrm()
|
||||
var account AccountInfo
|
||||
_, err := o.QueryTable(ACCOUNT_INFO).Filter("account_uid", accountUid).Limit(1).All(&account)
|
||||
if err != nil {
|
||||
logs.Error("get account by uid fail: ", err)
|
||||
}
|
||||
|
||||
return account
|
||||
}
|
||||
|
||||
func GetAccountLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ACCOUNT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Limit(-1).OrderBy("-update_time").Count()
|
||||
if err != nil {
|
||||
logs.Error("get account len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetAccountByMap(params map[string]string, displayCount, offset int) []AccountInfo {
|
||||
o := orm.NewOrm()
|
||||
var accountList []AccountInfo
|
||||
qs := o.QueryTable(ACCOUNT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&accountList)
|
||||
if err != nil {
|
||||
logs.Error("get account by map fail: ", err)
|
||||
}
|
||||
return accountList
|
||||
}
|
||||
|
||||
func GetAllAccount() []AccountInfo {
|
||||
o := orm.NewOrm()
|
||||
var accountList []AccountInfo
|
||||
|
||||
_, err := o.QueryTable(ACCOUNT_INFO).Limit(-1).All(&accountList)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get all account fail: ", err)
|
||||
}
|
||||
|
||||
return accountList
|
||||
}
|
||||
|
||||
func UpdateAccount(account AccountInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&account)
|
||||
if err != nil {
|
||||
logs.Error("update account fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteAccountByUid(accountUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(ACCOUNT_INFO).Filter("account_uid", accountUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete account fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
69
gateway/models/accounts/account_history_info.go
Normal file
69
gateway/models/accounts/account_history_info.go
Normal file
@ -0,0 +1,69 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/19 14:56
|
||||
** @Author : yuebin
|
||||
** @File : account_history_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/19 14:56
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type AccountHistoryInfo struct {
|
||||
Id int
|
||||
AccountUid string
|
||||
AccountName string
|
||||
Type string
|
||||
Amount float64
|
||||
Balance float64
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ACCOUNT_HISTORY_INFO = "account_history_info"
|
||||
|
||||
func InsertAccountHistory(accountHistory AccountHistoryInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(accountHistory)
|
||||
if err != nil {
|
||||
logs.Error("insert account history fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetAccountHistoryLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ACCOUNT_HISTORY_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get account history len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetAccountHistoryByMap(params map[string]string, displayCount, offset int) []AccountHistoryInfo {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ACCOUNT_HISTORY_INFO)
|
||||
var accountHistoryList []AccountHistoryInfo
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&accountHistoryList)
|
||||
if err != nil {
|
||||
logs.Error("get account history by map fail: ", err)
|
||||
}
|
||||
return accountHistoryList
|
||||
}
|
162
gateway/models/agent/agent_info.go
Normal file
162
gateway/models/agent/agent_info.go
Normal file
@ -0,0 +1,162 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/9/19 14:41
|
||||
** @Author : yuebin
|
||||
** @File : agent_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/9/19 14:41
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package agent
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type AgentInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
AgentName string
|
||||
AgentPassword string
|
||||
PayPassword string
|
||||
AgentRemark string
|
||||
AgentUid string
|
||||
AgentPhone string
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const AGENT_INFO = "agent_info"
|
||||
|
||||
func IsEixstByAgentName(agentName string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(AGENT_INFO).Filter("agent_name", agentName).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func IsExistByAgentUid(uid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(AGENT_INFO).Filter("agent_uid", uid).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func IsEixstByAgentPhone(agentPhone string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(AGENT_INFO).Filter("agent_phone", agentPhone).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func InsertAgentInfo(agentInfo AgentInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&agentInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert agent info fail: ", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func GetAgentInfoByAgentUid(agentUid string) AgentInfo {
|
||||
o := orm.NewOrm()
|
||||
var agentInfo AgentInfo
|
||||
_, err := o.QueryTable(AGENT_INFO).Filter("agent_uid", agentUid).Limit(1).All(&agentInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get agent info by agentUid fail: ", err)
|
||||
}
|
||||
|
||||
return agentInfo
|
||||
}
|
||||
|
||||
func GetAgentInfoByPhone(phone string) AgentInfo {
|
||||
o := orm.NewOrm()
|
||||
var agentInfo AgentInfo
|
||||
_, err := o.QueryTable(AGENT_INFO).Filter("agent_phone", phone).Limit(1).All(&agentInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get agent info by phone fail: ", err)
|
||||
}
|
||||
|
||||
return agentInfo
|
||||
}
|
||||
|
||||
func GetAgentInfoLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(AGENT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get agentinfo len by map fail: ", err)
|
||||
}
|
||||
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetAgentInfoByMap(params map[string]string, displayCount, offset int) []AgentInfo {
|
||||
o := orm.NewOrm()
|
||||
var agentInfoList []AgentInfo
|
||||
|
||||
qs := o.QueryTable(AGENT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&agentInfoList)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get agentInfo by map fail: ", err)
|
||||
}
|
||||
|
||||
return agentInfoList
|
||||
}
|
||||
|
||||
func GetAllAgentByMap(parmas map[string]string) []AgentInfo {
|
||||
o := orm.NewOrm()
|
||||
var agentList []AgentInfo
|
||||
|
||||
qs := o.QueryTable(AGENT_INFO)
|
||||
for k, v := range parmas {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := qs.Limit(-1).All(&agentList)
|
||||
if err != nil {
|
||||
logs.Error("get all agent by map fail: ", err)
|
||||
}
|
||||
|
||||
return agentList
|
||||
}
|
||||
|
||||
func UpdateAgentInfo(agentInfo AgentInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&agentInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("update agentinfo fail: ", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteAgentByAgentUid(agentUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(AGENT_INFO).Filter("agent_uid", agentUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete agent by agent uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
/***************************************************
|
||||
** @Desc : 接受上游通道商的订单结果异步回调
|
||||
** @Time : 2019/11/22 23:27
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/12/17 17:50
|
||||
** @Author : yuebin
|
||||
** @File : supplier_notify
|
||||
** @File : agent_profit
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 23:27
|
||||
** @Last Modified time: 2019/12/17 17:50
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
package agent
|
||||
|
||||
type AgentProfit struct {
|
||||
}
|
@ -12,6 +12,15 @@ package models
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/agent"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/notify"
|
||||
"gateway/models/order"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
"gateway/models/system"
|
||||
"gateway/models/user"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
@ -30,10 +39,23 @@ func init() {
|
||||
|
||||
orm.RegisterDriver("mysql", orm.DRMySQL)
|
||||
orm.RegisterDataBase("default", "mysql", link)
|
||||
orm.RegisterModel(new(UserInfo), new(MenuInfo), new(SecondMenuInfo),
|
||||
new(PowerInfo), new(RoleInfo), new(BankCardInfo), new(RoadInfo),
|
||||
new(RoadPoolInfo), new(AgentInfo), new(MerchantInfo), new(MerchantDeployInfo),
|
||||
new(AccountInfo), new(AccountHistoryInfo), new(OrderInfo), new(OrderProfitInfo),
|
||||
new(OrderSettleInfo), new(NotifyInfo), new(MerchantLoadInfo),
|
||||
new(PayforInfo))
|
||||
orm.RegisterModel(new(user.UserInfo),
|
||||
new(system.MenuInfo),
|
||||
new(system.SecondMenuInfo),
|
||||
new(system.PowerInfo),
|
||||
new(system.RoleInfo),
|
||||
new(system.BankCardInfo),
|
||||
new(road.RoadInfo),
|
||||
new(road.RoadPoolInfo),
|
||||
new(agent.AgentInfo),
|
||||
new(merchant.MerchantInfo),
|
||||
new(merchant.MerchantDeployInfo),
|
||||
new(accounts.AccountInfo),
|
||||
new(accounts.AccountHistoryInfo),
|
||||
new(order.OrderInfo),
|
||||
new(order.OrderProfitInfo),
|
||||
new(order.OrderSettleInfo),
|
||||
new(notify.NotifyInfo),
|
||||
new(merchant.MerchantLoadInfo),
|
||||
new(payfor.PayforInfo))
|
||||
}
|
||||
|
135
gateway/models/merchant/merchant_deploy_info.go
Normal file
135
gateway/models/merchant/merchant_deploy_info.go
Normal file
@ -0,0 +1,135 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/7 11:52
|
||||
** @Author : yuebin
|
||||
** @File : merchant_deploy_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/7 11:52
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type MerchantDeployInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
MerchantUid string
|
||||
PayType string
|
||||
SingleRoadUid string
|
||||
SingleRoadName string
|
||||
SingleRoadPlatformRate float64
|
||||
SingleRoadAgentRate float64
|
||||
RollRoadCode string
|
||||
RollRoadName string
|
||||
RollRoadPlatformRate float64
|
||||
RollRoadAgentRate float64
|
||||
IsLoan string
|
||||
LoanRate float64
|
||||
LoanDays int
|
||||
UnfreezeHour int
|
||||
WaitUnfreezeAmount float64
|
||||
LoanAmount float64
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const MERCHANT_DEPLOY_INFO = "merchant_deploy_info"
|
||||
|
||||
func InsertMerchantDeployInfo(merchantDeployInfo MerchantDeployInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&merchantDeployInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert merchant deploy info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsExistByUidAndPayType(uid, payType string) bool {
|
||||
o := orm.NewOrm()
|
||||
isEixst := o.QueryTable(MERCHANT_DEPLOY_INFO).Filter("merchant_uid", uid).Filter("pay_type", payType).Exist()
|
||||
return isEixst
|
||||
}
|
||||
|
||||
func GetMerchantDeployByUidAndPayType(uid, payType string) MerchantDeployInfo {
|
||||
o := orm.NewOrm()
|
||||
var merchantDeployInfo MerchantDeployInfo
|
||||
_, err := o.QueryTable(MERCHANT_DEPLOY_INFO).Filter("merchant_uid", uid).Filter("pay_type", payType).Limit(1).All(&merchantDeployInfo)
|
||||
if err != nil {
|
||||
logs.Error("get merchant deploy by uid and paytype fail:", err)
|
||||
}
|
||||
return merchantDeployInfo
|
||||
}
|
||||
|
||||
func GetMerchantDeployByUid(uid string) (ms []MerchantDeployInfo) {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(MERCHANT_DEPLOY_INFO).Filter("merchant_uid", uid).All(&ms)
|
||||
if err != nil {
|
||||
logs.Error("get merchant deploy by uid fail:", err)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
|
||||
func GetMerchantDeployByHour(hour int) []MerchantDeployInfo {
|
||||
o := orm.NewOrm()
|
||||
var merchantDeployList []MerchantDeployInfo
|
||||
_, err := o.QueryTable(MERCHANT_DEPLOY_INFO).Filter("unfreeze_hour", hour).Filter("status", "active").Limit(-1).All(&merchantDeployList)
|
||||
if err != nil {
|
||||
logs.Error("get merchant deploy list fail: ", err)
|
||||
}
|
||||
|
||||
return merchantDeployList
|
||||
}
|
||||
func DeleteMerchantDeployByUidAndPayType(uid, payType string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(MERCHANT_DEPLOY_INFO).Filter("merchant_uid", uid).Filter("pay_type", payType).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete merchant deploy by uid and payType fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateMerchantDeploy(merchantDeploy MerchantDeployInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&merchantDeploy)
|
||||
if err != nil {
|
||||
logs.Error("update merchant deploy fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetMerchantDeployLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_DEPLOY_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Count()
|
||||
if err != nil {
|
||||
logs.Error("get merchant deploy len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetMerchantDeployListByMap(params map[string]string, displayCount, offset int) (md []MerchantDeployInfo) {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_DEPLOY_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&md)
|
||||
if err != nil {
|
||||
logs.Error("get merchant deploy list by map fail: ", err)
|
||||
}
|
||||
return md
|
||||
}
|
205
gateway/models/merchant/merchant_info.go
Normal file
205
gateway/models/merchant/merchant_info.go
Normal file
@ -0,0 +1,205 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/9/28 16:47
|
||||
** @Author : yuebin
|
||||
** @File : merchant_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/9/28 16:47
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type MerchantInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
BelongAgentUid string
|
||||
BelongAgentName string
|
||||
MerchantName string
|
||||
MerchantUid string
|
||||
MerchantKey string
|
||||
MerchantSecret string
|
||||
LoginPassword string
|
||||
LoginAccount string
|
||||
AutoSettle string
|
||||
AutoPayFor string
|
||||
WhiteIps string
|
||||
Remark string
|
||||
SinglePayForRoadUid string
|
||||
SinglePayForRoadName string
|
||||
RollPayForRoadCode string
|
||||
RollPayForRoadName string
|
||||
PayforFee float64
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const MERCHANT_INFO = "merchant_info"
|
||||
|
||||
func IsExistByMerchantName(merchantName string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MERCHANT_INFO).Filter("merchant_name", merchantName).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func IsExistByMerchantUid(uid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MERCHANT_INFO).Filter("merchant_uid", uid).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func IsExistMerchantByAgentUid(uid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MERCHANT_INFO).Filter("belong_agent_uid", uid).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func IsExistByMerchantPhone(phone string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MERCHANT_INFO).Filter("LoginAccount", phone).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func GetMerchantByPhone(phone string) (m MerchantInfo) {
|
||||
o := orm.NewOrm()
|
||||
_, e := o.QueryTable(MERCHANT_INFO).Filter("LoginAccount", phone).Limit(1).All(&m)
|
||||
if e != nil {
|
||||
logs.Error("GetMerchantByPhone merchant fail: ", e)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func InsertMerchantInfo(merchantInfo MerchantInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&merchantInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert merchant fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetMerchantLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Count()
|
||||
if err != nil {
|
||||
logs.Error("get merchant len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetMerchantListByMap(params map[string]string, displayCount, offset int) []MerchantInfo {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
var merchantList []MerchantInfo
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&merchantList)
|
||||
if err != nil {
|
||||
logs.Error("get merchant list by map fail: ", err)
|
||||
}
|
||||
return merchantList
|
||||
}
|
||||
|
||||
func GetAllMerchant() []MerchantInfo {
|
||||
o := orm.NewOrm()
|
||||
var merchantList []MerchantInfo
|
||||
|
||||
_, err := o.QueryTable(MERCHANT_INFO).Limit(-1).All(&merchantList)
|
||||
if err != nil {
|
||||
logs.Error("get all merchant fail:", err)
|
||||
}
|
||||
|
||||
return merchantList
|
||||
}
|
||||
|
||||
func GetMerchantByParams(params map[string]string, displayCount, offset int) []MerchantInfo {
|
||||
o := orm.NewOrm()
|
||||
var merchantList []MerchantInfo
|
||||
qs := o.QueryTable(MERCHANT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
qs.Limit(displayCount, offset).All(&merchantList)
|
||||
|
||||
return merchantList
|
||||
}
|
||||
|
||||
func GetMerchantLenByParams(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get merchant len by params fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetMerchantByUid(merchantUid string) MerchantInfo {
|
||||
o := orm.NewOrm()
|
||||
var merchantInfo MerchantInfo
|
||||
_, err := o.QueryTable(MERCHANT_INFO).Filter("merchant_uid", merchantUid).Limit(1).All(&merchantInfo)
|
||||
if err != nil {
|
||||
logs.Error("get merchant info fail: ", err)
|
||||
}
|
||||
return merchantInfo
|
||||
}
|
||||
|
||||
func GetMerchantByPaykey(payKey string) MerchantInfo {
|
||||
o := orm.NewOrm()
|
||||
var merchantInfo MerchantInfo
|
||||
_, err := o.QueryTable(MERCHANT_INFO).Filter("merchant_key", payKey).Limit(1).All(&merchantInfo)
|
||||
if err != nil {
|
||||
logs.Error("get merchant by merchantKey fail: ", err)
|
||||
}
|
||||
return merchantInfo
|
||||
}
|
||||
|
||||
func UpdateMerchant(merchantInfo MerchantInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&merchantInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("update merchant fail: ", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteMerchantByUid(merchantUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(MERCHANT_INFO).Filter("merchant_uid", merchantUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete merchant fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
56
gateway/models/merchant/merchant_load_info.go
Normal file
56
gateway/models/merchant/merchant_load_info.go
Normal file
@ -0,0 +1,56 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/11/22 13:07
|
||||
** @Author : yuebin
|
||||
** @File : merchant_load_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 13:07
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type MerchantLoadInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
MerchantUid string
|
||||
RoadUid string
|
||||
LoadDate string
|
||||
LoadAmount float64
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const MERCHANT_LOAD_INFO = "merchant_load_info"
|
||||
|
||||
func GetMerchantLoadInfoByMap(params map[string]string) []MerchantLoadInfo {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_LOAD_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
var merchantLoadList []MerchantLoadInfo
|
||||
_, err := qs.Limit(-11).All(&merchantLoadList)
|
||||
if err != nil {
|
||||
logs.Error("get merchant load info fail: ", err)
|
||||
}
|
||||
return merchantLoadList
|
||||
}
|
||||
|
||||
func IsExistMerchantLoadByParams(params map[string]string) bool {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MERCHANT_LOAD_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return qs.Exist()
|
||||
}
|
84
gateway/models/notify/notify_info.go
Normal file
84
gateway/models/notify/notify_info.go
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/11/20 13:13
|
||||
** @Author : yuebin
|
||||
** @File : notify_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/20 13:13
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package notify
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type NotifyInfo struct {
|
||||
Id int
|
||||
Type string //订单-order,代付-payfor
|
||||
BankOrderId string
|
||||
MerchantOrderId string
|
||||
Status string
|
||||
Times int
|
||||
Url string
|
||||
Response string
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const NOTIFYINFO = "notify_info"
|
||||
|
||||
func InsertNotifyInfo(notifyInfo NotifyInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(¬ifyInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert notify fail:", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func NotifyInfoExistByBankOrderId(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(NOTIFYINFO).Filter("bank_order_id", bankOrderId).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func GetNotifyInfoByBankOrderId(bankOrderId string) NotifyInfo {
|
||||
o := orm.NewOrm()
|
||||
var notifyInfo NotifyInfo
|
||||
_, err := o.QueryTable(NOTIFYINFO).Filter("bank_order_id", bankOrderId).All(¬ifyInfo)
|
||||
if err != nil {
|
||||
logs.Error("get notify info by bankOrderId fail: ", err)
|
||||
}
|
||||
|
||||
return notifyInfo
|
||||
}
|
||||
|
||||
func GetNotifyInfosNotSuccess(params map[string]interface{}) []NotifyInfo {
|
||||
o := orm.NewOrm()
|
||||
var notifyInfoList []NotifyInfo
|
||||
qs := o.QueryTable(NOTIFYINFO)
|
||||
for k, v := range params {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
qs = qs.Exclude("status", "success")
|
||||
_, err := qs.Limit(-1).All(¬ifyInfoList)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get notifyinfos fail: ", err)
|
||||
}
|
||||
|
||||
return notifyInfoList
|
||||
}
|
||||
|
||||
func UpdateNotifyInfo(notifyInfo NotifyInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(¬ifyInfo)
|
||||
if err != nil {
|
||||
logs.Error("update notify info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
222
gateway/models/order/order_info.go
Normal file
222
gateway/models/order/order_info.go
Normal file
@ -0,0 +1,222 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/28 10:15
|
||||
** @Author : yuebin
|
||||
** @File : order_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/28 10:15
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package order
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type OrderInfo struct {
|
||||
Id int
|
||||
ShopName string //商品名称
|
||||
OrderPeriod string //订单有效时间
|
||||
MerchantOrderId string //商户订单id
|
||||
BankOrderId string //本系统订单id
|
||||
BankTransId string //上游流水id
|
||||
OrderAmount float64 //订单提交的金额
|
||||
ShowAmount float64 //待支付的金额
|
||||
FactAmount float64 //用户实际支付金额
|
||||
RollPoolCode string //轮询池编码
|
||||
RollPoolName string //轮询池名臣
|
||||
RoadUid string //通道标识
|
||||
RoadName string //通道名称
|
||||
PayProductName string //上游支付公司的名称
|
||||
PayProductCode string //上游支付公司的编码代号
|
||||
PayTypeCode string //支付产品编码
|
||||
PayTypeName string //支付产品名称
|
||||
OsType string //操作系统类型
|
||||
Status string //订单支付状态
|
||||
Refund string //退款状态
|
||||
RefundTime string //退款操作时间
|
||||
Freeze string //冻结状态
|
||||
FreezeTime string //冻结时间
|
||||
Unfreeze string //是否已经解冻
|
||||
UnfreezeTime string //解冻时间
|
||||
ReturnUrl string //支付完跳转地址
|
||||
NotifyUrl string //下游回调地址
|
||||
MerchantUid string //商户id
|
||||
MerchantName string //商户名称
|
||||
AgentUid string //该商户所属代理
|
||||
AgentName string //该商户所属代理名称
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ORDER_INFO = "order_info"
|
||||
|
||||
func InsertOrder(orderInfo OrderInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&orderInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert order info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func OrderNoIsEixst(orderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
exits := o.QueryTable(ORDER_INFO).Filter("merchant_order_id", orderId).Exist()
|
||||
return exits
|
||||
}
|
||||
|
||||
func BankOrderIdIsEixst(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
exists := o.QueryTable(ORDER_INFO).Filter("bank_order_id", bankOrderId).Exist()
|
||||
return exists
|
||||
}
|
||||
|
||||
func GetOrderLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ORDER_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, _ := qs.Limit(-1).Count()
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetOrderByMap(params map[string]string, display, offset int) []OrderInfo {
|
||||
o := orm.NewOrm()
|
||||
var orderInfoList []OrderInfo
|
||||
qs := o.QueryTable(ORDER_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(display, offset).OrderBy("-update_time").All(&orderInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get order by map fail: ", err)
|
||||
}
|
||||
return orderInfoList
|
||||
}
|
||||
|
||||
func GetSuccessRateByMap(params map[string]string) string {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ORDER_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
successRate := "0%"
|
||||
allCount, _ := qs.Limit(-1).Count()
|
||||
successCount, _ := qs.Filter("status", "success").Limit(-1).Count()
|
||||
if allCount == 0 {
|
||||
return successRate
|
||||
}
|
||||
tmp := float64(successCount) / float64(allCount) * 100
|
||||
successRate = fmt.Sprintf("%.1f", tmp)
|
||||
return successRate + "%"
|
||||
}
|
||||
|
||||
func GetAllAmountByMap(params map[string]string) float64 {
|
||||
o := orm.NewOrm()
|
||||
condition := "select sum(order_amount) as allAmount from order_info "
|
||||
for _, v := range params {
|
||||
if len(v) > 0 {
|
||||
condition = condition + "where "
|
||||
break
|
||||
}
|
||||
}
|
||||
flag := false
|
||||
if params["create_time__gte"] != "" {
|
||||
flag = true
|
||||
condition = condition + " create_time >= '" + params["create_time__gte"] + "'"
|
||||
}
|
||||
if params["create_time__lte"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + " create_time <= '" + params["create_time__lte"] + "'"
|
||||
}
|
||||
if params["merchant_name__icontains"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + "merchant_name like %'" + params["merchant_name__icontains"] + "'% "
|
||||
}
|
||||
if params["merchant_order_id"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + " merchant_order_id = '" + params["merchant_order_id"] + "'"
|
||||
}
|
||||
if params["bank_order_id"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + " bank_order_id = '" + params["bank_order_id"] + "'"
|
||||
}
|
||||
if params["status"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + "status = '" + params["status"] + "'"
|
||||
}
|
||||
if params["pay_product_code"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + "pay_product_code = " + params["pay_product_code"] + "'"
|
||||
}
|
||||
if params["pay_type_code"] != "" {
|
||||
if flag {
|
||||
condition = condition + " and "
|
||||
}
|
||||
condition = condition + "pay_type_code = " + params["pay_type_code"]
|
||||
}
|
||||
logs.Info("get order amount str = ", condition)
|
||||
var maps []orm.Params
|
||||
allAmount := 0.00
|
||||
num, err := o.Raw(condition).Values(&maps)
|
||||
if err == nil && num > 0 {
|
||||
allAmount, _ = strconv.ParseFloat(maps[0]["allAmount"].(string), 64)
|
||||
}
|
||||
return allAmount
|
||||
}
|
||||
|
||||
func GetOrderByBankOrderId(bankOrderId string) OrderInfo {
|
||||
o := orm.NewOrm()
|
||||
var orderInfo OrderInfo
|
||||
_, err := o.QueryTable(ORDER_INFO).Filter("bank_order_id", bankOrderId).Limit(1).All(&orderInfo)
|
||||
if err != nil {
|
||||
logs.Error("get order info by bankOrderId fail: ", err)
|
||||
}
|
||||
return orderInfo
|
||||
}
|
||||
|
||||
func GetOrderByMerchantOrderId(merchantOrderId string) OrderInfo {
|
||||
o := orm.NewOrm()
|
||||
var orderInfo OrderInfo
|
||||
_, err := o.QueryTable(ORDER_INFO).Filter("merchant_order_id", merchantOrderId).Limit(1).All(&orderInfo)
|
||||
if err != nil {
|
||||
logs.Error("get order by merchant_order_id: ", err.Error())
|
||||
}
|
||||
return orderInfo
|
||||
}
|
||||
|
||||
func GetOneOrder(bankOrderId string) OrderInfo {
|
||||
o := orm.NewOrm()
|
||||
var orderInfo OrderInfo
|
||||
_, err := o.QueryTable(ORDER_INFO).Filter("bank_order_id", bankOrderId).Limit(1).All(&orderInfo)
|
||||
if err != nil {
|
||||
logs.Error("get one order fail: ", err)
|
||||
}
|
||||
|
||||
return orderInfo
|
||||
}
|
120
gateway/models/order/order_profit_info.go
Normal file
120
gateway/models/order/order_profit_info.go
Normal file
@ -0,0 +1,120 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/30 11:44
|
||||
** @Author : yuebin
|
||||
** @File : order_profit_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/30 11:44
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package order
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type OrderProfitInfo struct {
|
||||
Id int
|
||||
MerchantName string
|
||||
MerchantUid string
|
||||
AgentName string
|
||||
AgentUid string
|
||||
PayProductCode string
|
||||
PayProductName string
|
||||
PayTypeCode string
|
||||
PayTypeName string
|
||||
Status string
|
||||
MerchantOrderId string
|
||||
BankOrderId string
|
||||
BankTransId string
|
||||
OrderAmount float64
|
||||
ShowAmount float64
|
||||
FactAmount float64
|
||||
UserInAmount float64
|
||||
SupplierRate float64
|
||||
PlatformRate float64
|
||||
AgentRate float64
|
||||
AllProfit float64
|
||||
SupplierProfit float64
|
||||
PlatformProfit float64
|
||||
AgentProfit float64
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ORDER_PROFIT_INFO = "order_profit_info"
|
||||
|
||||
func GetOrderProfitByBankOrderId(bankOrderId string) OrderProfitInfo {
|
||||
o := orm.NewOrm()
|
||||
var orderProfit OrderProfitInfo
|
||||
_, err := o.QueryTable(ORDER_PROFIT_INFO).Filter("bank_order_id", bankOrderId).Limit(1).All(&orderProfit)
|
||||
if err != nil {
|
||||
logs.Error("GetOrderProfitByBankOrderId fail:", err)
|
||||
}
|
||||
return orderProfit
|
||||
}
|
||||
|
||||
func GetOrderProfitLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ORDER_PROFIT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, _ := qs.Limit(-1).Count()
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetOrderProfitByMap(params map[string]string, display, offset int) []OrderProfitInfo {
|
||||
o := orm.NewOrm()
|
||||
var orderProfitInfoList []OrderProfitInfo
|
||||
qs := o.QueryTable(ORDER_PROFIT_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(display, offset).OrderBy("-update_time").All(&orderProfitInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get order by map fail: ", err)
|
||||
}
|
||||
return orderProfitInfoList
|
||||
}
|
||||
|
||||
/*
|
||||
func GetPlatformProfitByMap(params map[string]string) []models.PlatformProfit {
|
||||
|
||||
o := orm.NewOrm()
|
||||
|
||||
cond := "select merchant_name, agent_name, pay_product_name as supplier_name, pay_type_name, sum(fact_amount) as order_amount, count(1) as order_count, " +
|
||||
"sum(platform_profit) as platform_profit, sum(agent_profit) as agent_profit from " + ORDER_PROFIT_INFO + " where status='success' "
|
||||
flag := false
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
if flag {
|
||||
cond += " and"
|
||||
}
|
||||
if strings.Contains(k, "create_time__gte") {
|
||||
cond = cond + " create_time>='" + v + "'"
|
||||
} else if strings.Contains(k, "create_time__lte") {
|
||||
cond = cond + " create_time<='" + v + "'"
|
||||
} else {
|
||||
cond = cond + " " + k + "='" + v + "'"
|
||||
}
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
|
||||
cond += " group by merchant_uid, agent_uid, pay_product_code, pay_type_code"
|
||||
|
||||
var platformProfitList []models.PlatformProfit
|
||||
_, err := o.Raw(cond).QueryRows(&platformProfitList)
|
||||
if err != nil {
|
||||
logs.Error("get platform profit by map fail:", err)
|
||||
}
|
||||
|
||||
return platformProfitList
|
||||
}
|
||||
*/
|
51
gateway/models/order/order_settle_info.go
Normal file
51
gateway/models/order/order_settle_info.go
Normal file
@ -0,0 +1,51 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/30 11:41
|
||||
** @Author : yuebin
|
||||
** @File : order_settle_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/30 11:41
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package order
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type OrderSettleInfo struct {
|
||||
Id int
|
||||
PayProductCode string
|
||||
PayProductName string
|
||||
PayTypeCode string
|
||||
RoadUid string
|
||||
PayTypeName string
|
||||
MerchantUid string
|
||||
MerchantName string
|
||||
MerchantOrderId string
|
||||
BankOrderId string
|
||||
SettleAmount float64
|
||||
IsAllowSettle string
|
||||
IsCompleteSettle string
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ORDER_SETTLE_INFO = "order_settle_info"
|
||||
|
||||
func GetOrderSettleListByParams(params map[string]string) []OrderSettleInfo {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ORDER_SETTLE_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
var orderSettleList []OrderSettleInfo
|
||||
if _, err := qs.Limit(-1).All(&orderSettleList); err != nil {
|
||||
logs.Error("get order settle list fail: ", err)
|
||||
}
|
||||
|
||||
return orderSettleList
|
||||
}
|
21
gateway/models/order/platform_profit.go
Normal file
21
gateway/models/order/platform_profit.go
Normal file
@ -0,0 +1,21 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/12/17 17:50
|
||||
** @Author : yuebin
|
||||
** @File : platform_profit
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/17 17:50
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package order
|
||||
|
||||
type PlatformProfit struct {
|
||||
MerchantName string
|
||||
AgentName string
|
||||
SupplierName string
|
||||
PayTypeName string
|
||||
OrderAmount float64
|
||||
OrderCount int
|
||||
PlatformProfit float64
|
||||
AgentProfit float64
|
||||
}
|
116
gateway/models/payfor/payfor_info.go
Normal file
116
gateway/models/payfor/payfor_info.go
Normal file
@ -0,0 +1,116 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/11/25 14:32
|
||||
** @Author : yuebin
|
||||
** @File : payfor_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/25 14:32
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package payfor
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type PayforInfo struct {
|
||||
Id int
|
||||
PayforUid string
|
||||
MerchantUid string
|
||||
MerchantName string
|
||||
MerchantOrderId string
|
||||
BankOrderId string
|
||||
BankTransId string
|
||||
RoadUid string
|
||||
RoadName string
|
||||
RollPoolCode string
|
||||
RollPoolName string
|
||||
PayforFee float64
|
||||
PayforAmount float64
|
||||
PayforTotalAmount float64
|
||||
BankCode string
|
||||
BankName string
|
||||
BankAccountName string
|
||||
BankAccountNo string
|
||||
BankAccountType string
|
||||
Country string
|
||||
City string
|
||||
Ares string
|
||||
BankAccountAddress string
|
||||
PhoneNo string
|
||||
GiveType string
|
||||
Type string
|
||||
NotifyUrl string
|
||||
Status string
|
||||
IsSend string
|
||||
RequestTime string
|
||||
ResponseTime string
|
||||
ResponseContent string
|
||||
Remark string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
|
||||
const PAYFORINFO = "payfor_info"
|
||||
|
||||
func InsertPayfor(payFor PayforInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&payFor)
|
||||
if err != nil {
|
||||
logs.Error("insert payfor fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsExistPayForByBankOrderId(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(PAYFORINFO).Filter("bank_order_id", bankOrderId).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func IsExistPayForByMerchantOrderId(merchantOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(PAYFORINFO).Filter("merchant_order_id", merchantOrderId).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func GetPayForByBankOrderId(bankOrderId string) PayforInfo {
|
||||
o := orm.NewOrm()
|
||||
var payFor PayforInfo
|
||||
_, err := o.QueryTable(PAYFORINFO).Filter("bank_order_id", bankOrderId).Limit(1).All(&payFor)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get pay for by bank_order_id fail: ", err)
|
||||
}
|
||||
|
||||
return payFor
|
||||
}
|
||||
|
||||
func GetPayForByMerchantOrderId(merchantOrderId string) PayforInfo {
|
||||
o := orm.NewOrm()
|
||||
var payFor PayforInfo
|
||||
|
||||
_, err := o.QueryTable(PAYFORINFO).Filter("merchant_order_id", merchantOrderId).Limit(1).All(&payFor)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("fail: ", err)
|
||||
}
|
||||
|
||||
return payFor
|
||||
}
|
||||
|
||||
func UpdatePayFor(payFor PayforInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&payFor)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("update pay for fail:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
162
gateway/models/road/road_info.go
Normal file
162
gateway/models/road/road_info.go
Normal file
@ -0,0 +1,162 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/9/8 12:09
|
||||
** @Author : yuebin
|
||||
** @File : road_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/9/8 12:09
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package road
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type RoadInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
RoadName string
|
||||
RoadUid string
|
||||
Remark string
|
||||
ProductName string
|
||||
ProductUid string
|
||||
PayType string
|
||||
BasicFee float64
|
||||
SettleFee float64
|
||||
TotalLimit float64
|
||||
TodayLimit float64
|
||||
SingleMinLimit float64
|
||||
SingleMaxLimit float64
|
||||
StarHour int
|
||||
EndHour int
|
||||
Params string
|
||||
TodayIncome float64
|
||||
TotalIncome float64
|
||||
TodayProfit float64
|
||||
TotalProfit float64
|
||||
Balance float64
|
||||
RequestAll int
|
||||
RequestSuccess int
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ROAD_INFO = "road_info"
|
||||
|
||||
func GetRoadInfoByRoadUid(roadUid string) RoadInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadInfo RoadInfo
|
||||
_, err := o.QueryTable(ROAD_INFO).Exclude("status", "delete").Filter("road_uid", roadUid).Limit(1).All(&roadInfo)
|
||||
if err != nil {
|
||||
logs.Error("get road info by road uid fail: ", err)
|
||||
}
|
||||
return roadInfo
|
||||
}
|
||||
|
||||
func GetRoadInfosByRoadUids(roadUids []string) []RoadInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadInfoList []RoadInfo
|
||||
_, err := o.QueryTable(ROAD_INFO).Filter("road_uid__in", roadUids).OrderBy("update_time").All(&roadInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get roadInfos by roadUids fail: ", err)
|
||||
}
|
||||
return roadInfoList
|
||||
}
|
||||
|
||||
func GetRoadInfoByName(roadName string) RoadInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadInfo RoadInfo
|
||||
_, err := o.QueryTable(ROAD_INFO).Exclude("status", "delete").Filter("road_name", roadName).Limit(1).All(&roadInfo)
|
||||
if err != nil {
|
||||
logs.Error("get road info by name fail: ", err)
|
||||
}
|
||||
return roadInfo
|
||||
}
|
||||
|
||||
func GetRoadLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ROAD_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Exclude("status", "delete").Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get road len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetRoadInfoByMap(params map[string]string, displayCount, offset int) []RoadInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadInfoList []RoadInfo
|
||||
qs := o.QueryTable(ROAD_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := qs.Exclude("status", "delete").Limit(displayCount, offset).OrderBy("-update_time").All(&roadInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get road info by map fail: ", err)
|
||||
}
|
||||
return roadInfoList
|
||||
}
|
||||
|
||||
func GetAllRoad(params map[string]string) []RoadInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadInfoList []RoadInfo
|
||||
qs := o.QueryTable(ROAD_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(-1).All(&roadInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get all road fail: ", err)
|
||||
}
|
||||
return roadInfoList
|
||||
}
|
||||
|
||||
func InsertRoadInfo(roadInfo RoadInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&roadInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("insert road info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func RoadInfoExistByRoadUid(roadUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(ROAD_INFO).Filter("status", "active").Filter("road_uid", roadUid).Exist()
|
||||
|
||||
return exist
|
||||
}
|
||||
|
||||
func UpdateRoadInfo(roadInfo RoadInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&roadInfo)
|
||||
if err != nil {
|
||||
logs.Error("update road info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteRoadByRoadUid(roadUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(ROAD_INFO).Filter("road_uid", roadUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete road by road uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
127
gateway/models/road/road_pool_info.go
Normal file
127
gateway/models/road/road_pool_info.go
Normal file
@ -0,0 +1,127 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/9/9 16:35
|
||||
** @Author : yuebin
|
||||
** @File : road_pool_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/9/9 16:35
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package road
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type RoadPoolInfo struct {
|
||||
Id int
|
||||
Status string
|
||||
RoadPoolName string
|
||||
RoadPoolCode string
|
||||
RoadUidPool string
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const ROAD_POOL_INFO = "road_pool_info"
|
||||
|
||||
func InsertRoadPool(roadPool RoadPoolInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&roadPool)
|
||||
if err != nil {
|
||||
logs.Error("insert road pool fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetRoadPoolLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ROAD_POOL_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get road pool len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetRoadPoolByMap(params map[string]string, displayCount, offset int) []RoadPoolInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadPoolList []RoadPoolInfo
|
||||
qs := o.QueryTable(ROAD_POOL_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&roadPoolList)
|
||||
if err != nil {
|
||||
logs.Error("get road pool by map fail: ", err)
|
||||
}
|
||||
return roadPoolList
|
||||
}
|
||||
|
||||
func GetRoadPoolByRoadPoolCode(roadPoolCode string) RoadPoolInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadPoolInfo RoadPoolInfo
|
||||
_, err := o.QueryTable(ROAD_POOL_INFO).Filter("road_pool_code", roadPoolCode).Limit(1).All(&roadPoolInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get road pool info by road pool code fail: ", err)
|
||||
}
|
||||
|
||||
return roadPoolInfo
|
||||
}
|
||||
|
||||
func GetAllRollPool(params map[string]string) []RoadPoolInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadPoolList []RoadPoolInfo
|
||||
qs := o.QueryTable(ROAD_POOL_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(-1).All(&roadPoolList)
|
||||
if err != nil {
|
||||
logs.Error("get all roll pool fail: ", err)
|
||||
}
|
||||
return roadPoolList
|
||||
}
|
||||
|
||||
func GetRoadPoolByName(roadPoolName string) RoadPoolInfo {
|
||||
o := orm.NewOrm()
|
||||
var roadPoolInfo RoadPoolInfo
|
||||
_, err := o.QueryTable(ROAD_POOL_INFO).Filter("road_pool_name", roadPoolName).Limit(1).All(&roadPoolInfo)
|
||||
if err != nil {
|
||||
logs.Error("get road pool by name fail: ", err)
|
||||
}
|
||||
return roadPoolInfo
|
||||
}
|
||||
|
||||
func DeleteRoadPoolByCode(roadPoolCode string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(ROAD_POOL_INFO).Filter("road_pool_code", roadPoolCode).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete road pool by code fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateRoadPool(roadPool RoadPoolInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&roadPool)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("update road pool fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
106
gateway/models/system/bank_card_info.go
Normal file
106
gateway/models/system/bank_card_info.go
Normal file
@ -0,0 +1,106 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/9/6 10:19
|
||||
** @Author : yuebin
|
||||
** @File : bank_card_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/9/6 10:19
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type BankCardInfo struct {
|
||||
Id int
|
||||
Uid string
|
||||
UserName string
|
||||
BankName string
|
||||
BankCode string
|
||||
BankAccountType string
|
||||
AccountName string
|
||||
BankNo string
|
||||
IdentifyCard string
|
||||
CertificateNo string
|
||||
PhoneNo string
|
||||
BankAddress string
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
const BANK_CARD_INFO = "bank_card_info"
|
||||
|
||||
func InsertBankCardInfo(bankCardInfo BankCardInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&bankCardInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("insert bank card info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetBankCardLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(BANK_CARD_INFO)
|
||||
for k, v := range params {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get bank card len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetBankCardByMap(params map[string]string, displayCount, offset int) []BankCardInfo {
|
||||
o := orm.NewOrm()
|
||||
var bankCardList []BankCardInfo
|
||||
qs := o.QueryTable(BANK_CARD_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&bankCardList)
|
||||
if err != nil {
|
||||
logs.Error("get bank card by map fail: ", err)
|
||||
}
|
||||
return bankCardList
|
||||
}
|
||||
|
||||
func GetBankCardByUid(uid string) BankCardInfo {
|
||||
o := orm.NewOrm()
|
||||
var bankCardInfo BankCardInfo
|
||||
_, err := o.QueryTable(bankCardInfo).Filter("uid", uid).Limit(1).All(&bankCardInfo)
|
||||
if err != nil {
|
||||
logs.Error("get bank card by uid fail: ", err)
|
||||
}
|
||||
|
||||
return bankCardInfo
|
||||
}
|
||||
|
||||
func DeleteBankCardByUid(uid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(BANK_CARD_INFO).Filter("uid", uid).Delete()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("delete bank card by uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateBankCard(bankCard BankCardInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&bankCard)
|
||||
if err != nil {
|
||||
logs.Error("update bank card fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
179
gateway/models/system/menu_info.go
Normal file
179
gateway/models/system/menu_info.go
Normal file
@ -0,0 +1,179 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/8/21 9:33
|
||||
** @Author : yuebin
|
||||
** @File : menu_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/8/21 9:33
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type MenuInfo struct {
|
||||
Id int
|
||||
MenuOrder int
|
||||
MenuUid string
|
||||
FirstMenu string
|
||||
SecondMenu string
|
||||
Creater string
|
||||
Status string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
|
||||
//实现排序的三个接口函数
|
||||
type MenuInfoSlice []MenuInfo
|
||||
|
||||
func (m MenuInfoSlice) Len() int {
|
||||
return len(m)
|
||||
}
|
||||
|
||||
func (m MenuInfoSlice) Swap(i, j int) {
|
||||
m[i], m[j] = m[j], m[i]
|
||||
}
|
||||
|
||||
func (m MenuInfoSlice) Less(i, j int) bool {
|
||||
return m[i].MenuOrder < m[j].MenuOrder //从小到大排序
|
||||
}
|
||||
|
||||
const MENUINFO = "menu_info"
|
||||
|
||||
func InsertMenu(menuInfo MenuInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&menuInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert new menu info fail:", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FirstMenuIsExists(firstMenu string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MENUINFO).Filter("first_menu", firstMenu).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func FirstMenuUidIsExists(firstMenUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MENUINFO).Filter("menu_uid", firstMenUid).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func MenuOrderIsExists(menuOrder int) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(MENUINFO).Filter("menu_order", menuOrder).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func GetMenuLen() int {
|
||||
o := orm.NewOrm()
|
||||
cnt, err := o.QueryTable(MENUINFO).Count()
|
||||
if err != nil {
|
||||
logs.Error("get menu info len length fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetMenuInfoByMenuUid(menuUid string) MenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var menuInfo MenuInfo
|
||||
_, err := o.QueryTable(MENUINFO).Filter("menu_uid", menuUid).Limit(1).All(&menuInfo)
|
||||
if err != nil {
|
||||
logs.Error("get menu info by menuUid fail: ", err)
|
||||
}
|
||||
return menuInfo
|
||||
}
|
||||
|
||||
func GetMenuInfosByMenuUids(menuUids []string) []MenuInfo {
|
||||
menuInfoList := make([]MenuInfo, 0)
|
||||
for _, v := range menuUids {
|
||||
m := GetMenuInfoByMenuUid(v)
|
||||
menuInfoList = append(menuInfoList, m)
|
||||
}
|
||||
return menuInfoList
|
||||
}
|
||||
|
||||
func GetMenuInfoByMenuOrder(menuOrder int) MenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var menuInfo MenuInfo
|
||||
_, err := o.QueryTable(MENUINFO).Filter("menu_order", menuOrder).Limit(1).All(&menuInfo)
|
||||
if err != nil {
|
||||
logs.Error("get menu info by menu order fail: ", err)
|
||||
}
|
||||
return menuInfo
|
||||
}
|
||||
|
||||
func GetMenuAll() []MenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var menuInfoList []MenuInfo
|
||||
_, err := o.QueryTable(MENUINFO).OrderBy("-update_time").All(&menuInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get all menu list fail:", err)
|
||||
}
|
||||
return menuInfoList
|
||||
}
|
||||
|
||||
func GetMenuOffset(displayCount, offset int) []MenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var menuInfoList []MenuInfo
|
||||
_, err := o.QueryTable(MENUINFO).Limit(displayCount, offset).All(&menuInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get menu offset fail: ", err)
|
||||
}
|
||||
return menuInfoList
|
||||
}
|
||||
|
||||
func GetMenuOffsetByMap(params map[string]string, displayCount, offset int) []MenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var menuInfoList []MenuInfo
|
||||
qs := o.QueryTable(MENUINFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&menuInfoList)
|
||||
if err != nil {
|
||||
logs.Error("get menu offset by map fail: ", err)
|
||||
}
|
||||
return menuInfoList
|
||||
}
|
||||
|
||||
func GetMenuLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(MENUINFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Count()
|
||||
if err != nil {
|
||||
logs.Error("get menu len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func UpdateMenuInfo(menuInfo MenuInfo) {
|
||||
o := orm.NewOrm()
|
||||
cnt, err := o.Update(&menuInfo)
|
||||
if err != nil {
|
||||
logs.Error("update menu info fail: ", err)
|
||||
}
|
||||
logs.Info("update menu info success, num: ", cnt)
|
||||
}
|
||||
|
||||
func DeleteMenuInfo(menuUid string) {
|
||||
o := orm.NewOrm()
|
||||
cnt, err := o.QueryTable(MENUINFO).Filter("menu_uid", menuUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete menu info fail: ", err)
|
||||
}
|
||||
logs.Info("delete menu info num: ", cnt)
|
||||
}
|
143
gateway/models/system/power_info.go
Normal file
143
gateway/models/system/power_info.go
Normal file
@ -0,0 +1,143 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/8/28 17:59
|
||||
** @Author : yuebin
|
||||
** @File : power_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/8/28 17:59
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type PowerInfo struct {
|
||||
Id int
|
||||
FirstMenuUid string
|
||||
SecondMenuUid string
|
||||
SecondMenu string
|
||||
PowerId string
|
||||
PowerItem string
|
||||
Creater string
|
||||
Status string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
|
||||
const POWER_INFO = "power_info"
|
||||
|
||||
type PowerInfoSlice []PowerInfo
|
||||
|
||||
func (sm PowerInfoSlice) Len() int {
|
||||
return len(sm)
|
||||
}
|
||||
|
||||
func (sm PowerInfoSlice) Swap(i, j int) {
|
||||
sm[i], sm[j] = sm[j], sm[i]
|
||||
}
|
||||
|
||||
func (sm PowerInfoSlice) Less(i, j int) bool {
|
||||
return sm[i].SecondMenuUid < sm[j].SecondMenuUid
|
||||
}
|
||||
|
||||
func PowerUidExists(powerUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exists := o.QueryTable(POWER_INFO).Filter("power_id", powerUid).Exist()
|
||||
return exists
|
||||
}
|
||||
|
||||
func InsertPowerInfo(powerInfo PowerInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&powerInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert power info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetPower() []PowerInfo {
|
||||
o := orm.NewOrm()
|
||||
var powerInfo []PowerInfo
|
||||
_, err := o.QueryTable(POWER_INFO).Limit(-1).All(&powerInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get power fail: ", err)
|
||||
}
|
||||
return powerInfo
|
||||
}
|
||||
|
||||
func GetPowerById(powerId string) PowerInfo {
|
||||
o := orm.NewOrm()
|
||||
var powerInfo PowerInfo
|
||||
_, err := o.QueryTable(POWER_INFO).Filter("power_id", powerId).Limit(1).All(&powerInfo)
|
||||
if err != nil {
|
||||
logs.Error("get power by id fail: ", err)
|
||||
}
|
||||
return powerInfo
|
||||
}
|
||||
|
||||
func GetPowerByIds(powerIds []string) []PowerInfo {
|
||||
var powerInfoList []PowerInfo
|
||||
for _, v := range powerIds {
|
||||
m := GetPowerById(v)
|
||||
powerInfoList = append(powerInfoList, m)
|
||||
}
|
||||
return powerInfoList
|
||||
}
|
||||
|
||||
func GetPowerItemLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(POWER_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get power item len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetPowerItemByMap(params map[string]string, displpay, offset int) []PowerInfo {
|
||||
o := orm.NewOrm()
|
||||
var powerItemList []PowerInfo
|
||||
qs := o.QueryTable(POWER_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := qs.Limit(displpay, offset).OrderBy("-update_time").All(&powerItemList)
|
||||
if err != nil {
|
||||
logs.Error("get power item by map fail: ", err)
|
||||
}
|
||||
return powerItemList
|
||||
}
|
||||
|
||||
func DeletePowerItemByPowerID(powerID string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(POWER_INFO).Filter("power_id", powerID).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete power item by powerID fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func DeletePowerBySecondUid(secondUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(POWER_INFO).Filter("second_menu_uid", secondUid).Delete()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("delete power by second menu uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
123
gateway/models/system/role_info.go
Normal file
123
gateway/models/system/role_info.go
Normal file
@ -0,0 +1,123 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/8/29 14:43
|
||||
** @Author : yuebin
|
||||
** @File : role_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/8/29 14:43
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type RoleInfo struct {
|
||||
Id int
|
||||
RoleName string
|
||||
RoleUid string
|
||||
ShowFirstMenu string
|
||||
ShowFirstUid string
|
||||
ShowSecondMenu string
|
||||
ShowSecondUid string
|
||||
ShowPower string
|
||||
ShowPowerUid string
|
||||
Creater string
|
||||
Status string
|
||||
Remark string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
|
||||
const ROLE_INFO = "role_info"
|
||||
|
||||
func GetRoleLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(ROLE_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
cnt, err := qs.Count()
|
||||
if err != nil {
|
||||
logs.Error("get role len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetRole() []RoleInfo {
|
||||
o := orm.NewOrm()
|
||||
var roleInfo []RoleInfo
|
||||
_, err := o.QueryTable(ROLE_INFO).Limit(-1).OrderBy("-update_time").All(&roleInfo)
|
||||
if err != nil {
|
||||
logs.Error("get all role fail: ", err)
|
||||
}
|
||||
return roleInfo
|
||||
}
|
||||
|
||||
func GetRoleByMap(params map[string]string, display, offset int) []RoleInfo {
|
||||
o := orm.NewOrm()
|
||||
var roleInfo []RoleInfo
|
||||
qs := o.QueryTable(ROLE_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(display, offset).OrderBy("-update_time").All(&roleInfo)
|
||||
if err != nil {
|
||||
logs.Error("get role by map fail: ", err)
|
||||
}
|
||||
return roleInfo
|
||||
}
|
||||
|
||||
func GetRoleByRoleUid(roleUid string) RoleInfo {
|
||||
o := orm.NewOrm()
|
||||
var roleInfo RoleInfo
|
||||
_, err := o.QueryTable(ROLE_INFO).Filter("role_uid", roleUid).Limit(1).All(&roleInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get role by role uid fail: ", err)
|
||||
}
|
||||
return roleInfo
|
||||
}
|
||||
|
||||
func RoleNameExists(roleName string) bool {
|
||||
o := orm.NewOrm()
|
||||
exists := o.QueryTable(ROLE_INFO).Filter("role_name", roleName).Exist()
|
||||
return exists
|
||||
}
|
||||
|
||||
func InsertRole(roleInfo RoleInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&roleInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert role fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteRoleByRoleUid(roleUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(ROLE_INFO).Filter("role_uid", roleUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete role by role uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateRoleInfo(roleInfo RoleInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&roleInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("update role info fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
216
gateway/models/system/second_menu_info.go
Normal file
216
gateway/models/system/second_menu_info.go
Normal file
@ -0,0 +1,216 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/8/26 9:33
|
||||
** @Author : yuebin
|
||||
** @File : second_menu_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/8/26 9:33
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
const SECOND_MENU_INFO = "second_menu_info"
|
||||
|
||||
type SecondMenuInfo struct {
|
||||
Id int
|
||||
FirstMenuOrder int
|
||||
FirstMenuUid string
|
||||
FirstMenu string
|
||||
MenuOrder int
|
||||
SecondMenuUid string
|
||||
SecondMenu string
|
||||
SecondRouter string
|
||||
Creater string
|
||||
Status string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
|
||||
type SecondMenuSlice []SecondMenuInfo
|
||||
|
||||
func (sm SecondMenuSlice) Len() int {
|
||||
return len(sm)
|
||||
}
|
||||
|
||||
func (sm SecondMenuSlice) Swap(i, j int) {
|
||||
sm[i], sm[j] = sm[j], sm[i]
|
||||
}
|
||||
|
||||
func (sm SecondMenuSlice) Less(i, j int) bool {
|
||||
if sm[i].FirstMenuOrder == sm[j].FirstMenuOrder {
|
||||
return sm[i].MenuOrder < sm[j].MenuOrder
|
||||
}
|
||||
return sm[i].FirstMenuOrder < sm[j].FirstMenuOrder
|
||||
}
|
||||
|
||||
func GetSecondMenuLen() int {
|
||||
o := orm.NewOrm()
|
||||
cnt, err := o.QueryTable(SECOND_MENU_INFO).Count()
|
||||
if err != nil {
|
||||
logs.Error("get second meun len fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetSecondMenuInfoByMenuOrder(menuOrder int, firstMenuUid string) SecondMenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var secondMenuInfo SecondMenuInfo
|
||||
_, err := o.QueryTable(SECOND_MENU_INFO).Filter("first_menu_uid", firstMenuUid).Filter("menu_order", menuOrder).Limit(1).All(&secondMenuInfo)
|
||||
if err != nil {
|
||||
logs.Error("get second menu info by menu order fail: ", err)
|
||||
}
|
||||
return secondMenuInfo
|
||||
}
|
||||
|
||||
func GetSecondMenuLenByFirstMenuUid(firstMenuUid string) int {
|
||||
o := orm.NewOrm()
|
||||
cnt, err := o.QueryTable(SECOND_MENU_INFO).Filter("first_menu_uid", firstMenuUid).Count()
|
||||
if err != nil {
|
||||
logs.Error("get second menu len by first menu uid fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetSecondMenuList() []SecondMenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var secondMenuList []SecondMenuInfo
|
||||
_, err := o.QueryTable(SECOND_MENU_INFO).Limit(-1).OrderBy("-update_time").All(&secondMenuList)
|
||||
if err != nil {
|
||||
logs.Error("get second menu list fail: ", err)
|
||||
}
|
||||
return secondMenuList
|
||||
}
|
||||
|
||||
func GetSecondMenuInfoBySecondMenuUid(secondMenuUid string) SecondMenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var secondMenuInfo SecondMenuInfo
|
||||
_, err := o.QueryTable(SECOND_MENU_INFO).Filter("second_menu_uid", secondMenuUid).Limit(1).All(&secondMenuInfo)
|
||||
if err != nil {
|
||||
logs.Error("get scond menu info by second menu uid fail: ", err)
|
||||
}
|
||||
return secondMenuInfo
|
||||
}
|
||||
|
||||
func GetSecondMenuInfoBySecondMenuUids(secondMenuUids []string) []SecondMenuInfo {
|
||||
secondMenuInfoList := make([]SecondMenuInfo, 0)
|
||||
for _, v := range secondMenuUids {
|
||||
sm := GetSecondMenuInfoBySecondMenuUid(v)
|
||||
secondMenuInfoList = append(secondMenuInfoList, sm)
|
||||
}
|
||||
return secondMenuInfoList
|
||||
}
|
||||
|
||||
func GetSecondMenuListByFirstMenuUid(firstMenuUid string) []SecondMenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var secondMenuList []SecondMenuInfo
|
||||
_, err := o.QueryTable(SECOND_MENU_INFO).Filter("first_menu_uid", firstMenuUid).Limit(-1).OrderBy("-update_time").All(&secondMenuList)
|
||||
if err != nil {
|
||||
logs.Error("get second menu list by first menu uid fail: ", err)
|
||||
}
|
||||
return secondMenuList
|
||||
}
|
||||
|
||||
func GetSecondMenuLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(SECOND_MENU_INFO)
|
||||
for k, v := range params {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
cnt, err := qs.Limit(-1).Count()
|
||||
if err != nil {
|
||||
logs.Error("get second menu len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func GetSecondMenuByMap(params map[string]string, displayCount, offset int) []SecondMenuInfo {
|
||||
o := orm.NewOrm()
|
||||
var secondMenuList []SecondMenuInfo
|
||||
qs := o.QueryTable(SECOND_MENU_INFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&secondMenuList)
|
||||
if err != nil {
|
||||
logs.Error("get second menu by map fail: ", err)
|
||||
}
|
||||
return secondMenuList
|
||||
}
|
||||
func InsertSecondMenu(secondMenuInfo SecondMenuInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&secondMenuInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert second menu fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SecondMenuIsExists(seconfMenu string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(SECOND_MENU_INFO).Filter("second_menu", seconfMenu).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func SecondMenuUidIsExists(secondMenuUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(SECOND_MENU_INFO).Filter("second_menu_uid", secondMenuUid).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func SecondRouterExists(secondRouter string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(SECOND_MENU_INFO).Filter("second_router", secondRouter).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func DeleteSecondMenuByFirstMenuUid(firstMenuUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
num, err := o.QueryTable(SECOND_MENU_INFO).Filter("first_menu_uid", firstMenuUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete second menu by first menu uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
logs.Info("delete second menu by first menu uid success, num: ", num)
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteSecondMenuBySecondMenuUid(secondMenuUid string) bool {
|
||||
o := orm.NewOrm()
|
||||
num, err := o.QueryTable(SECOND_MENU_INFO).Filter("second_menu_uid", secondMenuUid).Delete()
|
||||
if err != nil {
|
||||
logs.Error("delete second menu by second menu uid fail: ", err)
|
||||
return false
|
||||
}
|
||||
logs.Info("delete second menu by second menu uid success, num: ", num)
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateSecondMenuOrderBySecondUid(secondUid string, order int) {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(SECOND_MENU_INFO).Filter("second_menu_uid", secondUid).Update(orm.Params{"menu_order": order})
|
||||
if err != nil {
|
||||
logs.Error("update second menu order by second menu uid fail: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateSecondMenu(secondMenu SecondMenuInfo) {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Update(&secondMenu)
|
||||
if err != nil {
|
||||
logs.Error("update second menu for first order fail: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func SecondMenuExistByMenuOrder(menuOrder int) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(SECOND_MENU_INFO).Filter("menu_order", menuOrder).Exist()
|
||||
return exist
|
||||
}
|
146
gateway/models/user/user_info.go
Normal file
146
gateway/models/user/user_info.go
Normal file
@ -0,0 +1,146 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/8/9 14:02
|
||||
** @Author : yuebin
|
||||
** @File : user_info
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/8/9 14:02
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package user
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
const (
|
||||
USERINFO = "user_info"
|
||||
)
|
||||
|
||||
type UserInfo struct {
|
||||
Id int
|
||||
UserId string
|
||||
Passwd string
|
||||
Nick string
|
||||
Remark string
|
||||
Ip string
|
||||
Status string
|
||||
Role string
|
||||
RoleName string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
|
||||
func GetUserInfoByUserID(userID string) UserInfo {
|
||||
o := orm.NewOrm()
|
||||
var userInfo UserInfo
|
||||
err := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("user_id", userID).One(&userInfo)
|
||||
if err != nil {
|
||||
logs.Error("get user info fail: ", err)
|
||||
}
|
||||
return userInfo
|
||||
}
|
||||
|
||||
func GetOperatorByMap(params map[string]string, displayCount, offset int) []UserInfo {
|
||||
o := orm.NewOrm()
|
||||
var userInfo []UserInfo
|
||||
qs := o.QueryTable(USERINFO)
|
||||
for k, v := range params {
|
||||
if len(v) > 0 {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
}
|
||||
_, err := qs.Exclude("status", "delete").Limit(displayCount, offset).OrderBy("-update_time").All(&userInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get operator by map fail: ", err)
|
||||
}
|
||||
return userInfo
|
||||
}
|
||||
|
||||
func GetOperatorLenByMap(params map[string]string) int {
|
||||
o := orm.NewOrm()
|
||||
qs := o.QueryTable(USERINFO)
|
||||
for k, v := range params {
|
||||
qs = qs.Filter(k, v)
|
||||
}
|
||||
cnt, err := qs.Exclude("status", "delete").Count()
|
||||
if err != nil {
|
||||
logs.Error("get operator len by map fail: ", err)
|
||||
}
|
||||
return int(cnt)
|
||||
}
|
||||
|
||||
func UpdateUserInfoIP(userInfo UserInfo) {
|
||||
o := orm.NewOrm()
|
||||
num, err := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("user_id", userInfo.UserId).Update(orm.Params{"ip": userInfo.Ip})
|
||||
if err != nil {
|
||||
logs.Error("%s update user info ip fail: %v", userInfo.UserId, err)
|
||||
} else {
|
||||
logs.Info("%s update user info ip success, num: %d", userInfo.UserId, num)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateUserInfoPassword(userInfo UserInfo) {
|
||||
o := orm.NewOrm()
|
||||
num, err := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("user_id", userInfo.UserId).Update(orm.Params{"passwd": userInfo.Passwd})
|
||||
if err != nil {
|
||||
logs.Error("%s update user info password fail: %v", userInfo.UserId, err)
|
||||
} else {
|
||||
logs.Info("%s update user info password success, update num: %d", userInfo.UserId, num)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateUserInfo(userInfo UserInfo) {
|
||||
o := orm.NewOrm()
|
||||
if num, err := o.Update(&userInfo); err != nil {
|
||||
logs.Error("update user info fail: ", err)
|
||||
} else {
|
||||
logs.Info("update user info success, num: ", num)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateStauts(status, userId string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(USERINFO).Filter("user_id", userId).Update(orm.Params{"status": status})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("update status fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func UserInfoExistByUserId(userId string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("user_id", userId).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func NickIsExist(nick string) bool {
|
||||
o := orm.NewOrm()
|
||||
exist := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("nick", nick).Exist()
|
||||
return exist
|
||||
}
|
||||
|
||||
func InsertUser(userInfo UserInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.Insert(&userInfo)
|
||||
if err != nil {
|
||||
logs.Error("insert user fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func DeleteUserByUserId(userId string) bool {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("user_id", userId).Update(orm.Params{"status": "delete"})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("delete user by userId fail: ", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
173
gateway/notify/order_notify.go
Normal file
173
gateway/notify/order_notify.go
Normal file
@ -0,0 +1,173 @@
|
||||
/***************************************************
|
||||
** @Desc : 向下游返回支付结果
|
||||
** @Time : 2019/11/20 1:35
|
||||
** @Author : yuebin
|
||||
** @File : order_notify
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/20 1:35
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package notify
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/notify"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/httplib"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/go-stomp/stomp"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderNotifyTask struct {
|
||||
Delay *time.Timer
|
||||
MerchantOrderId string
|
||||
BankOrderId string
|
||||
FirstNotifyTime string
|
||||
NotifyTimes int
|
||||
LimitTimes int
|
||||
Status string //success-通知成功,其余的为待通知或者通知未完成
|
||||
}
|
||||
|
||||
const (
|
||||
LimitTimes = 5 //最多通知5次
|
||||
)
|
||||
|
||||
//给商户发送订单结果
|
||||
func SendOrderNotify(bankOrderId string) {
|
||||
if !notify.NotifyInfoExistByBankOrderId(bankOrderId) {
|
||||
logs.Error("该订单不存在回调内容,bankOrderId= " + bankOrderId)
|
||||
return
|
||||
}
|
||||
|
||||
notifyInfo := notify.GetNotifyInfoByBankOrderId(bankOrderId)
|
||||
if notifyInfo.Status == "success" {
|
||||
logs.Info(fmt.Sprintf("该订单= %s,已经回调", bankOrderId))
|
||||
return
|
||||
}
|
||||
notifyInfo.Times += 1
|
||||
notifyInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
req := httplib.Post(notifyInfo.Url)
|
||||
response, err := req.String()
|
||||
|
||||
if err == nil && ("success" == response || "SUCCESS" == response) {
|
||||
if strings.Contains(strings.ToLower(response), "success") {
|
||||
notifyInfo.Status = "success"
|
||||
if notify.UpdateNotifyInfo(notifyInfo) {
|
||||
logs.Info("订单回调成功, bankOrderId=", bankOrderId)
|
||||
} else {
|
||||
logs.Error("订单回调成功,但是更新数据库失败, bankOrderId=", bankOrderId)
|
||||
}
|
||||
} else {
|
||||
logs.Notice("订单已经回调,商户已经收到了回调通知,但是返回值错误: ", response)
|
||||
}
|
||||
} else {
|
||||
if notifyInfo.Times > LimitTimes {
|
||||
logs.Notice(fmt.Sprintf("该订单= %s,已经超过了回调次数", bankOrderId))
|
||||
} else {
|
||||
minute := GetOrderNotifyMinute(notifyInfo.Times)
|
||||
logs.Info(fmt.Sprintf("bankOrderId = %s, 进行第 %d 次回调,本次延时时间为:%d", notifyInfo.BankOrderId, notifyInfo.Times, minute))
|
||||
task := OrderNotifyTask{Delay: time.NewTimer(time.Duration(minute) * time.Minute),
|
||||
MerchantOrderId: notifyInfo.MerchantOrderId, BankOrderId: notifyInfo.BankOrderId, FirstNotifyTime: notifyInfo.CreateTime,
|
||||
NotifyTimes: notifyInfo.Times, LimitTimes: LimitTimes, Status: notifyInfo.Status}
|
||||
go OrderNotifyTimer(task)
|
||||
if !notify.UpdateNotifyInfo(notifyInfo) {
|
||||
logs.Error("订单回调失败,数据库更新失败:" + bankOrderId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetOrderNotifyMinute(times int) int {
|
||||
cur := 0
|
||||
switch times {
|
||||
case 0:
|
||||
cur = 0
|
||||
break
|
||||
case 1:
|
||||
cur = 1
|
||||
break
|
||||
case 2:
|
||||
cur = 2
|
||||
break
|
||||
case 3:
|
||||
cur = 5
|
||||
break
|
||||
case 4:
|
||||
cur = 15
|
||||
break
|
||||
case 5:
|
||||
cur = 30
|
||||
break
|
||||
default:
|
||||
cur = 45
|
||||
break
|
||||
}
|
||||
return cur
|
||||
}
|
||||
|
||||
func OrderNotifyTimer(task OrderNotifyTask) {
|
||||
for {
|
||||
select {
|
||||
case <-task.Delay.C:
|
||||
SendOrderNotify(task.BankOrderId)
|
||||
return
|
||||
//70分钟没有执行该协程,那么退出协程
|
||||
case <-time.After(time.Minute * 70):
|
||||
logs.Notice("订单回调延时执行,70分钟没有执行")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//读取一小时之内,未发送成功,并且还没有到达回调限制次数的记录读取,存入延迟队列
|
||||
func CreateOrderDelayQueue() {
|
||||
params := make(map[string]interface{})
|
||||
params["times__lte"] = LimitTimes
|
||||
params["create_time__gte"] = utils.GetDateTimeBeforeHours(48)
|
||||
notifyList := notify.GetNotifyInfosNotSuccess(params)
|
||||
for _, nf := range notifyList {
|
||||
minute := GetOrderNotifyMinute(nf.Times)
|
||||
task := OrderNotifyTask{Delay: time.NewTimer(time.Duration(minute) * time.Minute),
|
||||
MerchantOrderId: nf.MerchantOrderId, BankOrderId: nf.BankOrderId, FirstNotifyTime: nf.CreateTime,
|
||||
NotifyTimes: nf.Times, LimitTimes: LimitTimes, Status: nf.Status}
|
||||
go OrderNotifyTimer(task)
|
||||
}
|
||||
}
|
||||
|
||||
//创建订单回调消费者
|
||||
func CreateOrderNotifyConsumer() {
|
||||
CreateOrderDelayQueue()
|
||||
//启动定时任务
|
||||
conn := message.GetActiveMQConn()
|
||||
if conn == nil {
|
||||
logs.Error("启动消息队列消费者失败....")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logs.Notice("订单回调消息队列启动成功......")
|
||||
orderNotify, err := conn.Subscribe(conf.MqOrderNotify, stomp.AckClient)
|
||||
if err != nil {
|
||||
logs.Error("订阅订单回调失败......")
|
||||
os.Exit(1)
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case v := <-orderNotify.C:
|
||||
if v != nil {
|
||||
bankOrderId := string(v.Body)
|
||||
go SendOrderNotify(bankOrderId)
|
||||
//应答,重要
|
||||
err := conn.Ack(v)
|
||||
if err != nil {
|
||||
logs.Error("消息应答失败!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
gateway/notify/payfor_notify.go
Normal file
10
gateway/notify/payfor_notify.go
Normal file
@ -0,0 +1,10 @@
|
||||
/***************************************************
|
||||
** @Desc : 将代付结果返回给请求方
|
||||
** @Time : 2019/11/20 1:35
|
||||
** @Author : yuebin
|
||||
** @File : payfor_notify
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/20 1:35
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package notify
|
370
gateway/pay_for/payfor_service.go
Normal file
370
gateway/pay_for/payfor_service.go
Normal file
@ -0,0 +1,370 @@
|
||||
/***************************************************
|
||||
** @Desc : 代付处理
|
||||
** @Time : 2019/11/28 18:52
|
||||
** @Author : yuebin
|
||||
** @File : payfor_service
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/28 18:52
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package pay_for
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
"gateway/response"
|
||||
"gateway/supplier/third_party"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/rs/xid"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/**
|
||||
** 程序自动代付
|
||||
*/
|
||||
func AutoPayFor(params map[string]string, giveType string) *response.PayForResponse {
|
||||
|
||||
payForResponse := new(response.PayForResponse)
|
||||
|
||||
merchantInfo := merchant.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
logs.Error(fmt.Sprintf("下游商户代付请求,签名失败,商户信息: %+v", merchantInfo))
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "下游商户代付请求,签名失败。"
|
||||
return payForResponse
|
||||
} else {
|
||||
res, msg := checkSettAmount(params["amount"])
|
||||
if !res {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = msg
|
||||
|
||||
return payForResponse
|
||||
}
|
||||
|
||||
exist := payfor.IsExistPayForByMerchantOrderId(params["merchantOrderId"])
|
||||
if exist {
|
||||
logs.Error(fmt.Sprintf("代付订单号重复:merchantOrderId = %s", params["merchantOrderId"]))
|
||||
payForResponse.ResultMsg = "商户订单号重复"
|
||||
payForResponse.ResultCode = "01"
|
||||
|
||||
return payForResponse
|
||||
}
|
||||
|
||||
settAmount, err := strconv.ParseFloat(params["amount"], 64)
|
||||
if err != nil {
|
||||
logs.Error("代付的金额错误:", err)
|
||||
payForResponse.ResultMsg = "代付金额错误"
|
||||
payForResponse.ResultCode = "01"
|
||||
return payForResponse
|
||||
}
|
||||
|
||||
p := payfor.PayforInfo{
|
||||
PayforUid: "pppp" + xid.New().String(),
|
||||
MerchantUid: merchantInfo.MerchantUid,
|
||||
MerchantName: merchantInfo.MerchantName,
|
||||
MerchantOrderId: params["merchantOrderId"],
|
||||
BankOrderId: "4444" + xid.New().String(),
|
||||
PayforAmount: settAmount,
|
||||
Status: conf.PAYFOR_COMFRIM,
|
||||
BankAccountName: params["realname"],
|
||||
BankAccountNo: params["cardNo"],
|
||||
BankAccountType: params["accType"],
|
||||
City: params["city"],
|
||||
Ares: params["province"] + params["city"],
|
||||
PhoneNo: params["mobileNo"],
|
||||
GiveType: giveType,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
RequestTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
// 获取银行编码和银行名称
|
||||
p.BankCode = utils.GetBankCodeByBankCardNo(p.BankAccountNo)
|
||||
p.BankName = utils.GetBankNameByCode(p.BankCode)
|
||||
|
||||
if !payfor.InsertPayfor(p) {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "代付记录插入失败"
|
||||
} else {
|
||||
payForResponse.ResultMsg = "代付订单已生成"
|
||||
payForResponse.ResultCode = "00"
|
||||
payForResponse.SettAmount = params["amount"]
|
||||
payForResponse.MerchantOrderId = params["MerchantOrderId"]
|
||||
|
||||
p = payfor.GetPayForByBankOrderId(p.BankOrderId)
|
||||
|
||||
if findPayForRoad(p) {
|
||||
payForResponse.ResultCode = "00"
|
||||
payForResponse.ResultMsg = "银行处理中"
|
||||
} else {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "系统处理失败"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return payForResponse
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回1表示需要手动打款,返回0表示银行已经受理,-1表示系统处理失败
|
||||
*/
|
||||
func findPayForRoad(p payfor.PayforInfo) bool {
|
||||
|
||||
m := merchant.GetMerchantByUid(p.MerchantUid)
|
||||
// 检查商户是否设置了自动代付
|
||||
if m.AutoPayFor == conf.NO || m.AutoPayFor == "" {
|
||||
logs.Notice(fmt.Sprintf("该商户uid=%s, 没有开通自动代付功能", p.MerchantUid))
|
||||
p.Type = conf.PAYFOR_HAND
|
||||
payfor.UpdatePayFor(p)
|
||||
} else {
|
||||
|
||||
if m.SinglePayForRoadUid != "" {
|
||||
p.RoadUid = m.SinglePayForRoadUid
|
||||
p.RoadName = m.SinglePayForRoadName
|
||||
} else {
|
||||
roadPoolInfo := road.GetRoadPoolByRoadPoolCode(m.RollPayForRoadCode)
|
||||
roadUids := strings.Split(roadPoolInfo.RoadUidPool, "||")
|
||||
roadInfoList := road.GetRoadInfosByRoadUids(roadUids)
|
||||
if len(roadUids) == 0 || len(roadInfoList) == 0 {
|
||||
logs.Error(fmt.Sprintf("通道轮询池=%s, 没有配置通道", m.RollPayForRoadCode))
|
||||
} else {
|
||||
p.RoadUid = roadInfoList[0].RoadUid
|
||||
p.RoadName = roadInfoList[0].RoadName
|
||||
}
|
||||
}
|
||||
|
||||
if !payfor.UpdatePayFor(p) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(p.RoadUid) > 0 {
|
||||
roadInfo := road.GetRoadInfoByRoadUid(p.RoadUid)
|
||||
p.PayforFee = roadInfo.SettleFee
|
||||
p.PayforTotalAmount = p.PayforFee + p.PayforAmount
|
||||
|
||||
if m.PayforFee > conf.ZERO {
|
||||
logs.Info(fmt.Sprintf("商户uid=%s,有单独的代付手续费。", m.MerchantUid))
|
||||
p.PayforFee = m.PayforFee
|
||||
p.PayforTotalAmount = p.PayforFee + p.PayforAmount
|
||||
}
|
||||
|
||||
if !payfor.UpdatePayFor(p) {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.GiveType == conf.SELF_HELP {
|
||||
if !MerchantSelf(p) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if !SendPayFor(p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.Status = conf.PAYFOR_FAIL
|
||||
if !payfor.UpdatePayFor(p) {
|
||||
return false
|
||||
}
|
||||
p.ResponseContent = "没有设置代付通道"
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
** 商户自己体现
|
||||
*/
|
||||
func MerchantSelf(p payfor.PayforInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
p.UpdateTime = utils.GetBasicDateTime()
|
||||
p.Status = conf.PAYFOR_BANKING
|
||||
p.RequestTime = utils.GetBasicDateTime()
|
||||
p.IsSend = conf.YES
|
||||
if _, err := txOrm.Update(&p); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
RequestPayFor(p)
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SendPayFor(p payfor.PayforInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var account accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", p.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" {
|
||||
logs.Error("send payfor select account fail:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
//支付金额不足,将直接判定为失败,不往下面邹逻辑了
|
||||
if account.SettleAmount-account.PayforAmount < p.PayforAmount+p.PayforFee {
|
||||
p.Status = conf.PAYFOR_FAIL
|
||||
p.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
if _, err := txOrm.Update(&p); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
account.PayforAmount = account.PayforAmount + p.PayforAmount + p.PayforFee
|
||||
|
||||
if _, err := txOrm.Update(&account); err != nil {
|
||||
logs.Error(fmt.Sprintf("商户uid=%s,在发送代付给上游的处理中,更新账户表出错, err: %s", p.MerchantUid, err))
|
||||
return err
|
||||
}
|
||||
|
||||
p.IsSend = conf.YES
|
||||
p.Status = conf.PAYFOR_BANKING //变为银行处理中
|
||||
p.GiveType = conf.PAYFOR_ROAD
|
||||
p.RequestTime = utils.GetBasicDateTime()
|
||||
p.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
if _, err := txOrm.Update(&p); err != nil {
|
||||
logs.Error(fmt.Sprintf("商户uid=%s,在发送代付给上游的处理中,更代付列表出错, err:%s", p.MerchantUid, err))
|
||||
return err
|
||||
}
|
||||
|
||||
RequestPayFor(p)
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func RequestPayFor(p payfor.PayforInfo) {
|
||||
if p.RoadUid == "" {
|
||||
return
|
||||
}
|
||||
p.Type = conf.PAYFOR_ROAD
|
||||
roadInfo := road.GetRoadInfoByRoadUid(p.RoadUid)
|
||||
supplierCode := roadInfo.ProductUid
|
||||
supplier := third_party.GetPaySupplierByCode(supplierCode)
|
||||
res := supplier.PayFor(p)
|
||||
logs.Info(fmt.Sprintf("代付uid=%s,上游处理结果为:%s", p.PayforUid, res))
|
||||
//将代付订单号发送到消息队列
|
||||
message.SendMessage(conf.MQ_PAYFOR_QUERY, p.BankOrderId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 代付结果查询
|
||||
*/
|
||||
func PayForResultQuery(params map[string]string) string {
|
||||
|
||||
query := make(map[string]string)
|
||||
query["merchantOrderId"] = params["merchantOrderId"]
|
||||
merchantInfo := merchant.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
query["resultMsg"] = "签名错误"
|
||||
query["settStatus"] = "03"
|
||||
query["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
} else {
|
||||
payForInfo := payfor.GetPayForByMerchantOrderId(params["merchantOrderId"])
|
||||
if payForInfo.BankOrderId == "" {
|
||||
query["resultMsg"] = "不存在这样的代付订单"
|
||||
query["settStatus"] = "03"
|
||||
query["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
} else {
|
||||
switch payForInfo.Status {
|
||||
case conf.PAYFOR_BANKING:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case conf.PAYFOR_SOLVING:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case conf.PAYFOR_COMFRIM:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case conf.PAYFOR_SUCCESS:
|
||||
query["resultMsg"] = "打款成功"
|
||||
query["settStatus"] = "00"
|
||||
query["settAmount"] = strconv.FormatFloat(payForInfo.PayforAmount, 'f', 2, 64)
|
||||
query["settFee"] = strconv.FormatFloat(payForInfo.PayforFee, 'f', 2, 64)
|
||||
case conf.PAYFOR_FAIL:
|
||||
query["resultMsg"] = "打款失败"
|
||||
query["settStatus"] = "01"
|
||||
}
|
||||
query["sign"] = utils.GetMD5Sign(query, utils.SortMap(query), merchantInfo.MerchantSecret)
|
||||
}
|
||||
}
|
||||
|
||||
mJson, err := json.Marshal(query)
|
||||
if err != nil {
|
||||
logs.Error("PayForQuery json marshal fail:", err)
|
||||
return fmt.Sprintf("PayForQuery json marshal fail:%s", err.Error())
|
||||
} else {
|
||||
return string(mJson)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户查询余额
|
||||
*/
|
||||
func BalanceQuery(params map[string]string) string {
|
||||
|
||||
balanceResponse := new(response.BalanceResponse)
|
||||
str := ""
|
||||
merchantInfo := merchant.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
balanceResponse.ResultCode = "-1"
|
||||
balanceResponse.ResultMsg = "签名错误"
|
||||
mJson, _ := json.Marshal(balanceResponse)
|
||||
str = string(mJson)
|
||||
} else {
|
||||
accountInfo := accounts.GetAccountByUid(merchantInfo.MerchantUid)
|
||||
tmp := make(map[string]string)
|
||||
tmp["resultCode"] = "00"
|
||||
tmp["balance"] = strconv.FormatFloat(accountInfo.Balance, 'f', 2, 64)
|
||||
tmp["availableAmount"] = strconv.FormatFloat(accountInfo.SettleAmount, 'f', 2, 64)
|
||||
tmp["freezeAmount"] = strconv.FormatFloat(accountInfo.FreezeAmount, 'f', 2, 64)
|
||||
tmp["waitAmount"] = strconv.FormatFloat(accountInfo.WaitAmount, 'f', 2, 64)
|
||||
tmp["loanAmount"] = strconv.FormatFloat(accountInfo.LoanAmount, 'f', 2, 64)
|
||||
tmp["payforAmount"] = strconv.FormatFloat(accountInfo.PayforAmount, 'f', 2, 64)
|
||||
tmp["resultMsg"] = "查询成功"
|
||||
tmp["sign"] = utils.GetMD5Sign(tmp, utils.SortMap(tmp), merchantInfo.MerchantSecret)
|
||||
mJson, _ := json.Marshal(tmp)
|
||||
str = string(mJson)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
func checkSettAmount(settAmount string) (bool, string) {
|
||||
_, err := strconv.ParseFloat(settAmount, 64)
|
||||
if err != nil {
|
||||
logs.Error(fmt.Sprintf("代付金额有误,settAmount = %s", settAmount))
|
||||
return false, "代付金额有误"
|
||||
}
|
||||
return true, ""
|
||||
}
|
135
gateway/pay_for/payfor_solve.go
Normal file
135
gateway/pay_for/payfor_solve.go
Normal file
@ -0,0 +1,135 @@
|
||||
package pay_for
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/payfor"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
func PayForFail(p payfor.PayforInfo) bool {
|
||||
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var tmpForPay payfor.PayforInfo
|
||||
if err := txOrm.Raw("select * from payfor_info where bank_order_id = ? for update", p.BankOrderId).QueryRow(&tmpForPay); err != nil || tmpForPay.PayforUid == "" {
|
||||
|
||||
logs.Error("solve pay fail select fail:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if tmpForPay.Status == conf.PAYFOR_FAIL || tmpForPay.Status == conf.PAYFOR_SUCCESS {
|
||||
logs.Error(fmt.Sprintf("该代付订单uid=%s,状态已经是最终结果", tmpForPay.PayforUid))
|
||||
return errors.New("状态已经是最终结果")
|
||||
}
|
||||
//更新payfor记录的状态
|
||||
tmpForPay.Status = conf.PAYFOR_FAIL
|
||||
tmpForPay.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&tmpForPay); err != nil {
|
||||
logs.Error("PayForFail update payfor_info fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
var account accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", tmpForPay.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" {
|
||||
|
||||
logs.Error("payfor select account fail:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
if account.PayforAmount < tmpForPay.PayforTotalAmount {
|
||||
logs.Error(fmt.Sprintf("商户uid=%s,账户中待代付金额小于代付记录的金额", tmpForPay.MerchantUid))
|
||||
return errors.New("账户中待代付金额小于代付记录的金额")
|
||||
}
|
||||
//将正在打款中的金额减去
|
||||
account.PayforAmount = account.PayforAmount - tmpForPay.PayforTotalAmount
|
||||
|
||||
if _, err := txOrm.Update(&account); err != nil {
|
||||
logs.Error("PayForFail update account fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func PayForSuccess(p payfor.PayforInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
var tmpPayFor payfor.PayforInfo
|
||||
if err := txOrm.Raw("select * from payfor_info where bank_order_id = ? for update", p.BankOrderId).QueryRow(&tmpPayFor); err != nil || tmpPayFor.PayforUid == "" {
|
||||
logs.Error("payfor success select payfor fail:", err)
|
||||
return err
|
||||
}
|
||||
if tmpPayFor.Status == conf.PAYFOR_FAIL || tmpPayFor.Status == conf.PAYFOR_SUCCESS {
|
||||
logs.Error(fmt.Sprintf("该代付订单uid=#{payFor.PayforUid},已经是最终结果,不需要处理"))
|
||||
return errors.New("已经是最终结果,不需要处理")
|
||||
}
|
||||
|
||||
tmpPayFor.UpdateTime = utils.GetBasicDateTime()
|
||||
tmpPayFor.Status = conf.PAYFOR_SUCCESS
|
||||
_, err := txOrm.Update(&tmpPayFor)
|
||||
if err != nil {
|
||||
logs.Error("PayForSuccess update payfor fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
var account accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", tmpPayFor.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" {
|
||||
logs.Error("payfor success select account fail:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
if account.PayforAmount < tmpPayFor.PayforTotalAmount {
|
||||
logs.Error(fmt.Sprintf("商户uid=#{payFor.MerchantUid},账户中待代付金额小于代付记录的金额"))
|
||||
return errors.New("账户中待代付金额小于代付记录的金额")
|
||||
}
|
||||
|
||||
//代付打款中的金额减去
|
||||
account.PayforAmount = account.PayforAmount - tmpPayFor.PayforTotalAmount
|
||||
//减去余额,减去可用金额
|
||||
account.Balance = account.Balance - tmpPayFor.PayforTotalAmount
|
||||
//已结算金额减去
|
||||
account.SettleAmount = account.SettleAmount - tmpPayFor.PayforTotalAmount
|
||||
|
||||
if _, err := txOrm.Update(&account); err != nil {
|
||||
logs.Error("PayForSuccess update account fail:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
//添加一条动账记录
|
||||
accountHistory := accounts.AccountHistoryInfo{
|
||||
AccountUid: tmpPayFor.MerchantUid,
|
||||
AccountName: tmpPayFor.MerchantName,
|
||||
Type: conf.SUB_AMOUNT,
|
||||
Amount: tmpPayFor.PayforTotalAmount,
|
||||
Balance: account.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistory); err != nil {
|
||||
logs.Error("PayForSuccess insert account history fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
@ -7,20 +7,21 @@
|
||||
** @Last Modified time: 2019/11/6 13:59
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
package query
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gateway/models"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type QueryController struct {
|
||||
beego.Controller
|
||||
type MerchantQueryController struct {
|
||||
web.Controller
|
||||
}
|
||||
|
||||
type OrderQueryFailData struct {
|
||||
@ -32,7 +33,7 @@ type OrderQueryFailData struct {
|
||||
/*
|
||||
** 改接口是为下游商户提供订单查询
|
||||
*/
|
||||
func (c *QueryController) OrderQuery() {
|
||||
func (c *MerchantQueryController) OrderQuery() {
|
||||
orderNo := strings.TrimSpace(c.GetString("orderNo"))
|
||||
payKey := strings.TrimSpace(c.GetString("payKey"))
|
||||
sign := strings.TrimSpace(c.GetString("sign"))
|
||||
@ -44,11 +45,11 @@ func (c *QueryController) OrderQuery() {
|
||||
failData.StatusCode = "01"
|
||||
failData.PayKey = payKey
|
||||
|
||||
merchantInfo := models.GetMerchantByPaykey(payKey)
|
||||
merchantInfo := merchant.GetMerchantByPaykey(payKey)
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
failData.Msg = "商户不存在,请核对payKey字段"
|
||||
}
|
||||
orderInfo := models.GetOrderByMerchantOrderId(orderNo)
|
||||
orderInfo := order.GetOrderByMerchantOrderId(orderNo)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
failData.Msg = "不存在这样的订单,请核对orderNo字段"
|
||||
}
|
||||
@ -60,7 +61,7 @@ func (c *QueryController) OrderQuery() {
|
||||
}
|
||||
if failData.Msg != "" {
|
||||
c.Data["json"] = failData
|
||||
c.ServeJSON()
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
p := make(map[string]string)
|
137
gateway/query/payfor_query.go
Normal file
137
gateway/query/payfor_query.go
Normal file
@ -0,0 +1,137 @@
|
||||
/***************************************************
|
||||
** @Desc : 处理代付查询功能
|
||||
** @Time : 2019/12/3 15:07
|
||||
** @Author : yuebin
|
||||
** @File : pay_for_query
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/3 15:07
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
"gateway/pay_for"
|
||||
"gateway/supplier/third_party"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/go-stomp/stomp"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PayForQueryTask struct {
|
||||
Delay *time.Timer
|
||||
MerchantOrderId string
|
||||
BankOrderId string
|
||||
FirstNotifyTime string
|
||||
QueryTimes int
|
||||
LimitTimes int
|
||||
Status string
|
||||
}
|
||||
|
||||
const (
|
||||
PayForLimitTimes = 12 //最多查询次数
|
||||
PayForQueryInterval = 5 //时间间隔为5分钟
|
||||
)
|
||||
|
||||
func PayForQueryTimer(task PayForQueryTask) {
|
||||
for {
|
||||
select {
|
||||
case <-task.Delay.C:
|
||||
PayForSupplier(task)
|
||||
task.Delay.Stop()
|
||||
return
|
||||
//70分钟没有执行该协程,那么退出协程
|
||||
case <-time.After(time.Minute * 70):
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PayForSupplier(task PayForQueryTask) {
|
||||
logs.Info(fmt.Sprintf("执行代付查询任务:%+v", task))
|
||||
payFor := payfor.GetPayForByBankOrderId(task.BankOrderId)
|
||||
roadInfo := road.GetRoadInfoByRoadUid(payFor.RoadUid)
|
||||
supplier := third_party.GetPaySupplierByCode(roadInfo.ProductUid)
|
||||
if supplier == nil {
|
||||
logs.Error("代付查询返回supplier为空")
|
||||
return
|
||||
}
|
||||
res, _ := supplier.PayForQuery(payFor)
|
||||
if res == conf.PAYFOR_SUCCESS {
|
||||
//代付成功了
|
||||
pay_for.PayForSuccess(payFor)
|
||||
} else if res == conf.PAYFOR_FAIL {
|
||||
//代付失败
|
||||
pay_for.PayForFail(payFor)
|
||||
} else if res == conf.PAYFOR_BANKING {
|
||||
//银行处理中,那么就继续执行查询,直到次数超过最大次数
|
||||
if task.QueryTimes <= task.LimitTimes {
|
||||
task.QueryTimes += 1
|
||||
task.Delay = time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute)
|
||||
go PayForQueryTimer(task)
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("该代付订单已经超过最大查询次数,bankOrderId = %s", task.BankOrderId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func payForQueryConsumer(bankOrderId string) {
|
||||
exist := payfor.IsExistPayForByBankOrderId(bankOrderId)
|
||||
if !exist {
|
||||
logs.Error(fmt.Sprintf("代付记录不存在,bankOrderId = %s", bankOrderId))
|
||||
return
|
||||
}
|
||||
|
||||
payFor := payfor.GetPayForByBankOrderId(bankOrderId)
|
||||
|
||||
if payFor.Status != conf.PAYFOR_BANKING {
|
||||
logs.Info(fmt.Sprintf("代付状态不是银行处理中,不需要去查询,bankOrderId = %s", bankOrderId))
|
||||
return
|
||||
}
|
||||
|
||||
payForQueryTask := PayForQueryTask{Delay: time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute), MerchantOrderId: payFor.MerchantOrderId,
|
||||
BankOrderId: payFor.BankOrderId, FirstNotifyTime: utils.GetBasicDateTime(), QueryTimes: 1, LimitTimes: PayForLimitTimes, Status: payFor.Status}
|
||||
|
||||
go PayForQueryTimer(payForQueryTask)
|
||||
}
|
||||
|
||||
/*
|
||||
* 创建代付查询的消费者
|
||||
*/
|
||||
func CreatePayForQueryConsumer() {
|
||||
//启动定时任务
|
||||
conn := message.GetActiveMQConn()
|
||||
if conn == nil {
|
||||
logs.Error("启动消息队列消费者失败....")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logs.Notice("代付查询消费启动成功......")
|
||||
|
||||
payForQuery, err := conn.Subscribe(conf.MQ_PAYFOR_QUERY, stomp.AckClient)
|
||||
if err != nil {
|
||||
logs.Error("订阅代付查询失败......")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case v := <-payForQuery.C:
|
||||
if v != nil {
|
||||
bankOrderId := string(v.Body)
|
||||
go payForQueryConsumer(bankOrderId)
|
||||
//应答,重要
|
||||
err := conn.Ack(v)
|
||||
if err != nil {
|
||||
logs.Error("消息应答失败!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
109
gateway/query/supplier_query.go
Normal file
109
gateway/query/supplier_query.go
Normal file
@ -0,0 +1,109 @@
|
||||
/***************************************************
|
||||
** @Desc : 自动查询上游的支付结果
|
||||
** @Time : 2019/11/22 23:02
|
||||
** @Author : yuebin
|
||||
** @File : order_query
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 23:02
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/order"
|
||||
"gateway/supplier/third_party"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/go-stomp/stomp"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderQueryTask struct {
|
||||
BankOrderId string
|
||||
OrderQueryTimer *time.Timer
|
||||
Times int
|
||||
}
|
||||
|
||||
const (
|
||||
DelayTime = 5 //延时时间为5分钟查询一次
|
||||
LimitTimes = 5 //最多查询5次
|
||||
)
|
||||
|
||||
/*
|
||||
** 该接口是查询上游的订单
|
||||
*/
|
||||
func solveSupplierOrderQuery(task OrderQueryTask) {
|
||||
bankOrderId := task.BankOrderId
|
||||
orderInfo := order.GetOrderByBankOrderId(bankOrderId)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
logs.Error("不存在这样的订单,订单查询结束")
|
||||
return
|
||||
}
|
||||
if orderInfo.Status != "" && orderInfo.Status != "wait" {
|
||||
logs.Error(fmt.Sprintf("该订单=%s,已经处理完毕,", bankOrderId))
|
||||
return
|
||||
}
|
||||
supplierCode := orderInfo.PayProductCode
|
||||
supplier := third_party.GetPaySupplierByCode(supplierCode)
|
||||
flag := supplier.PayQuery(orderInfo)
|
||||
if flag {
|
||||
logs.Info("订单查询成功, bankOrderId:", bankOrderId)
|
||||
} else {
|
||||
if task.Times <= LimitTimes {
|
||||
task.Times += 1
|
||||
task.OrderQueryTimer = time.NewTimer(time.Duration(5) * time.Minute)
|
||||
DelayOrderQueryQueue(task)
|
||||
} else {
|
||||
logs.Notice(fmt.Sprintf("订单id=%s, 已经查询超过次数"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 延时队列
|
||||
*/
|
||||
func DelayOrderQueryQueue(task OrderQueryTask) {
|
||||
for {
|
||||
select {
|
||||
case <-task.OrderQueryTimer.C:
|
||||
logs.Info(fmt.Sprintf("订单id=%s,执行第:%d 次查询", task.BankOrderId, task.Times))
|
||||
solveSupplierOrderQuery(task)
|
||||
return
|
||||
case <-time.After(time.Duration(2*DelayTime) * time.Minute):
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** 启动消息订单查询的消息队列消费者
|
||||
*/
|
||||
func CreateSupplierOrderQueryCuConsumer() {
|
||||
conn := message.GetActiveMQConn()
|
||||
if conn == nil {
|
||||
logs.Error("supplier order query consumer fail")
|
||||
os.Exit(1)
|
||||
}
|
||||
logs.Notice("启动订单查询的消费者成功.....")
|
||||
orderQuerySub, _ := conn.Subscribe(conf.MqOrderQuery, stomp.AckClient)
|
||||
|
||||
for {
|
||||
select {
|
||||
case v := <-orderQuerySub.C:
|
||||
if v != nil {
|
||||
bankOrderId := string(v.Body)
|
||||
logs.Info("消费者正在处理订单查询: " + bankOrderId)
|
||||
task := OrderQueryTask{BankOrderId: bankOrderId, OrderQueryTimer: time.NewTimer(time.Second * 1), Times: 1}
|
||||
DelayOrderQueryQueue(task)
|
||||
//应答,重要
|
||||
err := conn.Ack(v)
|
||||
if err != nil {
|
||||
logs.Error("消息应答失败!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
gateway/response/pay_resp.go
Normal file
36
gateway/response/pay_resp.go
Normal file
@ -0,0 +1,36 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/road"
|
||||
)
|
||||
|
||||
type PayBaseResp struct {
|
||||
Params map[string]string //请求的基本参数
|
||||
ClientIp string //商户ip
|
||||
MerchantInfo merchant.MerchantInfo //商户信息
|
||||
Msg string //信息
|
||||
Code int //状态码 200正常
|
||||
RoadInfo road.RoadInfo
|
||||
RoadPoolInfo road.RoadPoolInfo
|
||||
OrderAmount float64
|
||||
PayWayCode string
|
||||
PlatformRate float64
|
||||
AgentRate float64
|
||||
}
|
||||
|
||||
type ScanSuccessData struct {
|
||||
OrderNo string `json:"orderNo"`
|
||||
Sign string `json:"sign"`
|
||||
OrderPrice string `json:"orderPrice"`
|
||||
PayKey string `json:"payKey"`
|
||||
PayUrl string `json:"payURL"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
type ScanFailData struct {
|
||||
PayKey string `json:"payKey"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
40
gateway/response/payfor_resp.go
Normal file
40
gateway/response/payfor_resp.go
Normal file
@ -0,0 +1,40 @@
|
||||
package response
|
||||
|
||||
/**
|
||||
* 返回自动代付结果
|
||||
*/
|
||||
type PayForResponse struct {
|
||||
ResultCode string `json:"resultCode,omitempty"`
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
MerchantOrderId string `json:"merchantOrderId,omitempty"`
|
||||
SettAmount string `json:"settAmount,omitempty"`
|
||||
SettFee string `json:"settFee,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商户代付结果查询结果
|
||||
*/
|
||||
type PayForQueryResponse struct {
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
MerchantOrderId string `json:"merchantOrderId,omitempty"`
|
||||
SettAmount string `json:"settAmount,omitempty"`
|
||||
SettFee string `json:"settFee,omitempty"`
|
||||
SettStatus string `json:"settStatus,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商户查询余额结果
|
||||
*/
|
||||
type BalanceResponse struct {
|
||||
ResultCode string `json:"resultCode,omitempty"`
|
||||
Balance string `json:"balance,omitempty"`
|
||||
AvailableAmount string `json:"availableAmount,omitempty"`
|
||||
FreezeAmount string `json:"freezeAmount,omitempty"`
|
||||
WaitAmount string `json:"waitAmount,omitempty"`
|
||||
LoanAmount string `json:"loanAmount,omitempty"`
|
||||
PayforAmount string `json:"payforAmount,omitempty"`
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
193
gateway/service/base_service.go
Normal file
193
gateway/service/base_service.go
Normal file
@ -0,0 +1,193 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gateway/conf"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/response"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//获取商户信息
|
||||
func GetMerchantInfo(params map[string]string) *response.PayBaseResp {
|
||||
|
||||
c := new(response.PayBaseResp)
|
||||
c.Params = make(map[string]string)
|
||||
c.Params = params
|
||||
|
||||
merchantInfo := merchant.GetMerchantByPaykey(params["payKey"])
|
||||
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户不存在,或者paykey有误,请联系管理员"
|
||||
} else if merchantInfo.Status != conf.ACTIVE {
|
||||
c.Code = -1
|
||||
c.Msg = "商户状态已经被冻结或者被删除,请联系管理员!"
|
||||
} else {
|
||||
c.MerchantInfo = merchantInfo
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func JudgeParams(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
//c.ReturnUrlIsValid()
|
||||
c = OrderIsValid(c)
|
||||
c = NotifyUrlIsValid(c)
|
||||
c = OsTypeIsValid(c)
|
||||
c = PayWayCodeIsValid(c)
|
||||
c = ProductIsValid(c)
|
||||
c = OrderPeriodIsValid(c)
|
||||
//c = IpIsWhite()
|
||||
c = OrderPriceIsValid(c)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/*
|
||||
* 插入支付订单记录和订单利润记录,保证一致性
|
||||
*/
|
||||
func InsertOrderAndOrderProfit(orderInfo order.OrderInfo, orderProfitInfo order.OrderProfitInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
if _, err := txOrm.Insert(&orderInfo); err != nil {
|
||||
logs.Error("insert orderInfo fail: ", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.Insert(&orderProfitInfo); err != nil {
|
||||
logs.Error("insert orderProfit fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断跳转地址是否符合规则
|
||||
*/
|
||||
func ReturnUrlIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["returnUrl"] == "" || len(c.Params["returnUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功后跳转地址不能为空"
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断回调地址是否符合规则
|
||||
*/
|
||||
func NotifyUrlIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["notifyUrl"] == "" || len(c.Params["notifyUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功订单回调地址不能空位"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断设备类型是否符合规则
|
||||
*/
|
||||
func OsTypeIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["osType"] == "" || len(c.Params["osType"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付设备系统类型不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断支付类型字段是否符合规则
|
||||
*/
|
||||
func PayWayCodeIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["payWayCode"] == "" || len(c.Params["payWayCode"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付类型字段不能为空"
|
||||
return c
|
||||
}
|
||||
|
||||
if !strings.Contains(c.Params["payWayCode"], "SCAN") {
|
||||
c.Code = -1
|
||||
c.Msg = "扫码支付不支持这种支付类型"
|
||||
} else {
|
||||
scanPayWayCodes := conf.GetScanPayWayCodes()
|
||||
for _, v := range scanPayWayCodes {
|
||||
if c.Params["payWayCode"] == v {
|
||||
c.PayWayCode = strings.Replace(c.Params["payWayCode"], "-", "_", -1)
|
||||
return c
|
||||
}
|
||||
}
|
||||
c.Code = -1
|
||||
c.Msg = "不存在这种支付类型,请仔细阅读对接文档"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func ProductIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["productName"] == "" || len(c.Params["productName"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商品描述信息字段不能为空"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func OrderPeriodIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["orderPeriod"] == "" || len(c.Params["orderPeriod"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单过期时间不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断订单金额
|
||||
func OrderPriceIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["orderPrice"] == "" || len(c.Params["orderPrice"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额不能为空"
|
||||
return c
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(c.Params["orderPrice"], 64)
|
||||
if err != nil {
|
||||
logs.Error("order price is invalid: ", c.Params["orderPrice"])
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额非法"
|
||||
}
|
||||
c.OrderAmount = a
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断金额订单号是否为空或者有重复
|
||||
func OrderIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["orderNo"] == "" || len(c.Params["orderNo"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号不能为空"
|
||||
return c
|
||||
}
|
||||
if order.OrderNoIsEixst(c.Params["orderNo"]) {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号重复"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断ip是否在白名单中
|
||||
func IpIsWhite() bool {
|
||||
//TODO
|
||||
return true
|
||||
}
|
249
gateway/service/pay_service.go
Normal file
249
gateway/service/pay_service.go
Normal file
@ -0,0 +1,249 @@
|
||||
/***************************************************
|
||||
** @Desc : 处理网关模块的一些需要操作数据库的功能
|
||||
** @Time : 2019/12/7 16:40
|
||||
** @Author : yuebin
|
||||
** @File : gateway_solve
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/7 16:40
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/models/road"
|
||||
"gateway/response"
|
||||
"gateway/supplier"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/rs/xid"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//选择通道
|
||||
func ChooseRoad(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
payWayCode := c.Params["payWayCode"]
|
||||
merchantUid := c.MerchantInfo.MerchantUid
|
||||
//通道配置信息
|
||||
deployInfo := merchant.GetMerchantDeployByUidAndPayType(merchantUid, payWayCode)
|
||||
if deployInfo.MerchantUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道信息"
|
||||
return c
|
||||
}
|
||||
|
||||
singleRoad := road.GetRoadInfoByRoadUid(deployInfo.SingleRoadUid)
|
||||
c.RoadPoolInfo = road.GetRoadPoolByRoadPoolCode(deployInfo.RollRoadCode)
|
||||
if RoadIsValid(singleRoad, c) {
|
||||
c.RoadInfo = singleRoad
|
||||
c.PlatformRate = deployInfo.SingleRoadPlatformRate
|
||||
c.AgentRate = deployInfo.SingleRoadAgentRate
|
||||
return c
|
||||
}
|
||||
//如果单通道没有有效的,那么寻找通道池里面的通道
|
||||
if c.RoadPoolInfo.RoadPoolCode == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道"
|
||||
return c
|
||||
}
|
||||
roadUids := strings.Split(c.RoadPoolInfo.RoadUidPool, "||")
|
||||
roadInfos := road.GetRoadInfosByRoadUids(roadUids)
|
||||
for _, roadInfo := range roadInfos {
|
||||
if RoadIsValid(roadInfo, c) {
|
||||
c.RoadInfo = roadInfo
|
||||
c.PlatformRate = deployInfo.RollRoadPlatformRate
|
||||
c.AgentRate = deployInfo.RollRoadAgentRate
|
||||
return c
|
||||
}
|
||||
}
|
||||
if c.RoadInfo.RoadUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道或者通道不可用"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断通道是否是合法的
|
||||
func RoadIsValid(roadInfo road.RoadInfo, c *response.PayBaseResp) bool {
|
||||
if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 {
|
||||
return false
|
||||
}
|
||||
FORMAT := fmt.Sprintf("该通道:%s;", roadInfo.RoadName)
|
||||
if roadInfo.Status != "active" {
|
||||
logs.Notice(FORMAT + "不是激活状态")
|
||||
return false
|
||||
}
|
||||
hour := time.Now().Hour()
|
||||
s := roadInfo.StarHour
|
||||
e := roadInfo.EndHour
|
||||
if hour < s || hour > e {
|
||||
logs.Notice(FORMAT)
|
||||
return false
|
||||
}
|
||||
minAmount := roadInfo.SingleMinLimit
|
||||
maxAmount := roadInfo.SingleMaxLimit
|
||||
if minAmount > c.OrderAmount || maxAmount < c.OrderAmount {
|
||||
logs.Error(FORMAT + "订单金额超限制")
|
||||
return false
|
||||
}
|
||||
todayLimit := roadInfo.TodayLimit
|
||||
totalLimit := roadInfo.TotalLimit
|
||||
todayIncome := roadInfo.TodayIncome
|
||||
totalIncome := roadInfo.TotalIncome
|
||||
if (todayIncome + c.OrderAmount) > todayLimit {
|
||||
logs.Error(FORMAT + "达到了每天金额上限")
|
||||
return false
|
||||
}
|
||||
if (totalIncome + c.OrderAmount) > totalLimit {
|
||||
logs.Error(FORMAT + "达到了总量限制")
|
||||
return false
|
||||
}
|
||||
//如果通道被选中,那么总请求数+1
|
||||
roadInfo.RequestAll = roadInfo.RequestAll + 1
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
road.UpdateRoadInfo(roadInfo)
|
||||
return true
|
||||
}
|
||||
|
||||
//获取基本订单记录
|
||||
func GenerateOrderInfo(c *response.PayBaseResp) order.OrderInfo {
|
||||
//6666是自己系统订单号
|
||||
bankOrderNo := "6666" + xid.New().String()
|
||||
//获取支付类型的名称,例如支付宝扫码等
|
||||
payTypeName := conf.GetNameByPayWayCode(c.Params["payWayCode"])
|
||||
orderInfo := order.OrderInfo{
|
||||
MerchantUid: c.MerchantInfo.MerchantUid,
|
||||
MerchantName: c.MerchantInfo.MerchantName,
|
||||
MerchantOrderId: c.Params["orderNo"],
|
||||
BankOrderId: bankOrderNo,
|
||||
OrderAmount: c.OrderAmount,
|
||||
FactAmount: c.OrderAmount,
|
||||
ShowAmount: c.OrderAmount,
|
||||
RollPoolCode: c.RoadPoolInfo.RoadPoolCode,
|
||||
RollPoolName: c.RoadPoolInfo.RoadPoolName,
|
||||
RoadUid: c.RoadInfo.RoadUid,
|
||||
RoadName: c.RoadInfo.RoadName,
|
||||
PayProductName: c.RoadInfo.ProductName,
|
||||
ShopName: c.Params["productName"],
|
||||
Freeze: conf.NO,
|
||||
Refund: conf.NO,
|
||||
Unfreeze: conf.NO,
|
||||
PayProductCode: c.RoadInfo.ProductUid,
|
||||
PayTypeCode: c.PayWayCode,
|
||||
PayTypeName: payTypeName,
|
||||
OsType: c.Params["osType"],
|
||||
Status: conf.WAIT,
|
||||
NotifyUrl: c.Params["notifyUrl"],
|
||||
ReturnUrl: c.Params["returnUrl"],
|
||||
OrderPeriod: c.Params["orderPeriod"],
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > conf.ZERO {
|
||||
orderInfo.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderInfo.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderInfo
|
||||
}
|
||||
|
||||
//计算收益,平台利润,代理利润
|
||||
func GenerateOrderProfit(orderInfo order.OrderInfo, c *response.PayBaseResp) order.OrderProfitInfo {
|
||||
//因为所有的手续费率都是百分率,所以需要除以100
|
||||
payTypeName := conf.GetNameByPayWayCode(c.PayWayCode)
|
||||
supplierProfit := c.OrderAmount / 100 * c.RoadInfo.BasicFee
|
||||
platformProfit := c.OrderAmount / 100 * c.PlatformRate
|
||||
agentProfit := c.OrderAmount / 100 * c.AgentRate
|
||||
//如果用户没有设置代理,那么代理利润为0.000
|
||||
if c.MerchantInfo.BelongAgentUid == "" || len(c.MerchantInfo.BelongAgentUid) == 0 {
|
||||
agentProfit = conf.ZERO
|
||||
}
|
||||
allProfit := supplierProfit + platformProfit + agentProfit
|
||||
|
||||
if allProfit >= c.OrderAmount {
|
||||
logs.Error("手续费已经超过订单金额,bankOrderId = %s", orderInfo.BankOrderId)
|
||||
c.Msg = "手续费已经超过了订单金额"
|
||||
c.Code = -1
|
||||
}
|
||||
|
||||
orderProfit := order.OrderProfitInfo{
|
||||
PayProductCode: c.RoadInfo.ProductUid,
|
||||
PayProductName: c.RoadInfo.ProductName,
|
||||
PayTypeCode: c.PayWayCode,
|
||||
PayTypeName: payTypeName,
|
||||
Status: conf.WAIT,
|
||||
MerchantOrderId: c.Params["orderNo"],
|
||||
BankOrderId: orderInfo.BankOrderId,
|
||||
OrderAmount: c.OrderAmount,
|
||||
FactAmount: c.OrderAmount,
|
||||
ShowAmount: c.OrderAmount,
|
||||
AllProfit: allProfit,
|
||||
UserInAmount: c.OrderAmount - allProfit,
|
||||
SupplierProfit: supplierProfit,
|
||||
PlatformProfit: platformProfit,
|
||||
AgentProfit: agentProfit,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
MerchantUid: c.MerchantInfo.MerchantUid,
|
||||
MerchantName: orderInfo.MerchantName,
|
||||
SupplierRate: c.RoadInfo.BasicFee,
|
||||
PlatformRate: c.PlatformRate,
|
||||
AgentRate: c.AgentRate,
|
||||
AgentName: orderInfo.AgentName,
|
||||
AgentUid: orderInfo.AgentUid,
|
||||
}
|
||||
|
||||
//如果该条订单设置了代理利率,并且设置了代理
|
||||
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > conf.ZERO {
|
||||
orderProfit.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderProfit.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderProfit
|
||||
}
|
||||
|
||||
/*
|
||||
* 生成订单一系列的记录
|
||||
*/
|
||||
func GenerateRecord(c *response.PayBaseResp) (order.OrderInfo, order.OrderProfitInfo) {
|
||||
//生成订单记录,订单利润利润
|
||||
orderInfo := GenerateOrderInfo(c)
|
||||
orderProfit := GenerateOrderProfit(orderInfo, c)
|
||||
if c.Code == -1 {
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
if !InsertOrderAndOrderProfit(orderInfo, orderProfit) {
|
||||
c.Code = -1
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
logs.Info("插入支付订单记录和支付利润记录成功")
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
|
||||
func GenerateSuccessData(scanData supplier.ScanData, c *response.PayBaseResp) *response.ScanSuccessData {
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = scanData.OrderNo
|
||||
params["orderPrice"] = scanData.OrderPrice
|
||||
params["payKey"] = c.MerchantInfo.MerchantKey
|
||||
params["payURL"] = scanData.PayUrl
|
||||
params["statusCode"] = "00"
|
||||
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, c.MerchantInfo.MerchantSecret)
|
||||
scanSuccessData := new(response.ScanSuccessData)
|
||||
|
||||
scanSuccessData.StatusCode = "00"
|
||||
scanSuccessData.PayKey = c.MerchantInfo.MerchantKey
|
||||
scanSuccessData.OrderNo = scanData.OrderNo
|
||||
scanSuccessData.OrderPrice = scanData.OrderPrice
|
||||
scanSuccessData.PayUrl = scanData.PayUrl
|
||||
scanSuccessData.PayKey = c.MerchantInfo.MerchantKey
|
||||
scanSuccessData.Msg = "请求成功"
|
||||
scanSuccessData.Sign = sign
|
||||
|
||||
return scanSuccessData
|
||||
}
|
503
gateway/service/pay_solve.go
Normal file
503
gateway/service/pay_solve.go
Normal file
@ -0,0 +1,503 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/notify"
|
||||
"gateway/models/order"
|
||||
"gateway/models/road"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//处理支付成功的加款等各项操作
|
||||
func SolvePaySuccess(bankOrderId string, factAmount float64, trxNo string) bool {
|
||||
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var orderInfo order.OrderInfo
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(&orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("不存在该订单,或者select for update出错")
|
||||
return err
|
||||
}
|
||||
|
||||
if orderInfo.Status != "wait" {
|
||||
logs.Error("该订单已经处理,订单号=", bankOrderId)
|
||||
return errors.New(fmt.Sprintf("该订单已经处理,订单号= %s", bankOrderId))
|
||||
}
|
||||
|
||||
if factAmount <= conf.ZERO {
|
||||
factAmount = orderInfo.OrderAmount
|
||||
}
|
||||
|
||||
var orderProfitInfo order.OrderProfitInfo
|
||||
if err := txOrm.Raw("select * from order_profit_info where bank_order_id = ? for update", bankOrderId).QueryRow(&orderProfitInfo); err != nil || orderProfitInfo.BankOrderId == "" {
|
||||
logs.Error("select order_profit_info for update fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if orderProfitInfo.BankOrderId == "" {
|
||||
logs.Error("solve pay success, get orderProfit fail, bankOrderId = ", bankOrderId)
|
||||
return errors.New(fmt.Sprintf("solve pay success, get orderProfit fail, bankOrderId = %s", bankOrderId))
|
||||
}
|
||||
|
||||
orderInfo.Status = conf.SUCCESS
|
||||
orderInfo.BankTransId = trxNo
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update order info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
orderSettleInfo := order.OrderSettleInfo{
|
||||
PayTypeCode: orderInfo.PayTypeCode,
|
||||
PayProductCode: orderInfo.PayProductCode,
|
||||
RoadUid: orderInfo.RoadUid,
|
||||
PayProductName: orderInfo.PayProductName,
|
||||
PayTypeName: orderInfo.PayTypeName,
|
||||
MerchantUid: orderInfo.MerchantUid,
|
||||
MerchantOrderId: orderInfo.MerchantOrderId,
|
||||
MerchantName: orderInfo.MerchantName,
|
||||
BankOrderId: bankOrderId,
|
||||
SettleAmount: orderProfitInfo.UserInAmount,
|
||||
IsAllowSettle: conf.YES,
|
||||
IsCompleteSettle: conf.NO,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&orderSettleInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success,insert order settle info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//做账户的加款操作,最重要的一部
|
||||
var accountInfo accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(&accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error(fmt.Sprintf("solve pay success, raw account info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.QueryTable(accounts.ACCOUNT_INFO).Filter("account_uid", orderInfo.MerchantUid).
|
||||
Update((orm.Params{"balance": accountInfo.Balance + orderProfitInfo.UserInAmount, "wait_amount": accountInfo.WaitAmount + orderProfitInfo.UserInAmount})); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update account info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//添加一条动账记录
|
||||
accountHistory := accounts.AccountHistoryInfo{
|
||||
AccountUid: orderInfo.MerchantUid,
|
||||
AccountName: orderInfo.MerchantName,
|
||||
Type: conf.PLUS_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: accountInfo.Balance + orderProfitInfo.UserInAmount,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistory); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success,insert account history fail:%s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//更新通道信息
|
||||
roadInfo := road.GetRoadInfoByRoadUid(orderInfo.RoadUid)
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
roadInfo.RequestSuccess += 1
|
||||
roadInfo.TotalIncome += orderInfo.FactAmount
|
||||
roadInfo.TodayIncome += orderInfo.FactAmount
|
||||
roadInfo.TodayProfit += orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit
|
||||
roadInfo.TotalProfit += orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&roadInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update road info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//更新订单利润表
|
||||
orderProfitInfo.Status = conf.SUCCESS
|
||||
orderProfitInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&orderProfitInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update order profit info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
// 给下游发送回调通知
|
||||
go CreateOrderNotifyInfo(orderInfo, conf.SUCCESS)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("SolvePaySuccess失败:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logs.Info("SolvePaySuccess处理成功")
|
||||
return true
|
||||
}
|
||||
|
||||
//处理支付失败
|
||||
func SolvePayFail(bankOrderId, transId string) bool {
|
||||
o := orm.NewOrm()
|
||||
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var orderTmp order.OrderInfo
|
||||
//bankOrderId := orderInfo.BankOrderId
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ?", bankOrderId).QueryRow(&orderTmp); err != nil || orderTmp.BankOrderId == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
if orderTmp.Status != "wait" {
|
||||
return errors.New("订单已经处理,不要重复加款")
|
||||
}
|
||||
if _, err := txOrm.QueryTable(order.ORDER_INFO).Filter("bank_order_id", bankOrderId).Update(orm.Params{"status": conf.FAIL, "bank_trans_id": transId}); err != nil {
|
||||
logs.Error("更改订单状态失败:", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.QueryTable(order.ORDER_PROFIT_INFO).Filter("bank_order_id", bankOrderId).Update(orm.Params{"status": conf.FAIL, "bank_trans_id": transId}); err != nil {
|
||||
logs.Error("更改订单状态失败:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
go CreateOrderNotifyInfo(orderTmp, conf.FAIL)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("SolvePayFail:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logs.Info("SolvePayFail成功")
|
||||
return true
|
||||
}
|
||||
|
||||
//处理订单冻结
|
||||
func SolveOrderFreeze(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var orderInfo order.OrderInfo
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(&orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("solve order freeze 不存在这样的订单记录,bankOrderId = ", bankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
if orderInfo.Status != conf.SUCCESS {
|
||||
logs.Error("非成功订单不能进行冻结")
|
||||
return errors.New("非成功订单不能进行冻结")
|
||||
}
|
||||
|
||||
orderInfo.Freeze = conf.YES
|
||||
orderInfo.FreezeTime = utils.GetBasicDateTime()
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&orderInfo); err != nil {
|
||||
logs.Error("solve order freeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
//账户的冻结金额里面加入相应的金额
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
|
||||
var accountInfo accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(&accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error(fmt.Sprintf("solve pay fail select acount fail:%s", err))
|
||||
return err
|
||||
}
|
||||
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
accountInfo.FreezeAmount = accountInfo.FreezeAmount + orderProfitInfo.UserInAmount
|
||||
if _, err := txOrm.Update(&accountInfo); err != nil {
|
||||
logs.Error("solve order freeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
//插入一条动账记录
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountName: accountInfo.AccountName,
|
||||
AccountUid: accountInfo.AccountUid,
|
||||
Type: conf.FREEZE_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: accountInfo.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
logs.Error("solve order freeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("SolveOrderFreeze:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logs.Info("SolveOrderFreeze")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//订单解冻
|
||||
func SolveOrderUnfreeze(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
orderInfo := new(order.OrderInfo)
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("solve order unfreeze 不存在这样的订单记录,bankOrderId = ", bankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
orderInfo.Freeze = ""
|
||||
orderInfo.Unfreeze = conf.YES
|
||||
orderInfo.UnfreezeTime = utils.GetBasicDateTime()
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(orderInfo); err != nil {
|
||||
logs.Error("solve order unfreeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
|
||||
accountInfo := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error(fmt.Sprintf("unfreeze select account fail: %s", err))
|
||||
return err
|
||||
}
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
accountInfo.FreezeAmount = accountInfo.FreezeAmount - orderProfitInfo.UserInAmount
|
||||
|
||||
if _, err := txOrm.Update(accountInfo); err != nil {
|
||||
logs.Error("solve order unfreeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountUid: accountInfo.AccountUid,
|
||||
AccountName: accountInfo.AccountName,
|
||||
Type: conf.UNFREEZE_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: accountInfo.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
logs.Error("SolveOrderUnfreeze失败:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func SolveRefund(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
orderInfo := new(order.OrderInfo)
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("solve refund 不存在这样的订单,bankOrderId = " + bankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
orderInfo.Refund = conf.YES
|
||||
orderInfo.RefundTime = utils.GetBasicDateTime()
|
||||
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
account := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(account); err != nil || account.AccountUid == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
account.SettleAmount = account.SettleAmount - orderProfitInfo.UserInAmount
|
||||
account.Balance = account.Balance - orderProfitInfo.UserInAmount
|
||||
|
||||
if orderInfo.Freeze == conf.YES {
|
||||
account.FreezeAmount = account.FreezeAmount - orderProfitInfo.UserInAmount
|
||||
if account.FreezeAmount < 0 {
|
||||
account.FreezeAmount = conf.ZERO
|
||||
}
|
||||
orderInfo.Freeze = ""
|
||||
}
|
||||
|
||||
if _, err := txOrm.Update(orderInfo); err != nil {
|
||||
logs.Error("solve order refund update order info fail: ", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.Update(account); err != nil {
|
||||
logs.Error("solve order refund update account fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountName: account.AccountName,
|
||||
AccountUid: account.AccountUid,
|
||||
Type: conf.REFUND,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: account.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
logs.Error("solve order refund insert account history fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
logs.Error("SolveRefund 成功:", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SolveOrderRoll(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
orderInfo := new(order.OrderInfo)
|
||||
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(orderInfo); err != nil {
|
||||
logs.Error("solve order roll fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if orderInfo.Status != conf.SUCCESS {
|
||||
logs.Error("solve order roll 订单不存在或者订单状态不是success, bankOrderId=", bankOrderId)
|
||||
return errors.New("solve order roll failed")
|
||||
}
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
|
||||
account := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(account); err != nil || account.AccountUid == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
if orderInfo.Refund == conf.YES {
|
||||
account.Balance = account.Balance + orderProfitInfo.UserInAmount
|
||||
account.SettleAmount = account.SettleAmount + orderProfitInfo.UserInAmount
|
||||
orderInfo.Refund = conf.NO
|
||||
}
|
||||
|
||||
if _, err := txOrm.Update(orderInfo); err != nil {
|
||||
logs.Error("solve order roll fail update order info fail: ", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.Update(account); err != nil {
|
||||
logs.Error("solve order roll update account fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountUid: account.AccountUid,
|
||||
AccountName: account.AccountName,
|
||||
Type: conf.PLUS_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: account.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
logs.Error("solve order roll insert account history fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
logs.Error("SolveOrderRoll处理失败:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//比较订单金额和实际支付金额的大小
|
||||
func CompareOrderAndFactAmount(factAmount float64, orderInfo order.OrderInfo) int {
|
||||
orderAmount := orderInfo.OrderAmount
|
||||
//将金额放大1000倍
|
||||
oa := int64(orderAmount * 1000)
|
||||
fa := int64(factAmount * 1000)
|
||||
if oa > fa {
|
||||
//如果实际金额大,返回1
|
||||
return 1
|
||||
} else if oa == fa {
|
||||
return 0
|
||||
} else {
|
||||
return 2
|
||||
}
|
||||
}
|
||||
|
||||
//支付完成后,处理给商户的回调信息
|
||||
func CreateOrderNotifyInfo(orderInfo order.OrderInfo, tradeStatus string) {
|
||||
|
||||
notifyInfo := new(notify.NotifyInfo)
|
||||
notifyInfo.Type = "order"
|
||||
notifyInfo.BankOrderId = orderInfo.BankOrderId
|
||||
notifyInfo.MerchantOrderId = orderInfo.MerchantOrderId
|
||||
notifyInfo.Status = "wait"
|
||||
notifyInfo.Times = 0
|
||||
notifyInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
notifyInfo.CreateTime = utils.GetBasicDateTime()
|
||||
|
||||
merchantInfo := merchant.GetMerchantByUid(orderInfo.MerchantUid)
|
||||
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = orderInfo.MerchantOrderId
|
||||
params["orderPrice"] = strconv.FormatFloat(orderInfo.OrderAmount, 'f', 2, 64)
|
||||
params["factPrice"] = strconv.FormatFloat(orderInfo.FactAmount, 'f', 2, 64)
|
||||
params["orderTime"] = utils.GetDateTimeNot()
|
||||
|
||||
if orderInfo.BankTransId != "" {
|
||||
params["trxNo"] = orderInfo.BankTransId
|
||||
} else {
|
||||
params["trxNo"] = orderInfo.BankOrderId
|
||||
}
|
||||
params["statusCode"] = "00"
|
||||
params["tradeStatus"] = tradeStatus
|
||||
params["payKey"] = merchantInfo.MerchantKey
|
||||
|
||||
params["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
|
||||
u := url.Values{}
|
||||
for k, v := range params {
|
||||
u.Add(k, v)
|
||||
}
|
||||
|
||||
notifyInfo.Url = orderInfo.NotifyUrl + "?" + u.Encode()
|
||||
|
||||
if notify.InsertNotifyInfo(*notifyInfo) {
|
||||
logs.Info(fmt.Sprintf("订单bankOrderId=%s,已经将回调地址插入数据库", orderInfo.BankOrderId))
|
||||
} else {
|
||||
logs.Error(fmt.Sprintf("订单bankOrderId=%s,插入回调数据库失败", orderInfo.BankOrderId))
|
||||
}
|
||||
//将订单发送到消息队列,给下面的商户进行回调
|
||||
go message.SendMessage(conf.MqOrderNotify, orderInfo.BankOrderId)
|
||||
}
|
234
gateway/service/settle_service.go
Normal file
234
gateway/service/settle_service.go
Normal file
@ -0,0 +1,234 @@
|
||||
/***************************************************
|
||||
** @Desc : 订单结算,将订单上面的钱加入到账户余额中
|
||||
** @Time : 2019/11/22 11:34
|
||||
** @Author : yuebin
|
||||
** @File : order_settle
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 11:34
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
Interval = 2 //隔多少分钟进行结算
|
||||
Minutes = 1 //每隔15分钟,进行扫码,看有没有隔天押款金额
|
||||
)
|
||||
|
||||
/**
|
||||
* 订单结算,将那些支付成功的订单金额加入到商户账户的结算金额中
|
||||
*/
|
||||
func OrderSettle() {
|
||||
|
||||
params := make(map[string]string)
|
||||
params["is_allow_settle"] = conf.YES
|
||||
params["is_complete_settle"] = conf.NO
|
||||
orderSettleList := order.GetOrderSettleListByParams(params)
|
||||
for _, orderSettle := range orderSettleList {
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(orderSettle.BankOrderId)
|
||||
if !settle(orderSettle, orderProfitInfo) {
|
||||
logs.Error(fmt.Sprintf("结算订单bankOrderId = #{orderSettle.BankOrderId}, 执行失败"))
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("结算订单bankOrderId= #{orderSettle.BankOrderId},执行成功"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func settle(orderSettle order.OrderSettleInfo, orderProfit order.OrderProfitInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
tmpSettle := new(order.OrderSettleInfo)
|
||||
if err := txOrm.Raw("select * from order_settle_info where bank_order_id=? for update", orderSettle.BankOrderId).QueryRow(tmpSettle); err != nil || tmpSettle.BankOrderId == "" {
|
||||
logs.Error("获取tmpSettle失败,bankOrderId=%s", orderSettle.BankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
tmpSettle.UpdateTime = utils.GetBasicDateTime()
|
||||
tmpSettle.IsCompleteSettle = conf.YES
|
||||
if _, err := txOrm.Update(tmpSettle); err != nil {
|
||||
logs.Error("更新tmpSettle失败,错误:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountInfo := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid=? for update", orderSettle.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo.UpdateTime == "" {
|
||||
logs.Error("结算select account info失败,错误信息:", err)
|
||||
return err
|
||||
}
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
// 商户有押款操作
|
||||
loadAmount := 0.0
|
||||
merchantDeployInfo := merchant.GetMerchantDeployByUidAndPayType(accountInfo.AccountUid, orderSettle.PayTypeCode)
|
||||
if merchantDeployInfo.IsLoan == conf.YES {
|
||||
loadAmount = merchantDeployInfo.LoanRate * 0.01 * orderProfit.FactAmount
|
||||
date := utils.GetDate()
|
||||
params := make(map[string]string)
|
||||
params["merchant_uid"] = tmpSettle.MerchantUid
|
||||
params["road_uid"] = tmpSettle.RoadUid
|
||||
params["load_date"] = date
|
||||
if !merchant.IsExistMerchantLoadByParams(params) {
|
||||
|
||||
tmp := merchant.MerchantLoadInfo{Status: conf.NO, MerchantUid: orderSettle.MerchantUid, RoadUid: orderSettle.RoadUid,
|
||||
LoadDate: utils.GetDateAfterDays(merchantDeployInfo.LoanDays), LoadAmount: loadAmount,
|
||||
UpdateTime: utils.GetBasicDateTime(), CreateTime: utils.GetBasicDateTime()}
|
||||
|
||||
if _, err := txOrm.Insert(&tmp); err != nil {
|
||||
logs.Error("結算插入merchantLoad失敗,失败信息:", err)
|
||||
return err
|
||||
} else {
|
||||
logs.Info("结算插入新的merchantLoad信息成功")
|
||||
}
|
||||
} else {
|
||||
merchantLoad := new(merchant.MerchantLoadInfo)
|
||||
if err := txOrm.Raw("select * from merchant_load_info where merchant_uid=? and road_uid=? and load_date=? for update").
|
||||
QueryRow(merchantLoad); err != nil || merchantLoad.UpdateTime == "" {
|
||||
logs.Error(fmt.Sprintf("结算过程,select merchant load info失败,错误信息:#{err}"))
|
||||
return err
|
||||
} else {
|
||||
merchantLoad.UpdateTime = utils.GetBasicDateTime()
|
||||
merchantLoad.LoadAmount += loadAmount
|
||||
if _, err := txOrm.Update(merchantLoad); err != nil {
|
||||
logs.Error(fmt.Sprintf("结算过程,update merchant load info失败,失败信息:#{err}"))
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("结算过程中,该商户不需要押款,全款结算"))
|
||||
}
|
||||
|
||||
if accountInfo.WaitAmount < orderProfit.UserInAmount {
|
||||
logs.Error("系统出现严重故障,账户的带结算金额小于订单结算金额")
|
||||
return errors.New("系统出现严重故障,账户的带结算金额小于订单结算金额, 账户 = " + accountInfo.AccountName + "订单id = " + orderProfit.BankOrderId)
|
||||
}
|
||||
|
||||
needAmount := orderProfit.UserInAmount - loadAmount
|
||||
|
||||
accountInfo.SettleAmount = accountInfo.SettleAmount + needAmount
|
||||
accountInfo.WaitAmount = accountInfo.WaitAmount - orderProfit.UserInAmount
|
||||
accountInfo.LoanAmount = accountInfo.LoanAmount + loadAmount
|
||||
|
||||
if _, err := txOrm.Update(accountInfo); err != nil {
|
||||
logs.Error("结算update account 失败,错误信息:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
* 商户的押款释放处理,根据商户的押款时间进行处理
|
||||
*/
|
||||
func MerchantLoadSolve() {
|
||||
hour := time.Now().Hour()
|
||||
merchantDeployList := merchant.GetMerchantDeployByHour(hour)
|
||||
for _, merchantDeploy := range merchantDeployList {
|
||||
logs.Info(fmt.Sprintf("开始执行商户uid= #{merchantDeploy.MerchantUid},进行解款操作"))
|
||||
|
||||
loadDate := utils.GetDateBeforeDays(merchantDeploy.LoanDays)
|
||||
params := make(map[string]string)
|
||||
params["status"] = conf.NO
|
||||
params["merchant_uid"] = merchantDeploy.MerchantUid
|
||||
params["load_date"] = loadDate
|
||||
|
||||
merchantLoadList := merchant.GetMerchantLoadInfoByMap(params)
|
||||
for _, merchantLoad := range merchantLoadList {
|
||||
if MerchantAbleAmount(merchantLoad) {
|
||||
logs.Info(fmt.Sprintf("商户uid= %s,押款金额=%f,押款通道= %s, 解款成功", merchantLoad.MerchantUid, merchantLoad.LoadAmount, merchantLoad.RoadUid))
|
||||
} else {
|
||||
logs.Error(fmt.Sprintf("商户uid=%s,押款金额=%f,押款通道=%s, 解款失败", merchantLoad.MerchantUid, merchantLoad.LoadAmount, merchantLoad.RoadUid))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 对应的商户的账户可用金额进行调整操作
|
||||
*/
|
||||
func MerchantAbleAmount(merchantLoad merchant.MerchantLoadInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
tmpLoad := new(merchant.MerchantLoadInfo)
|
||||
if err := txOrm.Raw("select * from merchant_load_info where merchant_uid=? and road_uid=? and load_date=? for update",
|
||||
merchantLoad.MerchantUid, merchantLoad.RoadUid, merchantLoad.LoadDate).QueryRow(tmpLoad); err != nil || tmpLoad.MerchantUid == "" {
|
||||
logs.Error(fmt.Sprintf("解款操作获取商户押款信息失败,fail: %s", err))
|
||||
return err
|
||||
|
||||
}
|
||||
if tmpLoad.Status != conf.NO {
|
||||
logs.Error(fmt.Sprintf("押款信息merchantuid=%s,通道uid=%s, 押款日期=%s,已经解款过,不需要再进行处理了", tmpLoad.MerchantUid, tmpLoad.RoadUid, tmpLoad.LoadDate))
|
||||
return errors.New("已经解款过,不需要再进行处理了")
|
||||
}
|
||||
|
||||
tmpLoad.UpdateTime = utils.GetBasicDateTime()
|
||||
tmpLoad.Status = conf.YES
|
||||
if _, err := txOrm.Update(tmpLoad); err != nil {
|
||||
logs.Error(fmt.Sprintf("解款操作更新merchant load info 失败:%s", err))
|
||||
return err
|
||||
}
|
||||
|
||||
accountInfo := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", merchantLoad.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error("结款操作获取账户信息失败:", err)
|
||||
return err
|
||||
}
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if accountInfo.LoanAmount >= tmpLoad.LoadAmount {
|
||||
accountInfo.LoanAmount = accountInfo.LoanAmount - tmpLoad.LoadAmount
|
||||
accountInfo.SettleAmount = accountInfo.SettleAmount + tmpLoad.LoadAmount
|
||||
} else {
|
||||
accountInfo.LoanAmount = conf.ZERO
|
||||
}
|
||||
|
||||
if _, err := txOrm.Update(accountInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("解款操作更新account info 失败:%s,账户uid=%s", err, accountInfo.AccountUid))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func OrderSettleInit() {
|
||||
//每隔5分钟,巡查有没有可以进行结算的订单
|
||||
go func() {
|
||||
settleTimer := time.NewTimer(time.Duration(Interval) * time.Minute)
|
||||
oneMinuteTimer := time.NewTimer(time.Duration(Minutes) * time.Minute)
|
||||
for {
|
||||
select {
|
||||
case <-settleTimer.C:
|
||||
settleTimer = time.NewTimer(time.Duration(Interval) * time.Minute)
|
||||
logs.Info("开始对商户进行支付订单结算>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
||||
OrderSettle()
|
||||
case <-oneMinuteTimer.C:
|
||||
oneMinuteTimer = time.NewTimer(time.Duration(Minutes) * time.Minute)
|
||||
logs.Info("开始执行商户的解款操作>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
||||
MerchantLoadSolve()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
@ -7,10 +7,13 @@
|
||||
** @Last Modified time: 2019/10/28 9:39
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package controller
|
||||
package supplier
|
||||
|
||||
import (
|
||||
"gateway/models"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
)
|
||||
|
||||
//定义扫码支付的返回值
|
||||
@ -27,15 +30,15 @@ type ScanData struct {
|
||||
}
|
||||
|
||||
type PayInterface interface {
|
||||
Scan(models.OrderInfo, models.RoadInfo, models.MerchantInfo) ScanData
|
||||
H5(models.OrderInfo, models.RoadInfo, models.MerchantInfo) ScanData
|
||||
Fast(models.OrderInfo, models.RoadInfo, models.MerchantInfo) bool
|
||||
Syt(models.OrderInfo, models.RoadInfo, models.MerchantInfo) ScanData
|
||||
Web(models.OrderInfo, models.RoadInfo, models.MerchantInfo) bool
|
||||
Scan(order.OrderInfo, road.RoadInfo, merchant.MerchantInfo) ScanData
|
||||
H5(order.OrderInfo, road.RoadInfo, merchant.MerchantInfo) ScanData
|
||||
Fast(order.OrderInfo, road.RoadInfo, merchant.MerchantInfo) bool
|
||||
Syt(order.OrderInfo, road.RoadInfo, merchant.MerchantInfo) ScanData
|
||||
Web(order.OrderInfo, road.RoadInfo, merchant.MerchantInfo) bool
|
||||
PayNotify()
|
||||
PayQuery(models.OrderInfo) bool
|
||||
PayFor(models.PayforInfo) string
|
||||
PayQuery(order.OrderInfo) bool
|
||||
PayFor(payfor.PayforInfo) string
|
||||
PayForNotify() string
|
||||
PayForQuery(models.PayforInfo) (string, string)
|
||||
BalanceQuery(models.RoadInfo) float64
|
||||
PayForQuery(payfor.PayforInfo) (string, string)
|
||||
BalanceQuery(road.RoadInfo) float64
|
||||
}
|
||||
|
190
gateway/supplier/third_party/daili.go
vendored
Normal file
190
gateway/supplier/third_party/daili.go
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/28 16:38
|
||||
** @Author : yuebin
|
||||
** @File : alipay
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/28 16:38
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package third_party
|
||||
|
||||
import (
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
"gateway/service"
|
||||
"gateway/supplier"
|
||||
"gateway/utils"
|
||||
"github.com/astaxie/beego/httplib"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
"github.com/rs/xid"
|
||||
"github.com/widuu/gojson"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DaiLiImpl struct {
|
||||
web.Controller
|
||||
}
|
||||
|
||||
const NOTITY_URL = "http://localhost:12306/accept/notify"
|
||||
const URL = "http://zhaoyin.lfwin.com/payapi/pay/jspay3"
|
||||
|
||||
func (c *DaiLiImpl) Scan(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||||
// 从boss后台获取数据
|
||||
service := gojson.Json(roadInfo.Params).Get("service").Tostring()
|
||||
apiKey := gojson.Json(roadInfo.Params).Get("apikey").Tostring()
|
||||
signKey := gojson.Json(roadInfo.Params).Get("signkey").Tostring()
|
||||
|
||||
params := make(map[string]string)
|
||||
params["service"] = service
|
||||
params["apikey"] = apiKey
|
||||
params["money"] = strconv.FormatFloat(orderInfo.OrderAmount, 'f', 2, 32)
|
||||
params["nonce_str"] = xid.New().String()
|
||||
params["mch_orderid"] = orderInfo.BankOrderId
|
||||
params["notify_url"] = NOTITY_URL
|
||||
|
||||
waitStr := utils.MapToString(utils.SortMapByKeys(params))
|
||||
waitStr = waitStr + "&signkey=" + signKey
|
||||
sign := utils.GetMD5LOWER(waitStr)
|
||||
params["sign"] = sign
|
||||
|
||||
request := URL + "?" + utils.MapToString(params)
|
||||
|
||||
logs.Info("代丽请求字符串 = " + request)
|
||||
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "00"
|
||||
response, err := httplib.Post(request).String()
|
||||
if err != nil {
|
||||
logs.Error("代丽支付请求失败:" + err.Error())
|
||||
scanData.Status = "-1"
|
||||
scanData.Msg = "请求失败:" + err.Error()
|
||||
} else {
|
||||
/*logs.Info("代丽支付返回 = " + response)
|
||||
status := gojson.Json(response).Get("status").Tostring()
|
||||
message := gojson.Json(response).Get("message").Tostring()
|
||||
if "10000" != status {
|
||||
scanData.Status = "-1"
|
||||
scanData.Msg = message
|
||||
} else {*/
|
||||
codeUrl := gojson.Json(response).Get("url").Tostring()
|
||||
codeUrl = "http://www.baidu.com"
|
||||
scanData.PayUrl = codeUrl
|
||||
scanData.OrderNo = orderInfo.BankOrderId
|
||||
scanData.OrderPrice = strconv.FormatFloat(orderInfo.OrderAmount, 'f', 2, 64)
|
||||
//}
|
||||
}
|
||||
|
||||
return scanData
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) H5(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return scanData
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) Syt(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return scanData
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) Fast(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) bool {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) Web(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) bool {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) PayNotify() {
|
||||
params := make(map[string]string)
|
||||
orderNo := strings.TrimSpace(c.GetString("orderNo"))
|
||||
orderInfo := order.GetOrderByBankOrderId(orderNo)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
logs.Error("快付回调的订单号不存在,订单号=", orderNo)
|
||||
c.StopRun()
|
||||
}
|
||||
roadInfo := road.GetRoadInfoByRoadUid(orderInfo.RoadUid)
|
||||
if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 {
|
||||
logs.Error("支付通道已经关系或者删除,不进行回调")
|
||||
c.StopRun()
|
||||
}
|
||||
merchantUid := orderInfo.MerchantUid
|
||||
merchantInfo := merchant.GetMerchantByUid(merchantUid)
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
logs.Error("快付回调失败,该商户不存在或者已经删除,商户uid=", merchantUid)
|
||||
c.StopRun()
|
||||
}
|
||||
paySecret := merchantInfo.MerchantSecret
|
||||
params["orderNo"] = orderNo
|
||||
params["orderPrice"] = strings.TrimSpace(c.GetString("orderPrice"))
|
||||
params["orderTime"] = strings.TrimSpace(c.GetString("orderTime"))
|
||||
params["trxNo"] = strings.TrimSpace(c.GetString("trxNo"))
|
||||
params["statusCode"] = strings.TrimSpace(c.GetString("statusCode"))
|
||||
params["tradeStatus"] = strings.TrimSpace(c.GetString("tradeStatus"))
|
||||
params["field1"] = strings.TrimSpace(c.GetString("field1"))
|
||||
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
|
||||
//对参数进行验签
|
||||
keys := utils.SortMap(params)
|
||||
tmpSign := utils.GetMD5Sign(params, keys, paySecret)
|
||||
sign := strings.TrimSpace(c.GetString("sign"))
|
||||
if tmpSign != sign {
|
||||
logs.Error("代丽回调签名异常,回调失败")
|
||||
//c.StopRun()
|
||||
}
|
||||
//实际支付金额
|
||||
factAmount, err := strconv.ParseFloat(params["orderPrice"], 64)
|
||||
if err != nil {
|
||||
orderInfo.FactAmount = 0
|
||||
}
|
||||
orderInfo.FactAmount = factAmount
|
||||
orderInfo.BankTransId = params["trxNo"]
|
||||
tradeStatus := params["tradeStatus"]
|
||||
|
||||
//paySolveController := new(service.PaySolveController)
|
||||
if tradeStatus == "FAILED" {
|
||||
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
|
||||
logs.Error("solve order fail fail")
|
||||
}
|
||||
} else if tradeStatus == "CANCELED" {
|
||||
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
|
||||
logs.Error("solve order cancel fail")
|
||||
}
|
||||
} else if tradeStatus == "WAITING_PAYMENT" {
|
||||
logs.Notice("快付回调,该订单还处于等待支付,订单id=", orderNo)
|
||||
} else if tradeStatus == "SUCCESS" {
|
||||
//订单支付成功,需要搞很多事情 TODO
|
||||
service.SolvePaySuccess(orderInfo.BankOrderId, orderInfo.FactAmount, c.GetString("trxNo"))
|
||||
}
|
||||
c.Ctx.WriteString("success")
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) PayQuery(orderInfo order.OrderInfo) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) PayFor(info payfor.PayforInfo) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) PayForNotify() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) PayForQuery(payFor payfor.PayforInfo) (string, string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func (c *DaiLiImpl) BalanceQuery(roadInfo road.RoadInfo) float64 {
|
||||
return 0.00
|
||||
}
|
48
gateway/supplier/third_party/init.go
vendored
Normal file
48
gateway/supplier/third_party/init.go
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/***************************************************
|
||||
** @Desc : 注册上游支付接口
|
||||
** @Time : 2019/10/28 14:48
|
||||
** @Author : yueBin
|
||||
** @File : init
|
||||
** @Last Modified by : yueBin
|
||||
** @Last Modified time: 2019/10/28 14:48
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package third_party
|
||||
|
||||
import (
|
||||
"gateway/supplier"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
//添加新的上游通道时,需要添加这里
|
||||
var supplierCode2Name = map[string]string{
|
||||
"KF": "快付支付",
|
||||
"WEIXIN": "官方微信",
|
||||
"ALIPAY": "官方支付宝",
|
||||
"DAILI": "代丽支付",
|
||||
}
|
||||
|
||||
var registerSupplier = make(map[string]supplier.PayInterface)
|
||||
|
||||
//注册各种上游的支付接口
|
||||
|
||||
func init() {
|
||||
registerSupplier["KF"] = new(KuaiFuImpl)
|
||||
logs.Notice(CheckSupplierByCode("KF"))
|
||||
|
||||
registerSupplier["DAILI"] = new(DaiLiImpl)
|
||||
logs.Notice(CheckSupplierByCode("DAILI"))
|
||||
}
|
||||
|
||||
func GetPaySupplierByCode(code string) supplier.PayInterface {
|
||||
return registerSupplier[code]
|
||||
}
|
||||
|
||||
func CheckSupplierByCode(code string) string {
|
||||
for k, v := range supplierCode2Name {
|
||||
if k == code {
|
||||
return v + ",注册完毕"
|
||||
}
|
||||
}
|
||||
return "未找到上游名称,注册有问题。"
|
||||
}
|
384
gateway/supplier/third_party/kuaifu.go
vendored
Normal file
384
gateway/supplier/third_party/kuaifu.go
vendored
Normal file
@ -0,0 +1,384 @@
|
||||
/***************************************************
|
||||
** @Desc : 快付支付的实现逻辑
|
||||
** @Time : 2019/10/28 14:12
|
||||
** @Author : yuebin
|
||||
** @File : kuaifu
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/28 14:12
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package third_party
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
"gateway/service"
|
||||
"gateway/supplier"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/httplib"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/rs/xid"
|
||||
"github.com/widuu/gojson"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type KuaiFuImpl struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
const (
|
||||
HOST = "localhost"
|
||||
KF_SCAN_HOST = "http://" + HOST + "/gateway/scanPay/payService"
|
||||
KF_PAYFOR_HOST = "http://" + HOST + "/gateway/remittance/pay"
|
||||
KF_BALANCE_QUERY = "http://" + HOST + "/gateway/remittance/getBalance"
|
||||
KF_ORDER_QUERY = "http://" + HOST + "/gateway/scanPay/orderQuery"
|
||||
KF_PAYFOR_QUERY = "http://" + HOST + "/gateway/remittance/query"
|
||||
KF_PAY_KEY = "xxxxxxx"
|
||||
KF_PAY_SECRET = "xxxxxx"
|
||||
)
|
||||
|
||||
func (c *KuaiFuImpl) Scan(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||||
payWayCode := ""
|
||||
switch orderInfo.PayTypeCode {
|
||||
case "ALI_SCAN":
|
||||
payWayCode = "SCAN_ALIPAY"
|
||||
case "WEIXIN_SCAN":
|
||||
payWayCode = "SCAN_WEIXIN"
|
||||
case "QQ_SCAN":
|
||||
payWayCode = "SCAN_QQ"
|
||||
case "UNION_SCAN":
|
||||
payWayCode = "SCAN_YL"
|
||||
case "BAIDU_SCAN":
|
||||
case "JD_SCAN":
|
||||
}
|
||||
//将金额转为带有2位小数点的float
|
||||
order := fmt.Sprintf("%0.2f", orderInfo.OrderAmount)
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = orderInfo.BankOrderId
|
||||
params["productName"] = orderInfo.ShopName
|
||||
params["orderPeriod"] = orderInfo.OrderPeriod
|
||||
params["orderPrice"] = order
|
||||
params["payWayCode"] = payWayCode
|
||||
params["osType"] = orderInfo.OsType
|
||||
params["notifyUrl"] = "KF"
|
||||
params["payKey"] = KF_PAY_KEY
|
||||
//params["field1"] = "field1"
|
||||
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, KF_PAY_SECRET)
|
||||
params["sign"] = sign
|
||||
|
||||
req := httplib.Post(KF_SCAN_HOST)
|
||||
for k, v := range params {
|
||||
req.Param(k, v)
|
||||
}
|
||||
var scanData supplier.ScanData
|
||||
scanData.Supplier = orderInfo.PayProductCode
|
||||
scanData.PayType = orderInfo.PayTypeCode
|
||||
scanData.OrderNo = orderInfo.MerchantOrderId
|
||||
scanData.BankNo = orderInfo.BankOrderId
|
||||
scanData.OrderPrice = params["orderPrice"]
|
||||
response, err := req.String()
|
||||
if err != nil {
|
||||
logs.Error("KF 请求失败:", err)
|
||||
scanData.Status = "01"
|
||||
scanData.Msg = gojson.Json(response).Get("statusMsg").Tostring()
|
||||
return scanData
|
||||
}
|
||||
statusCode := gojson.Json(response).Get("statusCode").Tostring()
|
||||
if statusCode != "00" {
|
||||
logs.Error("KF生成扫码地址失败")
|
||||
scanData.Status = "01"
|
||||
scanData.Msg = "生成扫码地址失败"
|
||||
return scanData
|
||||
}
|
||||
payUrl := gojson.Json(response).Get("payURL").Tostring()
|
||||
scanData.Status = "00"
|
||||
scanData.PayUrl = payUrl
|
||||
scanData.Msg = "请求成功"
|
||||
return scanData
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) H5(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return scanData
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) Syt(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return scanData
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) Fast(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) bool {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) Web(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) bool {
|
||||
var scanData supplier.ScanData
|
||||
scanData.Status = "01"
|
||||
return true
|
||||
}
|
||||
|
||||
//支付回调
|
||||
func (c *KuaiFuImpl) PayNotify() {
|
||||
params := make(map[string]string)
|
||||
orderNo := strings.TrimSpace(c.GetString("orderNo"))
|
||||
orderInfo := order.GetOrderByBankOrderId(orderNo)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
logs.Error("快付回调的订单号不存在,订单号=", orderNo)
|
||||
c.StopRun()
|
||||
}
|
||||
roadInfo := road.GetRoadInfoByRoadUid(orderInfo.RoadUid)
|
||||
if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 {
|
||||
logs.Error("支付通道已经关系或者删除,不进行回调")
|
||||
c.StopRun()
|
||||
}
|
||||
merchantUid := orderInfo.MerchantUid
|
||||
merchantInfo := merchant.GetMerchantByUid(merchantUid)
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
logs.Error("快付回调失败,该商户不存在或者已经删除,商户uid=", merchantUid)
|
||||
c.StopRun()
|
||||
}
|
||||
paySecret := merchantInfo.MerchantSecret
|
||||
params["orderNo"] = orderNo
|
||||
params["orderPrice"] = strings.TrimSpace(c.GetString("orderPrice"))
|
||||
params["orderTime"] = strings.TrimSpace(c.GetString("orderTime"))
|
||||
params["trxNo"] = strings.TrimSpace(c.GetString("trxNo"))
|
||||
params["statusCode"] = strings.TrimSpace(c.GetString("statusCode"))
|
||||
params["tradeStatus"] = strings.TrimSpace(c.GetString("tradeStatus"))
|
||||
params["field1"] = strings.TrimSpace(c.GetString("field1"))
|
||||
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
|
||||
//对参数进行验签
|
||||
keys := utils.SortMap(params)
|
||||
tmpSign := utils.GetMD5Sign(params, keys, paySecret)
|
||||
sign := strings.TrimSpace(c.GetString("sign"))
|
||||
if tmpSign != sign {
|
||||
logs.Error("快付回调签名异常,回调失败")
|
||||
c.StopRun()
|
||||
}
|
||||
//实际支付金额
|
||||
factAmount, err := strconv.ParseFloat(params["orderPrice"], 64)
|
||||
if err != nil {
|
||||
logs.Error("快付回调实际金额有误, factAmount=", params["orderPrice"])
|
||||
c.StopRun()
|
||||
}
|
||||
orderInfo.FactAmount = factAmount
|
||||
orderInfo.BankTransId = params["trxNo"]
|
||||
tradeStatus := params["tradeStatus"]
|
||||
if tradeStatus == "FAILED" {
|
||||
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
|
||||
logs.Error("solve order fail fail")
|
||||
}
|
||||
} else if tradeStatus == "CANCELED" {
|
||||
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
|
||||
logs.Error("solve order cancel fail")
|
||||
}
|
||||
} else if tradeStatus == "WAITING_PAYMENT" {
|
||||
logs.Notice("快付回调,该订单还处于等待支付,订单id=", orderNo)
|
||||
} else if tradeStatus == "SUCCESS" {
|
||||
//订单支付成功,需要搞很多事情 TODO
|
||||
service.SolvePaySuccess(orderInfo.BankOrderId, orderInfo.FactAmount, c.GetString("trxNo"))
|
||||
}
|
||||
c.Ctx.WriteString("success")
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) PayQuery(orderInfo order.OrderInfo) bool {
|
||||
if orderInfo.Status != "wait" && orderInfo.Status != "" {
|
||||
logs.Error("订单已经被处理,不需要查询,bankOrderId:", orderInfo.BankOrderId)
|
||||
return false
|
||||
}
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = orderInfo.BankOrderId
|
||||
params["payKey"] = KF_PAY_KEY
|
||||
paySecret := KF_PAY_SECRET
|
||||
keys := utils.SortMap(params)
|
||||
params["sign"] = utils.GetMD5Sign(params, keys, paySecret)
|
||||
req := httplib.Get(KF_ORDER_QUERY)
|
||||
for k, v := range params {
|
||||
req.Param(k, v)
|
||||
}
|
||||
response, err := req.String()
|
||||
if err != nil {
|
||||
logs.Error("快付订单查询失败,bankOrderId: ", orderInfo.BankOrderId)
|
||||
logs.Error("err: ", err)
|
||||
return false
|
||||
}
|
||||
statusCode := gojson.Json(response).Get("statusCode").Tostring()
|
||||
if statusCode != "00" {
|
||||
logs.Error("快付订单查询返回失败,bankOrderId:", orderInfo.BankOrderId)
|
||||
logs.Error("err: ", response)
|
||||
return false
|
||||
}
|
||||
//获取用户的实际支付金额
|
||||
orderPrice := gojson.Json(response).Get("orderPrice").Tostring()
|
||||
factAmount, err := strconv.ParseFloat(orderPrice, 64)
|
||||
if err != nil {
|
||||
logs.Error("快速查询得到的实际金额错误, orderPrice=", orderPrice)
|
||||
}
|
||||
|
||||
//orderInfo.FactAmount = orderInfo.OrderAmount
|
||||
tradeStatus := gojson.Json(response).Get("tradeStatus").Tostring()
|
||||
trxNo := gojson.Json(response).Get("trxNo").Tostring()
|
||||
if tradeStatus == "SUCCESS" {
|
||||
//调用支付成功的接口,做加款更新操作,需要把实际支付金额传入
|
||||
if !service.SolvePaySuccess(orderInfo.BankOrderId, factAmount, trxNo) {
|
||||
return false
|
||||
}
|
||||
} else if tradeStatus == "FAILED" {
|
||||
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
logs.Info("订单状态处于:" + tradeStatus + ";bankOrderId:" + orderInfo.BankOrderId)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) PayFor(payFor payfor.PayforInfo) string {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = KF_PAY_KEY
|
||||
params["realname"] = payFor.BankAccountName
|
||||
params["cardNo"] = payFor.BankAccountNo
|
||||
params["bankCode"] = payFor.BankCode
|
||||
if payFor.BankAccountType == conf.PRIVATE {
|
||||
params["accType"] = "01"
|
||||
} else {
|
||||
params["accType"] = "02"
|
||||
}
|
||||
params["province"] = payFor.BankAccountAddress
|
||||
params["city"] = payFor.BankAccountAddress
|
||||
params["bankAccountAddress"] = payFor.BankAccountAddress
|
||||
//将float64转为字符串
|
||||
params["amount"] = strconv.FormatFloat(payFor.PayforAmount, 'f', 2, 64)
|
||||
params["moblieNo"] = payFor.PhoneNo
|
||||
params["merchantOrderId"] = payFor.BankOrderId
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, KF_PAY_SECRET)
|
||||
params["sign"] = sign
|
||||
req := httplib.Post(KF_PAYFOR_HOST)
|
||||
for k, v := range params {
|
||||
req.Param(k, v)
|
||||
}
|
||||
response, err := req.String()
|
||||
if err != nil {
|
||||
logs.Error("快付代付返回错误结果: ", response)
|
||||
} else {
|
||||
json := gojson.Json(response)
|
||||
resultCode := json.Get("resultCode").Tostring()
|
||||
resultMsg := json.Get("resultMsg").Tostring()
|
||||
if resultCode != "00" {
|
||||
logs.Error("快付代付返回错误信息:", resultMsg)
|
||||
return "fail"
|
||||
}
|
||||
settStatus := json.Get("settStatus").Tostring()
|
||||
if settStatus == "00" {
|
||||
logs.Info(fmt.Sprintf("代付uid=%s,已经成功发送给了上游处理", payFor.PayforUid))
|
||||
} else if settStatus == "01" {
|
||||
logs.Info(fmt.Sprintf("代付uid=%s,发送失败", payFor.PayforUid))
|
||||
}
|
||||
}
|
||||
return "success"
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) PayForNotify() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) PayForQuery(payFor payfor.PayforInfo) (string, string) {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = KF_PAY_KEY
|
||||
params["timestamp"] = utils.GetNowTimesTamp()
|
||||
params["merchantOrderId"] = payFor.BankOrderId
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, KF_PAY_SECRET)
|
||||
params["sign"] = sign
|
||||
req := httplib.Get(KF_PAYFOR_QUERY)
|
||||
for k, v := range params {
|
||||
req.Param(k, v)
|
||||
}
|
||||
response, err := req.String()
|
||||
if err != nil {
|
||||
logs.Error("快付代付查询失败:", err)
|
||||
return conf.PAYFOR_SOLVING, "查询失败"
|
||||
}
|
||||
|
||||
payFor.ResponseContent = response
|
||||
payFor.ResponseTime = utils.GetBasicDateTime()
|
||||
payFor.UpdateTime = utils.GetBasicDateTime()
|
||||
if !payfor.UpdatePayFor(payFor) {
|
||||
logs.Error("更新快付代付订单状态失败")
|
||||
}
|
||||
|
||||
resultCode := gojson.Json(response).Get("resultCode").Tostring()
|
||||
resultMsg := gojson.Json(response).Get("resultMsg").Tostring()
|
||||
|
||||
if resultCode != "00" {
|
||||
logs.Error("快付代付查询返回错误:", resultMsg)
|
||||
return conf.PAYFOR_SOLVING, resultMsg
|
||||
}
|
||||
|
||||
logs.Info("快付代付查询返回结果:", resultMsg)
|
||||
|
||||
merchantOrderId := gojson.Json(response).Get("merchantOrderId").Tostring()
|
||||
if merchantOrderId != payFor.BankOrderId {
|
||||
logs.Error("快付代付返回结果,订单id不一致: ", merchantOrderId)
|
||||
return conf.PAYFOR_SOLVING, "快付代付返回结果,订单id不一致"
|
||||
}
|
||||
|
||||
settStatus := gojson.Json(response).Get("settStatus").Tostring()
|
||||
|
||||
if settStatus == "00" {
|
||||
return conf.PAYFOR_SUCCESS, "代付成功"
|
||||
} else if settStatus == "01" {
|
||||
return conf.PAYFOR_FAIL, "代付失败"
|
||||
} else {
|
||||
return conf.PAYFOR_BANKING, "银行处理中"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *KuaiFuImpl) BalanceQuery(roadInfo road.RoadInfo) float64 {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = KF_PAY_KEY
|
||||
params["timestamp"] = utils.GetNowTimesTamp()
|
||||
params["merchantOrderId"] = xid.New().String()
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, KF_PAY_SECRET)
|
||||
params["sign"] = sign
|
||||
req := httplib.Get(KF_BALANCE_QUERY)
|
||||
for k, v := range params {
|
||||
req.Param(k, v)
|
||||
}
|
||||
|
||||
response, err := req.String()
|
||||
if err != nil {
|
||||
logs.Error("快付余额查询失败,err: ", err)
|
||||
return 0.00
|
||||
}
|
||||
logs.Debug("快付余额查询返回:", response)
|
||||
|
||||
resultCode := gojson.Json(response).Get("resultCode").Tostring()
|
||||
resultMsg := gojson.Json(response).Get("resultMsg").Tostring()
|
||||
logs.Notice("快付返回信息:", resultMsg)
|
||||
|
||||
if resultCode != "00" {
|
||||
return 0.00
|
||||
}
|
||||
|
||||
balance := gojson.Json(response).Get("balance").Tostring()
|
||||
availableAmount := gojson.Json(response).Get("availableAmount").Tostring()
|
||||
|
||||
logs.Info(fmt.Sprintf("快付余额=%s,可用金额=%s", balance, availableAmount))
|
||||
|
||||
f, err := strconv.ParseFloat(availableAmount, 64)
|
||||
return f
|
||||
}
|
43
gateway/tests/pay_for_test.go
Normal file
43
gateway/tests/pay_for_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"gateway/conf"
|
||||
_ "gateway/message"
|
||||
_ "gateway/models"
|
||||
"gateway/models/payfor"
|
||||
"gateway/pay_for"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/rs/xid"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAutoPayFor(t *testing.T) {
|
||||
params := make(map[string]string)
|
||||
|
||||
params["merchantKey"] = "kkkkc254gk8isf001cqrj6p0"
|
||||
params["realname"] = "孔跃彬"
|
||||
params["cardNo"] = "6214830200383973"
|
||||
params["accType"] = "0"
|
||||
params["amount"] = "100"
|
||||
paySecret := "ssssc254gk8isf001cqrj6pg"
|
||||
params["merchantOrderId"] = xid.New().String()
|
||||
keys := utils.SortMap(params)
|
||||
params["sign"] = utils.GetMD5Sign(params, keys, paySecret)
|
||||
payFor := pay_for.AutoPayFor(params, conf.SELF_API)
|
||||
logs.Info(payFor)
|
||||
}
|
||||
|
||||
func TestPayForFail(t *testing.T) {
|
||||
p := new(payfor.PayforInfo)
|
||||
p.BankOrderId = "4444c4vlk3u7mathho2o8md0"
|
||||
res := pay_for.PayForFail(*p)
|
||||
logs.Info(res)
|
||||
}
|
||||
|
||||
func TestPayForSuccess(t *testing.T) {
|
||||
p := new(payfor.PayforInfo)
|
||||
p.BankOrderId = "4444c4vlk3u7mathho2o8md0"
|
||||
res := pay_for.PayForSuccess(*p)
|
||||
logs.Info(res)
|
||||
}
|
63
gateway/tests/pay_test.go
Normal file
63
gateway/tests/pay_test.go
Normal file
@ -0,0 +1,63 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
_ "gateway/message"
|
||||
_ "gateway/models"
|
||||
"gateway/service"
|
||||
"gateway/utils"
|
||||
"github.com/astaxie/beego/httplib"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/rs/xid"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
import _ "gateway/routers"
|
||||
|
||||
/*
|
||||
** 充值测试
|
||||
*/
|
||||
func TestPay(t *testing.T) {
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = xid.New().String()
|
||||
params["productName"] = "kongyuhebin"
|
||||
params["orderPeriod"] = "1"
|
||||
params["orderPrice"] = "100.00"
|
||||
params["payWayCode"] = "WEIXIN_SCAN"
|
||||
params["osType"] = "1"
|
||||
params["notifyUrl"] = "http://localhost:12309/shop/notify"
|
||||
params["payKey"] = "kkkkc254gk8isf001cqrj6p0"
|
||||
keys := utils.SortMap(params)
|
||||
params["sign"] = utils.GetMD5Sign(params, keys, "ssssc254gk8isf001cqrj6pg")
|
||||
|
||||
u := url.Values{}
|
||||
for k, v := range params {
|
||||
u.Add(k, v)
|
||||
}
|
||||
|
||||
l := "http://localhost:12309/gateway/scan?" + u.Encode()
|
||||
logs.Info("请求url:" + l)
|
||||
|
||||
resp := httplib.Get(l)
|
||||
s, err := resp.String()
|
||||
|
||||
if err != nil {
|
||||
logs.Error("请求错误:" + err.Error())
|
||||
|
||||
}
|
||||
|
||||
logs.Info("微信扫码返回结果:" + s)
|
||||
}
|
||||
|
||||
/**
|
||||
** 充值失败回调
|
||||
*/
|
||||
func TestPayFail(t *testing.T) {
|
||||
service.SolvePayFail("6666c50bd567matj5v6g30dg", "")
|
||||
}
|
||||
|
||||
/**
|
||||
** 充值成功
|
||||
*/
|
||||
func TestPaySuccess(t *testing.T) {
|
||||
service.SolvePaySuccess("6666c50mhcu7matjtv0a4330", 0, "")
|
||||
}
|
47
gateway/utils/bank.go
Normal file
47
gateway/utils/bank.go
Normal file
File diff suppressed because one or more lines are too long
@ -38,3 +38,7 @@ func GetDateBeforeDays(days int) string {
|
||||
func GetDateTimeBeforeDays(days int) string {
|
||||
return time.Now().Add(-time.Hour * time.Duration(days) * 24).Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func GetDateAfterDays(days int) string {
|
||||
return time.Now().Add(time.Hour * time.Duration(days) * 24).Format("2006-01-02")
|
||||
}
|
||||
|
@ -30,3 +30,18 @@ func GetMD5LOWER(s string) string {
|
||||
func GetMD5Upper(s string) string {
|
||||
return strings.ToUpper(GetMD5LOWER(s))
|
||||
}
|
||||
|
||||
/**
|
||||
** 将map数据变成key=value形式的字符串
|
||||
*/
|
||||
func MapToString(m map[string]string) string {
|
||||
|
||||
res := ""
|
||||
for k, v := range m {
|
||||
res = res + k + "=" + v + "&"
|
||||
}
|
||||
|
||||
suffix := strings.TrimSuffix(res, "&")
|
||||
|
||||
return suffix
|
||||
}
|
||||
|
@ -24,3 +24,16 @@ func SortMap(m map[string]string) []string {
|
||||
sort.Strings(arr)
|
||||
return arr
|
||||
}
|
||||
|
||||
/**
|
||||
** 按照key的ascii值从小到大给map排序
|
||||
*/
|
||||
func SortMapByKeys(m map[string]string) map[string]string {
|
||||
keys := SortMap(m)
|
||||
tmp := make(map[string]string)
|
||||
for _, key := range keys {
|
||||
tmp[key] = m[key]
|
||||
}
|
||||
|
||||
return tmp
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user