diff --git a/gateway/common/consts.go b/gateway/common/consts.go deleted file mode 100644 index 21f4191..0000000 --- a/gateway/common/consts.go +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************** - ** @Desc : This file for ... - ** @Time : 2019/11/25 14:14 - ** @Author : yuebin - ** @File : consts.go - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/11/25 14:14 - ** @Software: GoLand -****************************************************/ -package common - -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" //对私卡 -) diff --git a/gateway/common/mq_config.go b/gateway/common/mq_config.go deleted file mode 100644 index 472bdcd..0000000 --- a/gateway/common/mq_config.go +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************** - ** @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 common - -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) -} diff --git a/gateway/common/pay_way_code.go b/gateway/common/pay_way_code.go deleted file mode 100644 index a848388..0000000 --- a/gateway/common/pay_way_code.go +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************** - ** @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 common - -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 "未知" - } -} diff --git a/gateway/enum/bank_info.go b/gateway/enum/bank_info.go deleted file mode 100644 index da972de..0000000 --- a/gateway/enum/bank_info.go +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************** - ** @Desc : This file for 银行编码 - ** @Time : 19.12.4 10:42 - ** @Author : Joker - ** @File : bank_info - ** @Last Modified by : Joker - ** @Last Modified time: 19.12.4 10:42 - ** @Software: GoLand -****************************************************/ -package enum - -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: "深圳发展银行", -} - -func GetBankInfo() map[string]string { - return bankInfo -} diff --git a/gateway/enum/conf.go b/gateway/enum/conf.go deleted file mode 100644 index 1bcbb42..0000000 --- a/gateway/enum/conf.go +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************** - ** @Desc : This file for 配置常量 - ** @Time : 2019.04.01 11:45 - ** @Author : Joker - ** @File : strings - ** @Last Modified by : Joker - ** @Last Modified time: 2019-11-29 11:05:48 - ** @Software: GoLand -****************************************************/ -package enum - -// 对接云片 -// 短信配置 -const ( - ApiKey = "fd264ab6c43c02c52s40eab1ba" - TPL1 = 332236 - SendSmsUrl = "https://sms.yunpian.com/v2/sms/tpl_single_send.json" -) - -// session 配置 -const ( - SessionPath = "./sys/temp" // 保存路径 - SessionExpireTime = 9600 // 有效时间,秒 - CookieExpireTime = 1800 // 有效时间,秒 - SmsCookieExpireTime = 60 // 有效时间,秒 - LocalSessionName = "JOKERSession" // 客户端session名称 -) - -// 提现限制金额 -const ( - WithdrawalMaxAmount = 45000 - WithdrawalMinAmount = 2 - SettlementFee = 2 // 提现单笔手续费 -) diff --git a/gateway/enum/constant.go b/gateway/enum/constant.go deleted file mode 100644 index d378194..0000000 --- a/gateway/enum/constant.go +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************** - ** @Desc : This file for 系统常量 - ** @Time : 19.11.30 11:28 - ** @Author : Joker - ** @File : constant - ** @Last Modified by : Joker - ** @Last Modified time: 19.11.30 11:28 - ** @Software: GoLand -****************************************************/ -package enum - -const ( - UserSession = "agent_user" - UserCookie = "agent_user_cookie_md5" - - DoMainUrl = "/index/ui/" - - PublicAccount = "1" // 对公帐户 - PrivateDebitAccount = "0" // 对私借记卡 - SettleSingle = "SELFHELP_SETTLE" // 单笔代付 - - ExcelModelName = "batch_daifa_template.xlsx" - ExcelModelPath = "static/excel/batch_daifa_template.xlsx" - ExcelPath = "static/excel/temp/" - ExcelDownloadPath = "static/excel/download/" -) diff --git a/gateway/enum/pay_type.go b/gateway/enum/pay_type.go deleted file mode 100644 index 48ecde6..0000000 --- a/gateway/enum/pay_type.go +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************** - ** @Desc : This file for 支付方式 - ** @Time : 19.12.3 15:24 - ** @Author : Joker - ** @File : pay_type - ** @Last Modified by : Joker - ** @Last Modified time: 19.12.3 15:24 - ** @Software: GoLand -****************************************************/ -package enum - -const ( - WEIXIN_SCAN = "WEIXIN_SCAN" - WEIXIN_H5 = "WEIXIN_H5" - WEIXIN_SYT = "WEIXIN_SYT" - ALI_SCAN = "ALI_SCAN" - ALI_H5 = "ALI_H5" - ALI_SYT = "ALI_SYT" - QQ_SCAN = "QQ_SCAN" - QQ_H5 = "QQ_H5" - QQ_SYT = "QQ_SYT" - UNION_SCAN = "UNION_SCAN" - UNION_H5 = "UNION_H5" - UNION_PC_WAP = "UNION_PC_WAP" - UNION_SYT = "UNION_SYT" - UNION_FAST = "UNION_FAST" - BAIDU_SCAN = "BAIDU_SCAN" - BAIDU_H5 = "BAIDU_H5" - BAIDU_SYT = "BAIDU_SYT" - JD_SCAN = "JD_SCAN" - JD_H5 = "JD_H5" - JD_SYT = "JD_SYT" -) - -var payType = map[string]string{ - WEIXIN_SCAN: "微信扫码", - WEIXIN_H5: "微信H5", - WEIXIN_SYT: "微信收银台", - ALI_SCAN: "支付宝扫码", - ALI_H5: "支付宝H5", - ALI_SYT: "支付宝收银台", - QQ_SCAN: "QQ扫码", - QQ_H5: "QQ-H5", - QQ_SYT: "QQ收银台", - UNION_SCAN: "银联扫码", - UNION_H5: "银联H5", - UNION_PC_WAP: "银联pc-web", - UNION_SYT: "银联收银台", - UNION_FAST: "银联快捷", - BAIDU_SCAN: "百度钱包扫码", - BAIDU_H5: "百度钱包H5", - BAIDU_SYT: "百度钱包收银台", - JD_SCAN: "京东扫码", - JD_H5: "京东H5", - JD_SYT: "京东收银台", -} - -func GetPayType() map[string]string { - return payType -} diff --git a/gateway/enum/regular_expression.go b/gateway/enum/regular_expression.go deleted file mode 100644 index aa445b7..0000000 --- a/gateway/enum/regular_expression.go +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************** - ** @Desc : This file for 正则表达式 - ** @Time : 19.12.5 10:25 - ** @Author : Joker - ** @File : regular_expression - ** @Last Modified by : Joker - ** @Last Modified time: 19.12.5 10:25 - ** @Software: GoLand -****************************************************/ -package enum - -const ( - PasswordReg = `^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){5,19}$` - MoneyReg = `^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$` - MobileReg = `^[1]([3-9])[0-9]{9}$` -) diff --git a/gateway/enum/status.go b/gateway/enum/status.go deleted file mode 100644 index 77bb5a3..0000000 --- a/gateway/enum/status.go +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************** - ** @Desc : This file for 状态常量 - ** @Time : 19.11.30 11:12 - ** @Author : Joker - ** @File : status - ** @Last Modified by : Joker - ** @Last Modified time: 19.11.30 11:12 - ** @Software: GoLand -****************************************************/ -package enum - -// 成功与否 -const ( - FailedFlag = -9 - FailedString = "操作失败! " - FailedToAdmin = "系统内部错误,请联系管理员!" - SuccessFlag = 9 - SuccessString = "操作成功! " -) - -// 用户状态 -const ( - ACTIVE = "active" - FREEZE = "FREEZE" - UNACTIVE = "unactive" -) - -var userStatus = map[string]string{ - ACTIVE: "激活", - FREEZE: "冻结", - UNACTIVE: "冻结", -} - -// 用户状态 -func GetUserStatus() map[string]string { - return userStatus -} - -// 充值订单状态 -const ( - SUCCESS = "success" - FAILED = "failed" - WAITING_PAYMENT = "wait" -) - -var orderStatus = map[string]string{ - SUCCESS: "交易成功", - FAILED: "交易失败", - WAITING_PAYMENT: "等待支付", -} - -// 充值订单状态 -func GetOrderStatus() map[string]string { - return orderStatus -} - -// 投诉订单状态 -const ( - YES = "yes" - NO = "no" -) - -var orderComStatus = map[string]string{ - YES: "冻结", - NO: "未冻结", -} - -// 投诉订单状态 -func GetComOrderStatus() map[string]string { - return orderComStatus -} - -// 结算订单状态 -const ( - WAIT_CONFIRM = "payfor_confirm" - REMITTING = "payfor_solving" - REMIT_FAIL = "failed" - BANK_DEALING = "payfor_banking" - REMIT_SUCCESS = "success" -) - -var settlementStatus = map[string]string{ - WAIT_CONFIRM: "等待审核", - REMITTING: "打款中", - REMIT_FAIL: "打款失败", - BANK_DEALING: "银行处理中", - REMIT_SUCCESS: "打款成功", -} - -// 结算订单状态 -func GetSettlementStatus() map[string]string { - return settlementStatus -} - -// 充值订单状态 -const ( - RECHARGE = "recharge" - REFUND = "refund" - FREEZER = "freeze" - UNFREEZE = "unfreeze" -) - -var rechargeStatus = map[string]string{ - RECHARGE: "充值", - REFUND: "退款", - FREEZER: "冻结", - UNFREEZE: "解冻", -} - -// 充值订单状态 -func GetRechargeStatus() map[string]string { - return rechargeStatus -} - -// 历史记录状态 -const ( - PLUS_AMOUNT = "plus_amount" - SUB_AMOUNT = "sub_amount" - FREEZE_AMOUNT = "freeze_amount" - UNFREEZE_AMOUNT = "unfreeze_amount" -) - -var historyStatus = map[string]string{ - PLUS_AMOUNT: "加款", - SUB_AMOUNT: "减款", - FREEZE_AMOUNT: "冻结", - UNFREEZE_AMOUNT: "解冻", -} - -// 历史记录状态 -func GetHistoryStatus() map[string]string { - return historyStatus -} diff --git a/gateway/go.sum b/gateway/go.sum index e684658..238111d 100644 --- a/gateway/go.sum +++ b/gateway/go.sum @@ -2,8 +2,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= @@ -94,6 +96,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -157,6 +160,7 @@ github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBf github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s= github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -268,6 +272,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/gateway/main.go b/gateway/main.go index 9440374..3f68f15 100644 --- a/gateway/main.go +++ b/gateway/main.go @@ -1,13 +1,50 @@ package main import ( + _ "gateway/message" _ "gateway/models" - _ "gateway/supplier" - beego "github.com/beego/beego/v2/server/web" + "gateway/notify" + "gateway/query" + _ "gateway/routers" + "gateway/service" + _ "gateway/supplier/third_party" + "github.com/beego/beego/v2/core/logs" + "github.com/beego/beego/v2/server/web" ) func main() { - //启动订单查询消费者 - beego.BConfig.WebConfig.Session.SessionOn = true - beego.Run() + RegisterLogs() + web.BConfig.WebConfig.Session.SessionOn = true + + go notify.CreateOrderNotifyConsumer() + //go pay_for.PayForInit() + go query.CreatePayForQueryConsumer() + go service.OrderSettleInit() + go query.CreateSupplierOrderQueryCuConsumer() + + web.Run() +} + +/** +** 注册日志信息 + */ +func RegisterLogs() { + logs.SetLogger(logs.AdapterFile, + `{ + "filename":"../logs/legend.log", + "level":4, + "maxlines":0, + "maxsize":0, + "daily":true, + "maxdays":10, + "color":true + }`) + + f := &logs.PatternLogFormatter{ + Pattern: "%F:%n|%w%t>> %m", + WhenFormat: "2006-01-02", + } + + logs.RegisterFormatter("pattern", f) + _ = logs.SetGlobalFormatter("pattern") } diff --git a/gateway/message_queue/active_mq.go b/gateway/message_queue/active_mq.go deleted file mode 100644 index eb656c2..0000000 --- a/gateway/message_queue/active_mq.go +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************** - ** @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_queue - -import ( - "gateway/common" - "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 := common.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 -} diff --git a/gateway/message_queue/send_message.go b/gateway/message_queue/send_message.go deleted file mode 100644 index 0ad0024..0000000 --- a/gateway/message_queue/send_message.go +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************** - ** @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_queue - -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) - } -} diff --git a/gateway/models/account.go b/gateway/models/account.go deleted file mode 100644 index 770c85c..0000000 --- a/gateway/models/account.go +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/account_history_info.go b/gateway/models/account_history_info.go deleted file mode 100644 index abb630f..0000000 --- a/gateway/models/account_history_info.go +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/agent_info.go b/gateway/models/agent_info.go deleted file mode 100644 index 2c43f1e..0000000 --- a/gateway/models/agent_info.go +++ /dev/null @@ -1,162 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/agent_profit.go b/gateway/models/agent_profit.go deleted file mode 100644 index 1897b85..0000000 --- a/gateway/models/agent_profit.go +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************** - ** @Desc : This file for ... - ** @Time : 2019/12/17 17:50 - ** @Author : yuebin - ** @File : agent_profit - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/12/17 17:50 - ** @Software: GoLand -****************************************************/ -package models - -type AgentProfit struct { -} diff --git a/gateway/models/bank_card_info.go b/gateway/models/bank_card_info.go deleted file mode 100644 index ff881ea..0000000 --- a/gateway/models/bank_card_info.go +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/menu_info.go b/gateway/models/menu_info.go deleted file mode 100644 index e974db5..0000000 --- a/gateway/models/menu_info.go +++ /dev/null @@ -1,179 +0,0 @@ -/*************************************************** - ** @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 models - -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) -} diff --git a/gateway/models/merchant_deploy_info.go b/gateway/models/merchant_deploy_info.go deleted file mode 100644 index e8fa6da..0000000 --- a/gateway/models/merchant_deploy_info.go +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/merchant_info.go b/gateway/models/merchant_info.go deleted file mode 100644 index 2877ace..0000000 --- a/gateway/models/merchant_info.go +++ /dev/null @@ -1,205 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/merchant_load_info.go b/gateway/models/merchant_load_info.go deleted file mode 100644 index 8277c6f..0000000 --- a/gateway/models/merchant_load_info.go +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************** - ** @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 models - -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() -} diff --git a/gateway/models/notify_info.go b/gateway/models/notify_info.go deleted file mode 100644 index d2bab17..0000000 --- a/gateway/models/notify_info.go +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************** - ** @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 models - -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 GetNotifyBankOrderIdListByParams(params map[string]string) []string { - o := orm.NewOrm() - qs := o.QueryTable(NOTIFYINFO) - for k, v := range params { - if len(v) > 0 { - qs = qs.Filter(k, v) - } - } - - var notifyList []NotifyInfo - qs.Limit(-1).All(¬ifyList) - var list []string - for _, n := range notifyList { - list = append(list, n.BankOrderId) - } - - return list -} - -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 -} diff --git a/gateway/models/order_info.go b/gateway/models/order_info.go deleted file mode 100644 index 1a82ce0..0000000 --- a/gateway/models/order_info.go +++ /dev/null @@ -1,222 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/order_profit_info.go b/gateway/models/order_profit_info.go deleted file mode 100644 index 94e8559..0000000 --- a/gateway/models/order_profit_info.go +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************** - ** @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 models - -import ( - "github.com/beego/beego/v2/client/orm" - "github.com/beego/beego/v2/core/logs" - "strings" -) - -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) []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 []PlatformProfit - _, err := o.Raw(cond).QueryRows(&platformProfitList) - if err != nil { - logs.Error("get platform profit by map fail:", err) - } - - return platformProfitList -} diff --git a/gateway/models/order_settle_info.go b/gateway/models/order_settle_info.go deleted file mode 100644 index 966477d..0000000 --- a/gateway/models/order_settle_info.go +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/payfor_info.go b/gateway/models/payfor_info.go deleted file mode 100644 index 3665902..0000000 --- a/gateway/models/payfor_info.go +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************** - ** @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 models - -import ( - "context" - "errors" - "fmt" - "gateway/common" - "gateway/utils" - "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 - ResponseContext 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 GetPayForLenByMap(params map[string]string) int { - o := orm.NewOrm() - qs := o.QueryTable(PAYFORINFO) - 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 pay for len by map fail: ", err) - } - - return int(cnt) -} - -func GetPayForByMap(params map[string]string, displayCount, offset int) []PayforInfo { - o := orm.NewOrm() - var payForList []PayforInfo - - qs := o.QueryTable(PAYFORINFO) - for k, v := range params { - if len(v) > 0 { - qs = qs.Filter(k, v) - } - } - - _, err := qs.Limit(displayCount, offset).OrderBy("-create_time").All(&payForList) - - if err != nil { - logs.Error("get agentInfo by map fail: ", err) - } - - return payForList -} - -func GetPayForListByParams(params map[string]string) []PayforInfo { - o := orm.NewOrm() - var payForList []PayforInfo - qs := o.QueryTable(PAYFORINFO) - for k, v := range params { - if len(v) > 0 { - qs = qs.Filter(k, v) - } - } - _, err := qs.Limit(-1).All(&payForList) - if err != nil { - logs.Error("GetPayForListByParams fail:", err) - } - return payForList -} - -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 ForUpdatePayFor(payFor PayforInfo) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - var tmp PayforInfo - if err := txOrm.Raw("select * from payfor_info where bank_order_id = ? for update", payFor.BankOrderId).QueryRow(&tmp); err != nil || tmp.PayforUid == "" { - logs.Error("for update payfor select fail:", err) - return err - } - - if tmp.Status == common.PAYFOR_FAIL || tmp.Status == common.PAYFOR_SUCCESS { - return errors.New("订单已经处理") - } - - //如果是手动打款,并且是需要处理商户金额 - if payFor.Status == common.PAYFOR_SOLVING && tmp.Status == common.PAYFOR_COMFRIM && - payFor.GiveType == common.PAYFOR_HAND && payFor.Type != common.SELF_HELP { - - var account AccountInfo - if err := txOrm.Raw("select * from account_info where account_uid = ? for update", payFor.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" { - logs.Error("for update payfor select account info,fail:", err) - return err - } - //计算该用户的可用金额 - ableAmount := account.SettleAmount - account.FreezeAmount - account.PayforAmount - account.LoanAmount - if ableAmount >= payFor.PayforAmount+payFor.PayforFee { - account.PayforAmount += payFor.PayforFee + payFor.PayforAmount - account.UpdateTime = utils.GetBasicDateTime() - if _, err := txOrm.Update(&account); err != nil { - logs.Error("for update payfor update account fail:", err) - return err - } - } else { - logs.Error(fmt.Sprintf("商户uid=%s,可用金额不够", payFor.MerchantUid)) - payFor.ResponseContext = "商户可用余额不足" - payFor.Status = common.PAYFOR_FAIL - } - } - - if _, err := txOrm.Update(&payFor); err != nil { - logs.Error("for update payfor fail: ", err) - return err - } - - return nil - }); err != nil { - return false - } - return true -} - -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 -} diff --git a/gateway/models/platform_profit.go b/gateway/models/platform_profit.go deleted file mode 100644 index d408819..0000000 --- a/gateway/models/platform_profit.go +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************** - ** @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 models - -type PlatformProfit struct { - MerchantName string - AgentName string - SupplierName string - PayTypeName string - OrderAmount float64 - OrderCount int - PlatformProfit float64 - AgentProfit float64 -} diff --git a/gateway/models/power_info.go b/gateway/models/power_info.go deleted file mode 100644 index 893a686..0000000 --- a/gateway/models/power_info.go +++ /dev/null @@ -1,143 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/road_info.go b/gateway/models/road_info.go deleted file mode 100644 index 10c6c6c..0000000 --- a/gateway/models/road_info.go +++ /dev/null @@ -1,162 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/road_pool_info.go b/gateway/models/road_pool_info.go deleted file mode 100644 index 0fdced9..0000000 --- a/gateway/models/road_pool_info.go +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/role_info.go b/gateway/models/role_info.go deleted file mode 100644 index 49c7c51..0000000 --- a/gateway/models/role_info.go +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/second_menu_info.go b/gateway/models/second_menu_info.go deleted file mode 100644 index e1b3f87..0000000 --- a/gateway/models/second_menu_info.go +++ /dev/null @@ -1,216 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/models/transaction.go b/gateway/models/transaction.go deleted file mode 100644 index a283397..0000000 --- a/gateway/models/transaction.go +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************** - ** @Desc : This file for ... - ** @Time : 2019/10/19 14:17 - ** @Author : yuebin - ** @File : transaction - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/10/19 14:17 - ** @Software: GoLand -****************************************************/ -package models - -import ( -) - -/*func OperatorAccount(accountUid, operatorType string, amount float64) (string, bool) { - o := orm.NewOrm() - o.Begin() - - defer func(interface{}) { - if r := recover(); r != nil { - o.Rollback() - logs.Error("operator account fail") - } - }(o) - - msg := "" - //处理事务 - accountInfo := new(AccountInfo) - if err := o.Raw("select * from account_info where account_uid = ? for update", accountUid).QueryRow(accountInfo); err != nil || accountInfo.AccountUid == "" { - logs.Error("operator account get account info for update fail: ", err) - o.Rollback() - return msg, false - } - - accountInfo.UpdateTime = utils.GetBasicDateTime() - flag := true - - switch operatorType { - case common.PLUS_AMOUNT: //处理加款操作 - accountInfo.Balance = accountInfo.Balance + amount - accountInfo.SettleAmount = accountInfo.SettleAmount + amount - case common.SUB_AMOUNT: //处理减款 - if accountInfo.Balance >= amount && accountInfo.SettleAmount >= amount { - accountInfo.Balance = accountInfo.Balance - amount - accountInfo.SettleAmount = accountInfo.SettleAmount - amount - } else { - msg = "账户余额不够减" - flag = false - } - case common.FREEZE_AMOUNT: //处理冻结款 - accountInfo.FreezeAmount = accountInfo.FreezeAmount + amount - case common.UNFREEZE_AMOUNT: //处理解冻款 - if accountInfo.FreezeAmount >= amount { - accountInfo.FreezeAmount = accountInfo.FreezeAmount - amount - } else { - msg = "账户冻结金额不够解冻款" - flag = false - } - } - if !flag { - o.Rollback() - return msg, false - } - - if _, err := o.Update(accountInfo); err != nil { - logs.Error("operator account update account fail: ", err) - o.Rollback() - return msg, false - } - //往account_history表中插入一条动账记录 - accountHistory := AccountHistoryInfo{AccountUid: accountUid, AccountName: accountInfo.AccountName, Type: operatorType, - Amount: amount, Balance: accountInfo.Balance, CreateTime: utils.GetBasicDateTime(), UpdateTime: utils.GetBasicDateTime()} - - if _, err := o.Insert(&accountHistory); err != nil { - logs.Error("operator account insert account history fail: ", err) - o.Rollback() - return msg, false - } - if err := o.Commit(); err != nil { - logs.Error("operator account commit fail: ", err) - return msg, false - } else { - logs.Info("操作账户成功") - return "", true - } -} -*/ \ No newline at end of file diff --git a/gateway/models/user_info.go b/gateway/models/user_info.go deleted file mode 100644 index bf5235c..0000000 --- a/gateway/models/user_info.go +++ /dev/null @@ -1,146 +0,0 @@ -/*************************************************** - ** @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 models - -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 -} diff --git a/gateway/routers/router.go b/gateway/routers/router.go index 0c739c5..c793e4c 100644 --- a/gateway/routers/router.go +++ b/gateway/routers/router.go @@ -2,15 +2,18 @@ package routers import ( "gateway/controllers/gateway" - beego "github.com/beego/beego/v2/server/web" + "gateway/supplier/third_party" + "github.com/beego/beego/v2/server/web" ) func init() { //网关处理函数 - beego.Router("/gateway/scan", &gateway.ScanController{}, "*:Scan") - beego.Router("/err/params", &gateway.ErrorGatewayController{}, "*:ErrorParams") + web.Router("/gateway/scan", &gateway.ScanController{}, "*:Scan") + web.Router("/err/params", &gateway.ErrorGatewayController{}, "*:ErrorParams") //代付相关的接口 - beego.Router("gateway/payfor", &gateway.PayForGateway{}, "*:PayFor") - beego.Router("/gateway/payfor/query", &gateway.PayForGateway{}, "*:PayForQuery") - beego.Router("/gateway/balance", &gateway.PayForGateway{}, "*:Balance") + web.Router("gateway/payfor", &gateway.PayForGateway{}, "*:PayFor") + web.Router("/gateway/payfor/query", &gateway.PayForGateway{}, "*:PayForQuery") + web.Router("/gateway/balance", &gateway.PayForGateway{}, "*:Balance") + // 接收银行回调 + web.Router("/daili/notify", &third_party.DaiLiImpl{}, "*:PayNotify") } diff --git a/gateway/static/lib/bootstrap/css/bootstrap-theme.css.map b/gateway/static/lib/bootstrap/css/bootstrap-theme.css.map index d876f60..5823371 100644 --- a/gateway/static/lib/bootstrap/css/bootstrap-theme.css.map +++ b/gateway/static/lib/bootstrap/css/bootstrap-theme.css.map @@ -1 +1 @@ -{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAAA;;;;GAIG;ACeH;;;;;;EAME,yCAAA;EC2CA,4FAAA;EACQ,oFAAA;CFvDT;ACgBC;;;;;;;;;;;;ECsCA,yDAAA;EACQ,iDAAA;CFxCT;ACMC;;;;;;;;;;;;;;;;;;ECiCA,yBAAA;EACQ,iBAAA;CFnBT;AC/BD;;;;;;EAuBI,kBAAA;CDgBH;ACyBC;;EAEE,uBAAA;CDvBH;AC4BD;EErEI,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;EAuC2C,0BAAA;EAA2B,mBAAA;CDjBvE;ACpBC;;EAEE,0BAAA;EACA,6BAAA;CDsBH;ACnBC;;EAEE,0BAAA;EACA,sBAAA;CDqBH;ACfG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6BL;ACbD;EEtEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8DD;AC5DC;;EAEE,0BAAA;EACA,6BAAA;CD8DH;AC3DC;;EAEE,0BAAA;EACA,sBAAA;CD6DH;ACvDG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqEL;ACpDD;EEvEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsGD;ACpGC;;EAEE,0BAAA;EACA,6BAAA;CDsGH;ACnGC;;EAEE,0BAAA;EACA,sBAAA;CDqGH;AC/FG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6GL;AC3FD;EExEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ID;AC5IC;;EAEE,0BAAA;EACA,6BAAA;CD8IH;AC3IC;;EAEE,0BAAA;EACA,sBAAA;CD6IH;ACvIG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqJL;AClID;EEzEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsLD;ACpLC;;EAEE,0BAAA;EACA,6BAAA;CDsLH;ACnLC;;EAEE,0BAAA;EACA,sBAAA;CDqLH;AC/KG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6LL;ACzKD;EE1EI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ND;AC5NC;;EAEE,0BAAA;EACA,6BAAA;CD8NH;AC3NC;;EAEE,0BAAA;EACA,sBAAA;CD6NH;ACvNG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqOL;AC1MD;;EClCE,mDAAA;EACQ,2CAAA;CFgPT;ACrMD;;EE3FI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF0FF,0BAAA;CD2MD;ACzMD;;;EEhGI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFgGF,0BAAA;CD+MD;ACtMD;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EH+HA,mBAAA;ECjEA,4FAAA;EACQ,oFAAA;CF8QT;ACjND;;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,yDAAA;EACQ,iDAAA;CFwRT;AC9MD;;EAEE,+CAAA;CDgND;AC5MD;EEhII,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EHkJA,mBAAA;CDkND;ACrND;;EEhII,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,wDAAA;EACQ,gDAAA;CF+ST;AC/ND;;EAYI,0CAAA;CDuNH;AClND;;;EAGE,iBAAA;CDoND;AC/LD;EAfI;;;IAGE,YAAA;IE7JF,yEAAA;IACA,oEAAA;IACA,8FAAA;IAAA,uEAAA;IACA,4BAAA;IACA,uHAAA;GH+WD;CACF;AC3MD;EACE,8CAAA;EC3HA,2FAAA;EACQ,mFAAA;CFyUT;ACnMD;EEtLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+MD;AC1MD;EEvLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuND;ACjND;EExLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+ND;ACxND;EEzLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuOD;ACxND;EEjMI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH4ZH;ACrND;EE3MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHmaH;AC3ND;EE5MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH0aH;ACjOD;EE7MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHibH;ACvOD;EE9MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHwbH;AC7OD;EE/MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH+bH;AChPD;EElLI,8MAAA;EACA,yMAAA;EACA,sMAAA;CHqaH;AC5OD;EACE,mBAAA;EC9KA,mDAAA;EACQ,2CAAA;CF6ZT;AC7OD;;;EAGE,8BAAA;EEnOE,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFiOF,sBAAA;CDmPD;ACxPD;;;EAQI,kBAAA;CDqPH;AC3OD;ECnME,kDAAA;EACQ,0CAAA;CFibT;ACrOD;EE5PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHoeH;AC3OD;EE7PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH2eH;ACjPD;EE9PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHkfH;ACvPD;EE/PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHyfH;AC7PD;EEhQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHggBH;ACnQD;EEjQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHugBH;ACnQD;EExQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFsQF,sBAAA;EC3NA,0FAAA;EACQ,kFAAA;CFqeT","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file +{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAAA;;;;GAIG;ACeH;;;;;;EAME,yCAAA;EC2CA,4FAAA;EACQ,oFAAA;CFvDT;ACgBC;;;;;;;;;;;;ECsCA,yDAAA;EACQ,iDAAA;CFxCT;ACMC;;;;;;;;;;;;;;;;;;ECiCA,yBAAA;EACQ,iBAAA;CFnBT;AC/BD;;;;;;EAuBI,kBAAA;CDgBH;ACyBC;;EAEE,uBAAA;CDvBH;AC4BD;EErEI,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;EAuC2C,0BAAA;EAA2B,mBAAA;CDjBvE;ACpBC;;EAEE,0BAAA;EACA,6BAAA;CDsBH;ACnBC;;EAEE,0BAAA;EACA,sBAAA;CDqBH;ACfG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6BL;ACbD;EEtEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8DD;AC5DC;;EAEE,0BAAA;EACA,6BAAA;CD8DH;AC3DC;;EAEE,0BAAA;EACA,sBAAA;CD6DH;ACvDG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqEL;ACpDD;EEvEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsGD;ACpGC;;EAEE,0BAAA;EACA,6BAAA;CDsGH;ACnGC;;EAEE,0BAAA;EACA,sBAAA;CDqGH;AC/FG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6GL;AC3FD;EExEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ID;AC5IC;;EAEE,0BAAA;EACA,6BAAA;CD8IH;AC3IC;;EAEE,0BAAA;EACA,sBAAA;CD6IH;ACvIG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqJL;AClID;EEzEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsLD;ACpLC;;EAEE,0BAAA;EACA,6BAAA;CDsLH;ACnLC;;EAEE,0BAAA;EACA,sBAAA;CDqLH;AC/KG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6LL;ACzKD;EE1EI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ND;AC5NC;;EAEE,0BAAA;EACA,6BAAA;CD8NH;AC3NC;;EAEE,0BAAA;EACA,sBAAA;CD6NH;ACvNG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqOL;AC1MD;;EClCE,mDAAA;EACQ,2CAAA;CFgPT;ACrMD;;EE3FI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF0FF,0BAAA;CD2MD;ACzMD;;;EEhGI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFgGF,0BAAA;CD+MD;ACtMD;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EH+HA,mBAAA;ECjEA,4FAAA;EACQ,oFAAA;CF8QT;ACjND;;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,yDAAA;EACQ,iDAAA;CFwRT;AC9MD;;EAEE,+CAAA;CDgND;AC5MD;EEhII,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EHkJA,mBAAA;CDkND;ACrND;;EEhII,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,wDAAA;EACQ,gDAAA;CF+ST;AC/ND;;EAYI,0CAAA;CDuNH;AClND;;;EAGE,iBAAA;CDoND;AC/LD;EAfI;;;IAGE,YAAA;IE7JF,yEAAA;IACA,oEAAA;IACA,8FAAA;IAAA,uEAAA;IACA,4BAAA;IACA,uHAAA;GH+WD;CACF;AC3MD;EACE,8CAAA;EC3HA,2FAAA;EACQ,mFAAA;CFyUT;ACnMD;EEtLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+MD;AC1MD;EEvLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuND;ACjND;EExLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+ND;ACxND;EEzLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuOD;ACxND;EEjMI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH4ZH;ACrND;EE3MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHmaH;AC3ND;EE5MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH0aH;ACjOD;EE7MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHibH;ACvOD;EE9MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHwbH;AC7OD;EE/MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH+bH;AChPD;EElLI,8MAAA;EACA,yMAAA;EACA,sMAAA;CHqaH;AC5OD;EACE,mBAAA;EC9KA,mDAAA;EACQ,2CAAA;CF6ZT;AC7OD;;;EAGE,8BAAA;EEnOE,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFiOF,sBAAA;CDmPD;ACxPD;;;EAQI,kBAAA;CDqPH;AC3OD;ECnME,kDAAA;EACQ,0CAAA;CFibT;ACrOD;EE5PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHoeH;AC3OD;EE7PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH2eH;ACjPD;EE9PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHkfH;ACvPD;EE/PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHyfH;AC7PD;EEhQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHggBH;ACnQD;EEjQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHugBH;ACnQD;EExQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFsQF,sBAAA;EC3NA,0FAAA;EACQ,kFAAA;CFqeT","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/gateway/supplier/alipay.go b/gateway/supplier/alipay.go deleted file mode 100644 index 9470ea0..0000000 --- a/gateway/supplier/alipay.go +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************** - ** @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 controller - -import ( - "gateway/models" -) - -type AlipayImpl struct { -} - -func (c *AlipayImpl) Scan(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *AlipayImpl) H5(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *AlipayImpl) Syt(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *AlipayImpl) Fast(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) bool { - var scanData ScanData - scanData.Status = "01" - return true -} - -func (c *AlipayImpl) Web(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) bool { - var scanData ScanData - scanData.Status = "01" - return true -} - -func (c *AlipayImpl) PayNotify() { -} - -func (c *AlipayImpl) PayQuery(orderInfo models.OrderInfo) bool { - return true -} - -func (c *AlipayImpl) PayFor(info models.PayforInfo) string { - return "" -} - -func (c *AlipayImpl) PayForNotify() string { - return "" -} - -func (c *AlipayImpl) PayForQuery(payFor models.PayforInfo) (string, string) { - return "", "" -} - -func (c *AlipayImpl) BalanceQuery(roadInfo models.RoadInfo) float64 { - return 0.00 -} diff --git a/gateway/supplier/consts.go b/gateway/supplier/consts.go deleted file mode 100644 index 6751d91..0000000 --- a/gateway/supplier/consts.go +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************** - ** @Desc : This file for ... - ** @Time : 2019/11/19 18:12 - ** @Author : yuebin - ** @File : consts.go - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/11/19 18:12 - ** @Software: GoLand -****************************************************/ -package controller - -const ( - PayNotify = "" -) diff --git a/gateway/supplier/gateway_solve.go b/gateway/supplier/gateway_solve.go deleted file mode 100644 index f9813fc..0000000 --- a/gateway/supplier/gateway_solve.go +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************** - ** @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 controller - -import ( - "context" - "gateway/models" - "github.com/beego/beego/v2/client/orm" - "github.com/beego/beego/v2/core/logs" -) - -/* -* 插入支付订单记录和订单利润记录,保证一致性 - */ -func InsertOrderAndOrderProfit(orderInfo models.OrderInfo, orderProfitInfo models.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 -} diff --git a/gateway/supplier/init.go b/gateway/supplier/init.go deleted file mode 100644 index eb0b4ea..0000000 --- a/gateway/supplier/init.go +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************** - ** @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 controller - -import ( - "github.com/beego/beego/v2/core/logs" -) - -var registerSupplier = make(map[string]PayInterface) - -//注册各种上游的支付接口 - -func init() { - registerSupplier["KF"] = new(KuaiFuImpl) - logs.Notice(CheckSupplierByCode("KF")) - registerSupplier["WEIXIN"] = new(WeiXinImpl) - logs.Notice(CheckSupplierByCode("WEIXIN")) - registerSupplier["ALIPAY"] = new(AlipayImpl) - logs.Notice(CheckSupplierByCode("ALIPAY")) -} - -func GetPaySupplierByCode(code string) PayInterface { - return registerSupplier[code] -} diff --git a/gateway/supplier/kuaifu.go b/gateway/supplier/kuaifu.go deleted file mode 100644 index 0d023b1..0000000 --- a/gateway/supplier/kuaifu.go +++ /dev/null @@ -1,381 +0,0 @@ -/*************************************************** - ** @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 controller - -import ( - "fmt" - "gateway/common" - "gateway/models" - "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 models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) 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"] = PayNotify + "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 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 models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *KuaiFuImpl) Syt(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *KuaiFuImpl) Fast(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) bool { - var scanData ScanData - scanData.Status = "01" - return true -} - -func (c *KuaiFuImpl) Web(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) bool { - var scanData ScanData - scanData.Status = "01" - return true -} - -//支付回调 -func (c *KuaiFuImpl) PayNotify() { - params := make(map[string]string) - orderNo := strings.TrimSpace(c.GetString("orderNo")) - orderInfo := models.GetOrderByBankOrderId(orderNo) - if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 { - logs.Error("快付回调的订单号不存在,订单号=", orderNo) - c.StopRun() - } - roadInfo := models.GetRoadInfoByRoadUid(orderInfo.RoadUid) - if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 { - logs.Error("支付通道已经关系或者删除,不进行回调") - c.StopRun() - } - merchantUid := orderInfo.MerchantUid - merchantInfo := models.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"] - paySolveController := new(PaySolveController) - if tradeStatus == "FAILED" { - if !paySolveController.SolvePayFail(orderInfo, "fail") { - logs.Error("solve order fail fail") - } - } else if tradeStatus == "CANCELED" { - if !paySolveController.SolvePayFail(orderInfo, "cancel") { - logs.Error("solve order cancel fail") - } - } else if tradeStatus == "WAITING_PAYMENT" { - logs.Notice("快付回调,该订单还处于等待支付,订单id=", orderNo) - } else if tradeStatus == "SUCCESS" { - //订单支付成功,需要搞很多事情 TODO - paySolveController.SolvePaySuccess(orderInfo.BankOrderId, orderInfo.FactAmount, c.GetString("trxNo")) - } - c.Ctx.WriteString("success") -} - -func (c *KuaiFuImpl) PayQuery(orderInfo models.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() - paySolveController := new(PaySolveController) - trxNo := gojson.Json(response).Get("trxNo").Tostring() - if tradeStatus == "SUCCESS" { - //调用支付成功的接口,做加款更新操作,需要把实际支付金额传入 - if !paySolveController.SolvePaySuccess(orderInfo.BankOrderId, factAmount, trxNo) { - return false - } - } else if tradeStatus == "FAILED" { - if !paySolveController.SolvePayFail(orderInfo, "fail") { - return false - } - } else { - logs.Info("订单状态处于:" + tradeStatus + ";bankOrderId:" + orderInfo.BankOrderId) - } - return true -} - -func (c *KuaiFuImpl) PayFor(payFor models.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 == common.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 models.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 common.PAYFOR_SOLVING, "查询失败" - } - - payFor.ResponseContext = response - payFor.ResponseTime = utils.GetBasicDateTime() - payFor.UpdateTime = utils.GetBasicDateTime() - if !models.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 common.PAYFOR_SOLVING, resultMsg - } - - logs.Info("快付代付查询返回结果:", resultMsg) - - merchantOrderId := gojson.Json(response).Get("merchantOrderId").Tostring() - if merchantOrderId != payFor.BankOrderId { - logs.Error("快付代付返回结果,订单id不一致: ", merchantOrderId) - return common.PAYFOR_SOLVING, "快付代付返回结果,订单id不一致" - } - - settStatus := gojson.Json(response).Get("settStatus").Tostring() - - if settStatus == "00" { - return common.PAYFOR_SUCCESS, "代付成功" - } else if settStatus == "01" { - return common.PAYFOR_FAIL, "代付失败" - } else { - return common.PAYFOR_BANKING, "银行处理中" - } -} - -func (c *KuaiFuImpl) BalanceQuery(roadInfo models.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 -} diff --git a/gateway/supplier/order_settle.go b/gateway/supplier/order_settle.go deleted file mode 100644 index 4310b4f..0000000 --- a/gateway/supplier/order_settle.go +++ /dev/null @@ -1,182 +0,0 @@ -/*************************************************** - ** @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 controller - -import ( - "context" - "errors" - "fmt" - "gateway/common" - "gateway/models" - "gateway/utils" - "github.com/beego/beego/v2/client/orm" - "github.com/beego/beego/v2/core/logs" - "time" -) - -//订单结算,将那些支付成功的订单金额加入到商户账户的结算金额中 -func OrderSettle() { - - params := make(map[string]string) - params["is_allow_settle"] = common.YES - params["is_complete_settle"] = common.NO - orderSettleList := models.GetOrderSettleListByParams(params) - for _, orderSettle := range orderSettleList { - orderProfitInfo := models.GetOrderProfitByBankOrderId(orderSettle.BankOrderId) - if !settle(orderSettle, orderProfitInfo) { - logs.Error(fmt.Sprintf("结算订单bankOrderId=%s, 执行失败", orderSettle.BankOrderId)) - } else { - logs.Info(fmt.Sprintf("结算订单bankOrderId=%s,执行成功", orderSettle.BankOrderId)) - } - } -} - -func settle(orderSettle models.OrderSettleInfo, orderProfit models.OrderProfitInfo) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - tmpSettle := new(models.OrderSettleInfo) - if err := txOrm.Raw("select * from order_settle_info where bank_order_id=? for update", orderSettle.BankOrderId).QueryRow(tmpSettle); err != nil || tmpSettle == nil { - logs.Error("获取tmpSettle失败,bankOrderId=%s", orderSettle.BankOrderId) - return err - } - tmpSettle.UpdateTime = utils.GetBasicDateTime() - tmpSettle.IsCompleteSettle = common.YES - if _, err := txOrm.Update(tmpSettle); err != nil { - logs.Error("更新tmpSettle失败,错误:", err) - return err - } - - accountInfo := new(models.AccountInfo) - if err := txOrm.Raw("select * from account_info where account_uid=? for update", orderSettle.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo == nil { - logs.Error("结算select account info失败,错误信息:", err) - return err - } - accountInfo.UpdateTime = utils.GetBasicDateTime() - accountInfo.SettleAmount += orderProfit.FactAmount - if _, err := txOrm.Update(accountInfo); err != nil { - logs.Error("结算update account 失败,错误信息:", err) - return err - } - - merchantDeployInfo := models.GetMerchantDeployByUidAndPayType(accountInfo.AccountUid, orderSettle.PayTypeCode) - if merchantDeployInfo.IsLoan == common.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 !models.IsExistMerchantLoadByParams(params) { - tmp := models.MerchantLoadInfo{Status: common.NO, MerchantUid: orderSettle.MerchantUid, RoadUid: orderSettle.RoadUid, - LoadDate: date, 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(models.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 == nil { - logs.Error(fmt.Sprintf("结算过程,select merchant load info失败,错误信息:%s", 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失败,失败信息:%s", err)) - return err - } - } - } - } else { - logs.Info(fmt.Sprintf("结算过程中,该商户不需要押款,全款结算")) - } - return nil - }); err != nil { - return false - } - return true -} - -/* -* 商户的押款释放处理,根据商户的押款时间进行处理 - */ -func MerchantLoadSolve() { - hour := time.Now().Hour() - merchantDeployList := models.GetMerchantDeployByHour(hour) - for _, merchantDeploy := range merchantDeployList { - logs.Info(fmt.Sprintf("开始执行商户uid=%s,进行解款操作", merchantDeploy.MerchantUid)) - - loadDate := utils.GetDateBeforeDays(merchantDeploy.LoanDays) - params := make(map[string]string) - params["status"] = common.NO - params["merchant_uid"] = merchantDeploy.MerchantUid - params["load_date"] = loadDate - - merchantLoadList := models.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 models.MerchantLoadInfo) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - tmpLoad := new(models.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 == nil { - logs.Error(fmt.Sprintf("解款操作获取商户押款信息失败,fail: %s", err)) - return err - - } - if tmpLoad.Status != common.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 = common.YES - if _, err := txOrm.Update(tmpLoad); err != nil { - logs.Error(fmt.Sprintf("解款操作更新merchant load info 失败:%s", err)) - return err - } - - accountInfo := new(models.AccountInfo) - accountInfo.UpdateTime = utils.GetBasicDateTime() - if accountInfo.LoanAmount >= tmpLoad.LoadAmount { - accountInfo.LoanAmount -= tmpLoad.LoadAmount - } else { - accountInfo.LoanAmount = common.ZERO - } - - if _, err := o.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 -} diff --git a/gateway/supplier/pay_solve.go b/gateway/supplier/pay_solve.go deleted file mode 100644 index 88212d4..0000000 --- a/gateway/supplier/pay_solve.go +++ /dev/null @@ -1,489 +0,0 @@ -/*************************************************** - ** @Desc : 处理订单状态,用户加款等核心业务 - ** @Time : 2019/10/31 11:44 - ** @Author : yuebin - ** @File : pay_solve - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/10/31 11:44 - ** @Software: GoLand -****************************************************/ -package controller - -import ( - "context" - "errors" - "fmt" - "gateway/common" - "gateway/message_queue" - "gateway/models" - "gateway/utils" - "github.com/beego/beego/v2/client/orm" - "github.com/beego/beego/v2/core/logs" - url2 "net/url" - "strconv" -) - -type PaySolveController struct { -} - -//处理支付成功的加款等各项操作 -func (c *PaySolveController) SolvePaySuccess(bankOrderId string, factAmount float64, trxNo string) bool { - - o := orm.NewOrm() - - err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - var orderInfo models.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 <= common.ZERO { - factAmount = orderInfo.OrderAmount - } - - var orderProfitInfo models.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)) - } - - comp := c.CompareOrderAndFactAmount(factAmount, orderInfo) - //如果实际支付金额比订单金额大或者小,那么重新按照实际金额金额利润计算 - if comp != 0 { - orderProfitInfo.FactAmount = factAmount - orderProfitInfo.SupplierProfit = orderInfo.FactAmount * orderProfitInfo.SupplierRate - orderProfitInfo.PlatformProfit = orderInfo.FactAmount * orderProfitInfo.PlatformRate - orderProfitInfo.AgentProfit = orderInfo.FactAmount * orderProfitInfo.AgentRate - orderProfitInfo.AllProfit = orderProfitInfo.SupplierProfit + orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit - orderProfitInfo.UserInAmount = orderProfitInfo.FactAmount - orderProfitInfo.AllProfit - orderProfitInfo.UpdateTime = utils.GetBasicDateTime() - - orderInfo.FactAmount = factAmount - //如果实际支付金额跟订单金额有出入,那么需要重新更新利润记录 - if _, err := txOrm.Update(orderProfitInfo); err != nil { - logs.Info("solve pay success fail:", err) - return err - } - } - - orderInfo.Status = common.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 - } - - //插入一条待结算记录 - settAmount := orderProfitInfo.FactAmount - orderProfitInfo.SupplierProfit - orderProfitInfo.PlatformProfit - orderProfitInfo.AgentProfit - if settAmount <= 0.00 { - logs.Error(fmt.Sprintf("订单id=%s,计算利润存在异常", bankOrderId)) - return errors.New(fmt.Sprintf("订单id=%s,计算利润存在异常", bankOrderId)) - } - orderSettleInfo := models.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: settAmount, IsAllowSettle: common.YES, - IsCompleteSettle: common.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 models.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(models.ACCOUNT_INFO).Filter("account_uid", orderInfo.MerchantUid). - Update((orm.Params{"balance": accountInfo.Balance + settAmount, "wait_amount": accountInfo.WaitAmount + settAmount})); err != nil { - logs.Error(fmt.Sprintf("solve pay success, update account info fail: %s, bankOrderId = %s", err, bankOrderId)) - return err - } - - //添加一条动账记录 - accountHistory := models.AccountHistoryInfo{AccountUid: orderInfo.MerchantUid, AccountName: orderInfo.MerchantName, - Type: common.PLUS_AMOUNT, Amount: settAmount, Balance: accountInfo.Balance + settAmount, - 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 := models.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 = common.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 c.CreateOrderNotifyInfo(orderInfo, common.SUCCESS) - - return nil - }) - - if err != nil { - logs.Error("SolvePaySuccess失败:", err) - return false - } - - logs.Info("SolvePaySuccess处理成功") - return true -} - -//处理支付失败 -func (c *PaySolveController) SolvePayFail(orderInfo models.OrderInfo, str string) bool { - o := orm.NewOrm() - err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - var orderTmp models.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(models.ORDER_INFO).Filter("bank_order_id", bankOrderId).Update(orm.Params{"status": str, "bank_trans_id": orderInfo.BankTransId}); err != nil { - logs.Error("更改订单状态失败:", err) - return err - } - if _, err := txOrm.QueryTable(models.ORDER_PROFIT_INFO).Filter("bank_order_id", bankOrderId).Update(orm.Params{"status": str, "bank_trans_id": orderInfo.BankTransId}); err != nil { - logs.Error("更改订单状态失败:", err) - return err - } - - go c.CreateOrderNotifyInfo(orderInfo, common.FAIL) - - return nil - }) - - if err != nil { - logs.Error("SolvePayFail:", err) - return false - } - - logs.Info("SolvePayFail成功") - return true -} - -//处理订单冻结 -func (c *PaySolveController) SolveOrderFreeze(bankOrderId string) bool { - o := orm.NewOrm() - - err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - var orderInfo models.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 != common.SUCCESS { - logs.Error("非成功订单不能进行冻结") - return errors.New("非成功订单不能进行冻结") - } - - orderInfo.Freeze = common.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 := models.GetOrderProfitByBankOrderId(bankOrderId) - var accountInfo models.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 := models.AccountHistoryInfo{AccountName: accountInfo.AccountName, AccountUid: accountInfo.AccountUid, - Type: common.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 (c *PaySolveController) SolveOrderUnfreeze(bankOrderId string) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - orderInfo := new(models.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 = common.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 := models.GetOrderProfitByBankOrderId(bankOrderId) - - accountInfo := new(models.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 := models.AccountHistoryInfo{AccountUid: accountInfo.AccountUid, AccountName: accountInfo.AccountName, Type: common.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 (c *PaySolveController) SolveRefund(bankOrderId string) bool { - o := orm.NewOrm() - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - orderInfo := new(models.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 = common.YES - orderInfo.RefundTime = utils.GetBasicDateTime() - - orderProfitInfo := models.GetOrderProfitByBankOrderId(bankOrderId) - account := new(models.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 == common.YES { - account.FreezeAmount = account.FreezeAmount - orderProfitInfo.UserInAmount - if account.FreezeAmount < 0 { - account.FreezeAmount = common.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 := models.AccountHistoryInfo{AccountName: account.AccountName, AccountUid: account.AccountUid, - Type: common.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 (c *PaySolveController) SolveOrderRoll(bankOrderId string) bool { - o := orm.NewOrm() - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - orderInfo := new(models.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 != common.SUCCESS { - logs.Error("solve order roll 订单不存在或者订单状态不是success, bankOrderId=", bankOrderId) - return errors.New("solve order roll failed") - } - orderInfo.UpdateTime = utils.GetBasicDateTime() - - orderProfitInfo := models.GetOrderProfitByBankOrderId(bankOrderId) - - account := new(models.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 == common.YES { - account.Balance = account.Balance + orderProfitInfo.UserInAmount - account.SettleAmount = account.SettleAmount + orderProfitInfo.UserInAmount - orderInfo.Refund = common.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 := models.AccountHistoryInfo{AccountUid: account.AccountUid, AccountName: account.AccountName, - Type: common.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 (c *PaySolveController) CompareOrderAndFactAmount(factAmount float64, orderInfo models.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 (c *PaySolveController) CreateOrderNotifyInfo(orderInfo models.OrderInfo, tradeStatus string) { - - notifyInfo := new(models.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 := models.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) - - url := url2.Values{} - for k, v := range params { - url.Add(k, v) - } - - notifyInfo.Url = orderInfo.NotifyUrl + "?" + url.Encode() - - if models.InsertNotifyInfo(*notifyInfo) { - logs.Info(fmt.Sprintf("订单bankOrderId=%s,已经将回调地址插入数据库", orderInfo.BankOrderId)) - } else { - logs.Error(fmt.Sprintf("订单bankOrderId=%s,插入回调数据库失败", orderInfo.BankOrderId)) - } - //将订单发送到消息队列,给下面的商户进行回调 - message_queue.SendMessage(common.MqOrderNotify, orderInfo.BankOrderId) -} diff --git a/gateway/supplier/payfor_solve.go b/gateway/supplier/payfor_solve.go deleted file mode 100644 index 60626a9..0000000 --- a/gateway/supplier/payfor_solve.go +++ /dev/null @@ -1,350 +0,0 @@ -/*************************************************** - ** @Desc : 代付处理 - ** @Time : 2019/11/28 18:52 - ** @Author : yuebin - ** @File : payfor_solve - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/11/28 18:52 - ** @Software: GoLand -****************************************************/ -package controller - -import ( - "context" - "errors" - "fmt" - "gateway/common" - "gateway/message_queue" - "gateway/models" - "gateway/utils" - "github.com/beego/beego/v2/client/orm" - "github.com/beego/beego/v2/core/logs" - "strings" -) - -func PayForFail(payFor models.PayforInfo) bool { - - o := orm.NewOrm() - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - - var tmpForPay models.PayforInfo - if err := txOrm.Raw("select * from payfor_info where bank_order_id = ? for update", payFor.BankOrderId).QueryRow(&tmpForPay); err != nil || tmpForPay.PayforUid == "" { - logs.Error("solve pay fail select fail:", err) - return err - } - - if tmpForPay.Status == common.PAYFOR_FAIL || tmpForPay.Status == common.PAYFOR_SUCCESS { - logs.Error(fmt.Sprintf("该代付订单uid=%s,状态已经是最终结果", payFor.PayforUid)) - return errors.New("状态已经是最终结果") - } - //更新payfor记录的状态 - tmpForPay.Status = common.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 models.AccountInfo - if err := txOrm.Raw("select * from account_info where account_uid = ? for update", payFor.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" { - logs.Error("payfor select account fail:", err) - return err - } - account.UpdateTime = utils.GetBasicDateTime() - if account.PayforAmount < (payFor.PayforAmount + payFor.PayforFee) { - logs.Error(fmt.Sprintf("商户uid=%s,账户中待代付金额小于代付记录的金额", payFor.MerchantUid)) - return errors.New("账户中待代付金额小于代付记录的金额") - } - //将正在打款中的金额减去 - account.PayforAmount = account.PayforAmount - payFor.PayforAmount - payFor.PayforFee - - 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(payFor models.PayforInfo) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - var tmpPayFor models.PayforInfo - if err := txOrm.Raw("select * from payfor_info where bank_order_id = ? for update", payFor.BankOrderId).QueryRow(&tmpPayFor); err != nil || tmpPayFor.PayforUid == "" { - logs.Error("payfor success select payfor fail:", err) - return err - } - if tmpPayFor.Status == common.PAYFOR_FAIL || tmpPayFor.Status == common.PAYFOR_SUCCESS { - logs.Error(fmt.Sprintf("该代付订单uid=%s,已经是最终结果,不需要处理", payFor.PayforUid)) - return errors.New("已经是最终结果,不需要处理") - } - tmpPayFor.UpdateTime = utils.GetBasicDateTime() - tmpPayFor.Status = common.PAYFOR_SUCCESS - _, err := txOrm.Update(&tmpPayFor) - if err != nil { - logs.Error("PayForSuccess update payfor fail: ", err) - return err - } - - var account models.AccountInfo - if err := txOrm.Raw("select * from account_info where account_uid = ? for update", payFor.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" { - logs.Error("payfor success select account fail:", err) - return err - } - - account.UpdateTime = utils.GetBasicDateTime() - if account.PayforAmount < (payFor.PayforAmount + payFor.PayforFee) { - logs.Error(fmt.Sprintf("商户uid=%s,账户中待代付金额小于代付记录的金额", payFor.MerchantUid)) - return errors.New("账户中待代付金额小于代付记录的金额") - } - - //代付打款中的金额减去 - account.PayforAmount = account.PayforAmount - payFor.PayforAmount - payFor.PayforFee - //减去余额,减去可用金额 - account.Balance = account.Balance - payFor.PayforAmount - payFor.PayforFee - //已结算金额减去 - account.SettleAmount = account.SettleAmount - payFor.PayforAmount - payFor.PayforFee - - if _, err := txOrm.Update(&account); err != nil { - logs.Error("PayForSuccess udpate account fail:", err) - return err - } - - //添加一条动账记录 - accountHistory := models.AccountHistoryInfo{AccountUid: payFor.MerchantUid, AccountName: payFor.MerchantName, - Type: common.SUB_AMOUNT, Amount: payFor.PayforAmount + payFor.PayforFee, 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 -} - -/* -* 自动审核代付订单 - */ -func SolvePayForConfirm() { - params := make(map[string]string) - beforeOneDay := utils.GetDateTimeBeforeDays(1) - nowDate := utils.GetBasicDateTime() - params["create_time__lte"] = beforeOneDay - params["create_time__gte"] = nowDate - params["status"] = common.PAYFOR_COMFRIM - payForList := models.GetPayForListByParams(params) - for _, p := range payForList { - if p.Type == common.SELF_HELP || p.Type == common.SELF_MERCHANT { - //系统后台提交的,人工审核 - continue - } - //判断商户是否开通了自动代付功能 - merchant := models.GetMerchantByUid(p.MerchantUid) - //判断商户是否开通了自动代付 - if merchant.AutoPayFor == common.NO || merchant.AutoPayFor == "" { - logs.Notice(fmt.Sprintf("该商户uid=%s, 没有开通自动代付功能", p.MerchantUid)) - continue - } - //找自动代付通道 - findPayForRoad(p, merchant) - } -} - -func findPayForRoad(payFor models.PayforInfo, merchant models.MerchantInfo) bool { - //检查是否单独填写了每笔代付的手续费 - if merchant.PayforFee > common.ZERO { - logs.Info(fmt.Sprintf("商户uid=%s,有单独的代付手续费。", merchant.MerchantUid)) - payFor.PayforFee = merchant.PayforFee - payFor.PayforTotalAmount = payFor.PayforFee + payFor.PayforAmount - } - - if merchant.SinglePayForRoadUid != "" { - payFor.RoadUid = merchant.SinglePayForRoadUid - payFor.RoadName = merchant.SinglePayForRoadName - } else { - //到轮询里面寻找代付通道 - if merchant.RollPayForRoadCode == "" { - logs.Notice(fmt.Sprintf("该商户没有配置代付通道")) - return false - } - roadPoolInfo := models.GetRoadPoolByRoadPoolCode(merchant.RollPayForRoadCode) - roadUids := strings.Split(roadPoolInfo.RoadUidPool, "||") - roadInfoList := models.GetRoadInfosByRoadUids(roadUids) - if len(roadUids) == 0 || len(roadInfoList) == 0 { - logs.Error(fmt.Sprintf("通道轮询池=%s, 没有配置通道", merchant.RollPayForRoadCode)) - return false - } - payFor.RoadUid = roadInfoList[0].RoadUid - payFor.RoadName = roadInfoList[0].RoadName - } - - o := orm.NewOrm() - // 开启事务 - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - var tmpPayFor models.PayforInfo - if err := txOrm.Raw("select * from payfor_info where payfor_uid = ? for update", payFor.PayforUid).QueryRow(&tmpPayFor); err != nil || tmpPayFor.PayforUid == "" { - logs.Error("find payfor road select payfor fail:", err) - return err - } - - if tmpPayFor.Status != common.PAYFOR_COMFRIM { - logs.Notice(fmt.Sprintf("该代付记录uid=%s,已经被审核", payFor.PayforUid)) - return errors.New("已经被审核") - } - tmpPayFor.UpdateTime = utils.GetBasicDateTime() - tmpPayFor.Status = common.PAYFOR_SOLVING - tmpPayFor.GiveType = common.PAYFOR_ROAD - - if _, err := txOrm.Update(&tmpPayFor); err != nil { - logs.Error(fmt.Sprintf("该代付记录uid=%s,从审核更新为正在处理出错: %s", payFor.PayforUid, err)) - return err - } - - return nil - - }); err != nil { - return false - } - return true -} - -/* -* 执行逻辑 - */ -func SolvePayFor() { - //取出一天之内的没有做处理并且不是手动打款的代付记录 - params := make(map[string]string) - beforeOneDay := utils.GetDateTimeBeforeDays(1) - nowDate := utils.GetBasicDateTime() - params["create_time__lte"] = nowDate - params["create_time__gte"] = beforeOneDay - params["is_send"] = "no" - params["status"] = common.PAYFOR_SOLVING - params["give_type"] = common.PAYFOR_ROAD - - payForList := models.GetPayForListByParams(params) - for _, p := range payForList { - if p.Type == common.SELF_HELP { - //如果后台管理人员,通过任意下发,不涉及到商户减款操作,直接发送代付请求 - solveSelf(p) - } else { - SendPayFor(p) - } - } -} - -func solveSelf(payFor models.PayforInfo) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - var tmpPayFor models.PayforInfo - if err := txOrm.Raw("select * from payfor_info where payfor_uid = ? for update", payFor.PayforUid).QueryRow(&tmpPayFor); err != nil || tmpPayFor.PayforUid == "" { - logs.Error("solve self payfor fail:", err) - return errors.New("solve self payfor fail") - } - - if tmpPayFor.IsSend == common.YES { - return errors.New("代付已经发送") - } - - tmpPayFor.UpdateTime = utils.GetBasicDateTime() - if payFor.RoadUid == "" { - tmpPayFor.Status = common.PAYFOR_FAIL - } else { - tmpPayFor.Status = common.PAYFOR_BANKING - tmpPayFor.RequestTime = utils.GetBasicDateTime() - tmpPayFor.IsSend = common.YES - } - if _, err := txOrm.Update(&tmpPayFor); err != nil { - return err - } - - RequestPayFor(payFor) - - return nil - - }); err != nil { - return false - } - return true -} - -func SendPayFor(payFor models.PayforInfo) bool { - o := orm.NewOrm() - - if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error { - var tmpPayFor models.PayforInfo - if err := txOrm.Raw("select * from payfor_info where payfor_uid = ? for update", payFor.PayforUid).QueryRow(&tmpPayFor); err != nil || tmpPayFor.PayforUid == "" { - logs.Error("send payfor select payfor fail: ", err) - return err - } - - var account models.AccountInfo - if err := txOrm.Raw("select * from account_info where account_uid = ? for update", payFor.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" { - logs.Error("send payfor select account fail:", err) - return err - } - - //支付金额不足,将直接判定为失败,不往下面邹逻辑了 - if account.SettleAmount-account.PayforAmount < tmpPayFor.PayforAmount+tmpPayFor.PayforFee { - tmpPayFor.Status = common.PAYFOR_FAIL - tmpPayFor.UpdateTime = utils.GetBasicDateTime() - - if _, err := txOrm.Update(&tmpPayFor); err != nil { - return err - } else { - return nil - } - } - - account.UpdateTime = utils.GetBasicDateTime() - account.PayforAmount = account.PayforAmount + payFor.PayforAmount + payFor.PayforFee - - if _, err := txOrm.Update(&account); err != nil { - logs.Error(fmt.Sprintf("商户uid=%s,在发送代付给上游的处理中,更新账户表出错, err: %s", payFor.MerchantUid, err)) - return err - } - - tmpPayFor.IsSend = common.YES - tmpPayFor.Status = common.PAYFOR_BANKING //变为银行处理中 - tmpPayFor.RequestTime = utils.GetBasicDateTime() - tmpPayFor.UpdateTime = utils.GetBasicDateTime() - - if _, err := txOrm.Update(&tmpPayFor); err != nil { - logs.Error(fmt.Sprintf("商户uid=%s,在发送代付给上游的处理中,更代付列表出错, err:%s", payFor.MerchantUid, err)) - return err - } - - RequestPayFor(payFor) - - return nil - }); err != nil { - return false - } - return true -} - -func RequestPayFor(payFor models.PayforInfo) { - if payFor.RoadUid == "" { - return - } - roadInfo := models.GetRoadInfoByRoadUid(payFor.RoadUid) - supplierCode := roadInfo.ProductUid - supplier := GetPaySupplierByCode(supplierCode) - res := supplier.PayFor(payFor) - logs.Info(fmt.Sprintf("代付uid=%s,上游处理结果为:%s", payFor.PayforUid, res)) - //将代付订单号发送到消息队列 - message_queue.SendMessage(common.MQ_PAYFOR_QUERY, payFor.BankOrderId) -} diff --git a/gateway/supplier/supplier.go b/gateway/supplier/supplier.go deleted file mode 100644 index 93d918f..0000000 --- a/gateway/supplier/supplier.go +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************** - ** @Desc : 上有支付公司的编号 - ** @Time : 2019/10/28 10:47 - ** @Author : yuebin - ** @File : supplier - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/10/28 10:47 - ** @Software: GoLand -****************************************************/ -package controller - -//添加新的上游通道时,需要添加这里 -var supplierCode2Name = map[string]string{ - "KF": "快付支付", - "WEIXIN": "官方微信", - "ALIPAY": "官方支付宝", -} - -func GetSupplierMap() map[string]string { - return supplierCode2Name -} - -func GetSupplierCodes() []string { - var supplierCodes []string - for k := range supplierCode2Name { - supplierCodes = append(supplierCodes, k) - } - - return supplierCodes -} - -func GetSupplierNames() []string { - var supplierNames []string - for _, v := range supplierCode2Name { - supplierNames = append(supplierNames, v) - } - return supplierNames -} - -func CheckSupplierByCode(code string) string { - for k, v := range supplierCode2Name { - if k == code { - return v + ",注册完毕" - } - } - return "未找到上游名称,注册有问题。" -} diff --git a/gateway/supplier/weixin.go b/gateway/supplier/weixin.go deleted file mode 100644 index 2f4e329..0000000 --- a/gateway/supplier/weixin.go +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************** - ** @Desc : This file for ... - ** @Time : 2019/10/28 16:38 - ** @Author : yuebin - ** @File : weixin - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/10/28 16:38 - ** @Software: GoLand -****************************************************/ -package controller - -import ( - "gateway/models" -) - -type WeiXinImpl struct { -} - -func (c *WeiXinImpl) Scan(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *WeiXinImpl) H5(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *WeiXinImpl) Syt(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) ScanData { - var scanData ScanData - scanData.Status = "01" - return scanData -} - -func (c *WeiXinImpl) Fast(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) bool { - var scanData ScanData - scanData.Status = "01" - return true -} - -func (c *WeiXinImpl) Web(orderInfo models.OrderInfo, roadInfo models.RoadInfo, merchantInfo models.MerchantInfo) bool { - var scanData ScanData - scanData.Status = "01" - return true -} - -func (c *WeiXinImpl) PayNotify() { -} - -func (c *WeiXinImpl) PayQuery(orderInfo models.OrderInfo) bool { - return true -} - -func (c *WeiXinImpl) PayFor(payFor models.PayforInfo) string { - return "" -} - -func (c *WeiXinImpl) PayForNotify() string { - return "" -} - -func (c *WeiXinImpl) PayForQuery(payFor models.PayforInfo) (string, string) { - return "", "" -} - -func (c *WeiXinImpl) BalanceQuery(roadInfo models.RoadInfo) float64 { - return 0.00 -} diff --git a/gateway/tests/default_test.go b/gateway/tests/default_test.go deleted file mode 100644 index 897437d..0000000 --- a/gateway/tests/default_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package test - -import ( - "net/http" - "net/http/httptest" - "testing" - "runtime" - "path/filepath" - _ "gateway/routers" - - beego "github.com/beego/beego/v2/server/web" - . "github.com/smartystreets/goconvey/convey" -) - -func init() { - _, file, _, _ := runtime.Caller(0) - apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator)))) - beego.TestBeegoInit(apppath) -} - - -// TestBeego is a sample to run an endpoint test -func TestBeego(t *testing.T) { - r, _ := http.NewRequest("GET", "/", nil) - w := httptest.NewRecorder() - beego.BeeApp.Handlers.ServeHTTP(w, r) - - beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String()) - - Convey("Subject: Test Station Endpoint\n", t, func() { - Convey("Status Code Should Be 200", func() { - So(w.Code, ShouldEqual, 200) - }) - Convey("The Result Should Not Be Empty", func() { - So(w.Body.Len(), ShouldBeGreaterThan, 0) - }) - }) -} - diff --git a/gateway/utils/login_verify_code.go b/gateway/utils/login_verify_code.go deleted file mode 100644 index a20847e..0000000 --- a/gateway/utils/login_verify_code.go +++ /dev/null @@ -1,440 +0,0 @@ -/*************************************************** - ** @Desc : generate login verify code image - ** @Time : 2019/8/7 17:14 - ** @Author : yuebin - ** @File : login_verify_code - ** @Last Modified by : yuebin - ** @Last Modified time: 2019/8/7 17:14 - ** @Software: GoLand -****************************************************/ -package utils - -import ( - crand "crypto/rand" - "image" - "image/color" - "math/rand" - "time" - "io" - "image/png" - "net/http" - "strconv" - "fmt" -) - -const ( - stdWidth = 100 - stdHeight = 40 - maxSkew = 2 -) - -const ( - fontWidth = 5 - fontHeight = 8 - blackChar = 1 -) - -var font = [][]byte{ - { // 0 - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0}, - { // 1 - 0, 0, 1, 0, 0, - 0, 1, 1, 0, 0, - 1, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 1, 1, 1, 1, 1}, - { // 2 - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1}, - { // 3 - 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 0, 1, - 1, 1, 1, 1, 0}, - { // 4 - 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, - 1, 0, 0, 1, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0}, - { // 5 - 1, 1, 1, 1, 1, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 0, 1, - 0, 0, 0, 0, 1, - 1, 1, 1, 1, 0}, - { // 6 - 0, 0, 1, 1, 1, - 0, 1, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0}, - { // 7 - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 1, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0}, - { // 8 - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0}, - { // 9 - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 0, 0, 1, - 0, 1, 1, 1, 1, - 0, 0, 0, 0, 1, - 0, 0, 0, 0, 1, - 1, 1, 1, 1, 0}, -} - -type Image struct { - *image.NRGBA - color *color.NRGBA - width int //a digit width - height int //a digit height - dotsize int -} - -func init() { - rand.Seed(int64(time.Second)) - -} - -func NewImage(digits []byte, width, height int) *Image { - img := new(Image) - r := image.Rect(img.width, img.height, stdWidth, stdHeight) - img.NRGBA = image.NewNRGBA(r) - img.color = &color.NRGBA{ - uint8(rand.Intn(129)), - uint8(rand.Intn(129)), - uint8(rand.Intn(129)), - 0xFF} - // Draw background (10 random circles of random brightness) - img.calculateSizes(width, height, len(digits)) - img.fillWithCircles(0, img.dotsize) - maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize - maxy := height - img.height - img.dotsize*2 - x := rnd(img.dotsize*2, maxx) - y := rnd(img.dotsize*2, maxy) - // Draw digits. - for _, n := range digits { - img.drawDigit(font[n], x, y) - x += img.width + img.dotsize - } - // Draw strike-through line. - //img.strikeThrough() - return img - -} - -func (img *Image) WriteTo(w io.Writer) (int64, error) { - return 0, png.Encode(w, img) - -} - -func (img *Image) calculateSizes(width, height, ncount int) { - // Goal: fit all digits inside the image. - var border int - if width > height { - border = height / 5 - } else { - border = width / 5 - } - // Convert everything to floats for calculations. - w := float64(width - border*2) //268 - h := float64(height - border*2) //48 - // fw takes into account 1-dot spacing between digits. - fw := float64(fontWidth) + 1 //6 - fh := float64(fontHeight) //8 - nc := float64(ncount) //7 - // Calculate the width of a single digit taking into account only the - // width of the image. - nw := w / nc //38 - // Calculate the height of a digit from this width. - nh := nw * fh / fw //51 - // Digit too high? - if nh > h { - // Fit digits based on height. - nh = h //nh = 44 - nw = fw / fh * nh - } - // Calculate dot size. - img.dotsize = int(nh / fh) - // Save everything, making the actual width smaller by 1 dot to account - // for spacing between digits. - img.width = int(nw) - img.height = int(nh) - img.dotsize - -} - -func (img *Image) fillWithCircles(n, maxradius int) { - color := img.color - maxx := img.Bounds().Max.X - maxy := img.Bounds().Max.Y - for i := 0; i < n; i++ { - setRandomBrightness(color, 255) - r := rnd(3, maxradius) - img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r) - } - -} - -func (img *Image) drawHorizLine(color color.Color, fromX, toX, y int) { - for x := fromX; x <= toX; x++ { - img.Set(x, y, color) - } - -} - -func (img *Image) drawCircle(color color.Color, x, y, radius int) { - f := 1 - radius - dfx := 1 - dfy := -2 * radius - xx := 0 - yy := radius - img.Set(x, y+radius, color) - img.Set(x, y-radius, color) - img.drawHorizLine(color, x-radius, x+radius, y) - for xx < yy { - if f >= 0 { - yy-- - dfy += 2 - f += dfy - } - xx++ - dfx += 2 - f += dfx - img.drawHorizLine(color, x-xx, x+xx, y+yy) - img.drawHorizLine(color, x-xx, x+xx, y-yy) - img.drawHorizLine(color, x-yy, x+yy, y+xx) - img.drawHorizLine(color, x-yy, x+yy, y-xx) - } - -} - -func (img *Image) strikeThrough() { - r := 0 - maxx := img.Bounds().Max.X - maxy := img.Bounds().Max.Y - y := rnd(maxy/3, maxy-maxy/3) - for x := 0; x < maxx; x += r { - r = rnd(1, img.dotsize/3) - y += rnd(-img.dotsize/2, img.dotsize/2) - if y <= 0 || y >= maxy { - y = rnd(maxy/3, maxy-maxy/3) - } - img.drawCircle(img.color, x, y, r) - } - -} - -func (img *Image) drawDigit(digit []byte, x, y int) { - skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew)) - xs := float64(x) - minr := img.dotsize / 2 // minumum radius - maxr := img.dotsize/2 + img.dotsize/4 // maximum radius - y += rnd(-minr, minr) - for yy := 0; yy < fontHeight; yy++ { - for xx := 0; xx < fontWidth; xx++ { - if digit[yy*fontWidth+xx] != blackChar { - continue - } - // Introduce random variations. - or := rnd(minr, maxr) - ox := x + (xx * img.dotsize) + rnd(0, or/2) - oy := y + (yy * img.dotsize) + rnd(0, or/2) - img.drawCircle(img.color, ox, oy, or) - } - xs += skf - x = int(xs) - } - -} - -func setRandomBrightness(c *color.NRGBA, max uint8) { - minc := min3(c.R, c.G, c.B) - maxc := max3(c.R, c.G, c.B) - if maxc > max { - return - } - n := rand.Intn(int(max-maxc)) - int(minc) - c.R = uint8(int(c.R) + n) - c.G = uint8(int(c.G) + n) - c.B = uint8(int(c.B) + n) - -} - -func min3(x, y, z uint8) (o uint8) { - o = x - if y < o { - o = y - } - if z < o { - o = z - } - return - -} - -func max3(x, y, z uint8) (o uint8) { - o = x - if y > o { - o = y - } - if z > o { - o = z - } - return - -} - -// rnd returns a random number in range [from, to]. - -func rnd(from, to int) int { - //println(to+1-from) - return rand.Intn(to+1-from) + from - -} - -const ( - // Standard length of uniuri string to achive ~95 bits of entropy. - StdLen = 16 - // Length of uniurl string to achive ~119 bits of entropy, closest - // to what can be losslessly converted to UUIDv4 (122 bits). - UUIDLen = 20 -) - -// Standard characters allowed in uniuri string. - -var StdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") - -// New returns a new random string of the standard length, consisting of -// standard characters. - -func New() string { - return NewLenChars(StdLen, StdChars) - -} - -// NewLen returns a new random string of the provided length, consisting of -// standard characters. - -func NewLen(length int) string { - return NewLenChars(length, StdChars) - -} - -// NewLenChars returns a new random string of the provided length, consisting -// of the provided byte slice of allowed characters (maximum 256). - -func NewLenChars(length int, chars []byte) string { - b := make([]byte, length) - r := make([]byte, length+(length/4)) // storage for random bytes. - clen := byte(len(chars)) - maxrb := byte(256 - (256 % len(chars))) - i := 0 - for { - if _, err := io.ReadFull(crand.Reader, r); err != nil { - panic("error reading from random source: " + err.Error()) - } - for _, c := range r { - if c >= maxrb { - // Skip this number to avoid modulo bias. - continue - } - b[i] = chars[c%clen] - i++ - if i == length { - return string(b) - } - } - } - panic("unreachable") - -} - -func GenerateVerifyCodeImg() (*Image, string) { - d := make([]byte, 4) - s := NewLen(4) - ss := "" - d = []byte(s) - for v := range d { - d[v] %= 10 - ss += strconv.FormatInt(int64(d[v]), 32) - } - return NewImage(d, 100, 40), ss -} - -func pic(w http.ResponseWriter, req *http.Request) { - d := make([]byte, 4) - s := NewLen(4) - ss := "" - d = []byte(s) - for v := range d { - d[v] %= 10 - ss += strconv.FormatInt(int64(d[v]), 32) - } - w.Header().Set("Content-Type", "image/png") - NewImage(d, 100, 40).WriteTo(w) - fmt.Println(ss) - -} - -func index(w http.ResponseWriter, req *http.Request) { - str := "

golang 图片验证码例子

\"图片验证码\"" - w.Header().Set("Content-Type", "text/html") - w.Write([]byte(str)) - -} - -func main() { - http.HandleFunc("/pic", pic) - http.HandleFunc("/", index) - s := &http.Server{ - Addr: ":8080", - ReadTimeout: 30 * time.Second, - WriteTimeout: 30 * time.Second, - MaxHeaderBytes: 1 << 20} - s.ListenAndServe() - -} diff --git a/gateway/utils/mysql.go b/gateway/utils/mysql.go deleted file mode 100644 index 623b754..0000000 --- a/gateway/utils/mysql.go +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************** - ** @Desc : This file for 配置数据库连接 - ** @Time : 2018-12-22 13:55:26 - ** @Author : Joker - ** @File : init_database.go - ** @Last Modified by : Joker - ** @Last Modified time:2018-12-22 13:55:26 - ** @Software: GoLand -****************************************************/ -package utils - -import ( - "github.com/beego/beego/v2/client/orm" - beego "github.com/beego/beego/v2/server/web" - _ "github.com/go-sql-driver/mysql" -) - -//初始化数据连接 -func InitDatabase() bool { - //读取配置文件,设置数据库参数 - dbType, _ := beego.AppConfig.String("db_type") - dbAlias, _ := beego.AppConfig.String(dbType + "::db_alias") - dbName, _ := beego.AppConfig.String(dbType + "::db_name") - dbUser, _ := beego.AppConfig.String(dbType + "::db_user") - dbPwd, _ := beego.AppConfig.String(dbType + "::db_pwd") - dbHost, _ := beego.AppConfig.String(dbType + "::db_host") - dbPort, _ := beego.AppConfig.String(dbType + "::db_port") - - var err error - switch dbType { - case "sqlite3": - err = orm.RegisterDataBase(dbAlias, dbType, dbName) - case "mysql": - dbCharset, _ := beego.AppConfig.String(dbType + "::db_charset") - err = orm.RegisterDriver(dbType, orm.DRMySQL) - err = orm.RegisterDataBase(dbAlias, dbType, dbUser+":"+dbPwd+"@tcp("+dbHost+":"+ - dbPort+")/"+dbName+"?charset="+dbCharset) - } - - if err != nil { - return false - } - return true -} diff --git a/gateway/utils/send_messages.go b/gateway/utils/send_messages.go deleted file mode 100644 index 5af7f64..0000000 --- a/gateway/utils/send_messages.go +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************** - ** @Desc : This file for 发送短信验证码 - ** @Time : 2019.04.04 9:37 - ** @Author : Joker - ** @File : send_messages - ** @Last Modified by : Joker - ** @Last Modified time: 2019-11-29 11:05:41 - ** @Software: GoLand -****************************************************/ -package utils - -import ( - "fmt" - "gateway/enum" - "net/http" - "net/url" -) - -// 发送提现通知 -func SendSmsForPay(mobile, code string) bool { - tplValue := url.Values{"#code#": {code}}.Encode() - dataTplSms := url.Values{ - "apikey": {enum.ApiKey}, - "mobile": {mobile}, - "tpl_id": {fmt.Sprintf("%d", enum.TPL1)}, - "tpl_value": {tplValue}} - _, err := http.PostForm(enum.SendSmsUrl, dataTplSms) - if err != nil { - return false - } - return true -} diff --git a/shop/conf/app.conf b/shop/conf/app.conf index 41c80bf..fe0f6ed 100644 --- a/shop/conf/app.conf +++ b/shop/conf/app.conf @@ -1,7 +1,9 @@ #基本信息 appname = shop -httpport = 3800 +httpport = 12308 runmode = dev +siteName = 传奇支付 +host=localhost diff --git a/shop/controllers/page_controller.go b/shop/controllers/page_controller.go index fdd4bb4..a762ef7 100644 --- a/shop/controllers/page_controller.go +++ b/shop/controllers/page_controller.go @@ -21,7 +21,7 @@ type HomeAction struct { /*加载首页及数据*/ func (c *HomeAction) ShowHome() { //取值 - siteName, _ := beego.AppConfig.String("site.name") + siteName, _ := beego.AppConfig.String("siteName") orderNo := xid.New().String() productName := "测试应用-支付功能体验(非商品消费)" diff --git a/shop/controllers/pay.go b/shop/controllers/pay.go index 654b075..c3ed27e 100644 --- a/shop/controllers/pay.go +++ b/shop/controllers/pay.go @@ -51,7 +51,7 @@ func (c *PayController) Pay() { str := "/scan.html?" + "orderNo=" + orderNo + "&orderPrice=" + amount + "&qrCode=" + response.Qrcode + "&payWayCode=" + isScan c.Redirect(str, 302) } else { - flash.Error("请求失败,生成二维码失败") + flash.Error(response.Msg) flash.Store(&c.Controller) c.Redirect("/error.html", 302) } diff --git a/shop/controllers/scan_shop.go b/shop/controllers/scan_shop.go index 6bf30fd..af0113a 100644 --- a/shop/controllers/scan_shop.go +++ b/shop/controllers/scan_shop.go @@ -38,15 +38,15 @@ type ResponseJSON struct { } const ( - HOST = "http://localhost:10081" + HOST = "http://localhost:12309" SCAN_HOST = HOST + "/gateway/scan" H5_HOST = HOST + "/gateway/h5" SYT_HOST = HOST + "/gateway/syt" FAST_HOST = HOST + "/gateway/fast" NOTIFY_URL = HOST + "/shop/notify" RETURN_URL = HOST + "/shop/return" - PAY_KEY = "kkkkbmrb9gijhrt0th4naoag" - PAY_SERCET = "ssssbmrb9gijhrt0th4naob0" + PAY_KEY = "kkkkc254gk8isf001cqrj6p0" + PAY_SERCET = "ssssc254gk8isf001cqrj6pg" ) func (c *ScanShopController) Prepare() { @@ -77,7 +77,7 @@ func (c *ScanShopController) Shop(requestHost string) *ResponseJSON { if err != nil { logs.Error("扫码请求失败") responseJSON.Code = -1 - responseJSON.Msg = response + " ;" + err.Error() + responseJSON.Msg = response + " ;" + response } else { statusCode := gojson.Json(response).Get("statusCode").Tostring() if statusCode != "00" { @@ -115,6 +115,12 @@ func (c *ScanShopController) ScanRender() { if strings.Contains(payWayCode, "UNION") { c.Data["payTypeName"] = "云闪付app" c.Data["openApp"] = "云闪付app [扫一扫]" + } else if strings.Contains(payWayCode, "WEIXIN") { + c.Data["payTypeName"] = "微信APP" + c.Data["openApp"] = "打开微信 [扫一扫]" + } else if strings.Contains(payWayCode, "ALI") { + c.Data["payTypeName"] = "支付宝APP" + c.Data["openApp"] = "打开支付宝 [扫一扫]" } c.Data["qrCode"] = qrCode c.Data["orderNo"] = orderNo diff --git a/shop/main.go b/shop/main.go index e17af68..ab31e6a 100644 --- a/shop/main.go +++ b/shop/main.go @@ -3,6 +3,7 @@ package main import ( "github.com/beego/beego/v2/core/logs" beego "github.com/beego/beego/v2/server/web" + _ "shop/routers" ) func main() { @@ -16,7 +17,7 @@ func main() { func RegisterLogs() { logs.SetLogger(logs.AdapterFile, `{ - "filename":"../logs/legend.log", + "filename":"../.../logs/legend.log", "level":4, "maxlines":0, "maxsize":0, diff --git a/shop/views/index.html b/shop/views/index.html index cf27ca0..d1e1328 100644 --- a/shop/views/index.html +++ b/shop/views/index.html @@ -77,19 +77,21 @@ style="width:100px;height: 35px;"> -

H5支付(只支持手机端,不支持PC端):

- +
+

H5支付(只支持手机端,不支持PC端):

+ +

快捷支付: