@@ -4,6 +4,7 @@ import ( | |||
"applet/app/db" | |||
"applet/app/md" | |||
"applet/app/utils" | |||
"applet/app/utils/logx" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/implement" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/model" | |||
"code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" | |||
@@ -13,9 +14,29 @@ import ( | |||
"fmt" | |||
"github.com/gin-gonic/gin" | |||
"github.com/tidwall/gjson" | |||
"io/ioutil" | |||
"net/url" | |||
"strings" | |||
) | |||
func CallbackAlipayFace(c *gin.Context) { | |||
body, _ := ioutil.ReadAll(c.Request.Body) | |||
decodeArgs, err := url.QueryUnescape(string(body)) | |||
if err != nil { | |||
_ = logx.Warn(err) | |||
return | |||
} | |||
data, err := url.ParseQuery(decodeArgs) | |||
if err != nil { | |||
return | |||
} | |||
dataMap := make(map[string]interface{}) | |||
for k := range data { | |||
dataMap[k] = data.Get(k) | |||
} | |||
callbackStr := utils.Serialize(dataMap) | |||
fmt.Println("支付宝回调数据", string(callbackStr)) | |||
} | |||
func CallbackChuanshanjia(c *gin.Context) { | |||
userId := c.Query("user_id") | |||
transId := c.Query("trans_id") | |||
@@ -1,6 +1,7 @@ | |||
package hdl | |||
import ( | |||
"applet/app/mw" | |||
"applet/app/svc" | |||
"github.com/gin-gonic/gin" | |||
) | |||
@@ -46,7 +47,13 @@ func CollegeList(c *gin.Context) { | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/v1/college/detail [post] | |||
func CollegeDetail(c *gin.Context) { | |||
svc.CollegeDetail(c) | |||
uid := 0 | |||
if c.GetHeader("Authorization") != "" { | |||
mw.Auth(c) | |||
user := svc.GetUser(c) | |||
uid = int(user.Id) | |||
} | |||
svc.CollegeDetail(c, uid) | |||
} | |||
// CollegeLikeAdd | |||
@@ -49,6 +49,7 @@ func Config(c *gin.Context) { | |||
Guide := make([]md.Guide, 0) | |||
json.Unmarshal([]byte(guideStr), &Guide) | |||
res.Guide = Guide | |||
res.DownUrl = svc.GetSysCfgStr("kuaizhan_url") | |||
e.OutSuc(c, res, nil) | |||
return | |||
} | |||
@@ -0,0 +1,35 @@ | |||
package hdl | |||
import ( | |||
"applet/app/svc" | |||
"github.com/gin-gonic/gin" | |||
) | |||
// GetRealNameAuthBase | |||
// @Summary 实名认证-基础信息 | |||
// @Tags 实名认证 | |||
// @Description 实名认证-分类 | |||
// @Accept json | |||
// @Produce json | |||
// @param Authorization header string true "验证参数Bearer和token空格拼接" | |||
// @Success 200 {object} md.RealNameAuthBasicData "具体数据" | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/v1/faceRealName/base [get] | |||
func GetRealNameAuthBase(c *gin.Context) { | |||
svc.GetRealNameAuthBase(c) | |||
} | |||
// RealNameSave | |||
// @Summary 实名认证-保存 | |||
// @Tags 实名认证 | |||
// @Description 实名认证-保存 | |||
// @Accept json | |||
// @Produce json | |||
// @param Authorization header string true "验证参数Bearer和token空格拼接" | |||
// @Param req body md.RealNameAuthAddRequest true "参数" | |||
// @Success 200 {object} md.RealNameAuthResp "具体数据" | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/v1/faceRealName/save [post] | |||
func RealNameSave(c *gin.Context) { | |||
svc.RealNameSave(c) | |||
} |
@@ -1,261 +0,0 @@ | |||
package alipay | |||
import ( | |||
"applet/app/cfg" | |||
"applet/app/utils/logx" | |||
"fmt" | |||
"github.com/iGoogle-ink/gopay" | |||
"github.com/iGoogle-ink/gopay/alipay" | |||
) | |||
// TradeAppPay is 支付宝APP支付 | |||
// 抖音头条小程序使用APP调起 | |||
func TradeAppPay(appID, priKey, subject, orderID, amount, notiURL, RSA, PKCS string, paySet *md.PayData) (string, error) { | |||
//初始化支付宝客户端 | |||
// appID 是在支付宝申请的APPID | |||
// priKey 是支付宝私钥 | |||
// subject 是支付订单的主题 | |||
// orderID 是智莺这边生成的订单id | |||
// amount 是付费金额 | |||
// notiURL 通知地址url | |||
// passback_params 回调通知参数 | |||
client := alipay.NewClient(appID, priKey, true) | |||
client.DebugSwitch = gopay.DebugOn | |||
//判断密钥的类型 | |||
rsa_type := alipay.RSA2 | |||
pkcs_type := alipay.PKCS1 | |||
if RSA == "1" { | |||
rsa_type = alipay.RSA | |||
} | |||
if PKCS == "1" { | |||
pkcs_type = alipay.PKCS8 | |||
} | |||
if paySet.PayAliUseType == "1" { | |||
rsa_type = alipay.RSA2 | |||
pkcs_type = alipay.PKCS8 | |||
} | |||
//配置公共参数 | |||
client.SetCharset("utf-8"). | |||
SetSignType(rsa_type). | |||
SetPrivateKeyType(pkcs_type) | |||
if notiURL != "" { | |||
client.SetNotifyUrl(notiURL) | |||
} | |||
//新支付宝支付 | |||
if paySet.PayAliUseType == "1" { | |||
appCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAppCertSn) | |||
fmt.Println("-应用-") | |||
fmt.Println(appCertSN) | |||
if err != nil { | |||
fmt.Println(err) | |||
return "", err | |||
} | |||
if appCertSN == "" { | |||
fmt.Println(err) | |||
return "", err | |||
} | |||
client.SetAppCertSN(appCertSN) | |||
//aliPayRootCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayRootCertSn) | |||
aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6" | |||
client.SetAliPayRootCertSN(aliPayRootCertSN) | |||
aliPayPublicCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayrsaPublicKey) | |||
fmt.Println("-公钥-") | |||
fmt.Println(aliPayPublicCertSN) | |||
if err != nil { | |||
fmt.Println(err) | |||
return "", err | |||
} | |||
if aliPayPublicCertSN == "" { | |||
fmt.Println(err) | |||
return "", err | |||
} | |||
client.SetAliPayPublicCertSN(aliPayPublicCertSN) | |||
} | |||
fmt.Println(client) | |||
//请求参数 | |||
body := make(gopay.BodyMap) | |||
body.Set("subject", subject) | |||
body.Set("body", subject) | |||
body.Set("out_trade_no", orderID) | |||
body.Set("total_amount", amount) | |||
body.Set("timeout_express", "30m") | |||
// body.Set("passback_params", orderID) | |||
//手机APP支付参数请求 | |||
payParam, err := client.TradeAppPay(body) | |||
if err != nil { | |||
return "", logx.Warn(err) | |||
} | |||
return payParam, nil | |||
} | |||
// TradeAppPay is 支付宝H5支付 | |||
func TradeWapPay(appID, priKey, subject, orderID, amount, notiURL, RSA, PKCS, page_url string, paySet *md.PayData) (string, error) { | |||
fmt.Println("notifyURL is:>>>>>>>>>>", notiURL) | |||
//aliPayPublicKey := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wn1sU/8Q0rYLlZ6sq3enrPZw2ptp6FecHR2bBFLjJ+sKzepROd0bKddgj+Mr1ffr3Ej78mLdWV8IzLfpXUi945DkrQcOUWLY0MHhYVG2jSs/qzFfpzmtut2Cl2TozYpE84zom9ei06u2AXLMBkU6VpznZl+R4qIgnUfByt3Ix5b3h4Cl6gzXMAB1hJrrrCkq+WvWb3Fy0vmk/DUbJEz8i8mQPff2gsHBE1nMPvHVAMw1GMk9ImB4PxucVek4ZbUzVqxZXphaAgUXFK2FSFU+Q+q1SPvHbUsjtIyL+cLA6H/6ybFF9Ffp27Y14AHPw29+243/SpMisbGcj2KD+evBwIDAQAB" | |||
privateKey := priKey | |||
//判断密钥的类型 | |||
rsa_type := alipay.RSA2 | |||
pkcs_type := alipay.PKCS1 | |||
if RSA == "1" { | |||
rsa_type = alipay.RSA | |||
} | |||
if PKCS == "1" { | |||
pkcs_type = alipay.PKCS8 | |||
} | |||
if paySet.PayAliUseType == "1" { | |||
rsa_type = alipay.RSA2 | |||
pkcs_type = alipay.PKCS8 | |||
} | |||
//初始化支付宝客户端 | |||
// appId:应用ID | |||
// privateKey:应用秘钥 | |||
// isProd:是否是正式环境 | |||
client := alipay.NewClient(appID, privateKey, true) | |||
//配置公共参数 | |||
client.SetCharset("utf-8"). | |||
SetSignType(rsa_type). | |||
SetPrivateKeyType(pkcs_type). | |||
SetReturnUrl(page_url). | |||
SetNotifyUrl(notiURL) | |||
//新支付宝支付 | |||
if paySet.PayAliUseType == "1" { | |||
appCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAppCertSn) | |||
if err != nil { | |||
fmt.Println("appCertSn_err:>>>>>>>>", err) | |||
return "", err | |||
} | |||
if appCertSN == "" { | |||
fmt.Println(err) | |||
return "", err | |||
} | |||
client.SetAppCertSN(appCertSN) | |||
//aliPayRootCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayRootCertSn) | |||
//if err != nil { | |||
// | |||
// fmt.Println("rootcertsn_err:>>>>>>>>>>", err) | |||
// fmt.Println("rootcertsn_err:>>>>>>>>>>", cfg.WxappletFilepath.URL) | |||
// fmt.Println("rootcertsn_err:>>>>>>>>>>", paySet.PayAlipayRootCertSn) | |||
// return "", err | |||
//} | |||
//if aliPayRootCertSN == "" { | |||
// fmt.Println(err) | |||
// return "", err | |||
//} | |||
aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6" | |||
client.SetAliPayRootCertSN(aliPayRootCertSN) | |||
aliPayPublicCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayrsaPublicKey) | |||
if err != nil { | |||
fmt.Println("publicCertSn_err:>>>>>>>>>>>", err) | |||
return "", err | |||
} | |||
if aliPayPublicCertSN == "" { | |||
fmt.Println(err) | |||
return "", err | |||
} | |||
client.SetAliPayPublicCertSN(aliPayPublicCertSN) | |||
} | |||
//请求参数 | |||
body := make(gopay.BodyMap) | |||
body.Set("subject", subject) | |||
body.Set("out_trade_no", orderID) | |||
// quit_url is 用户付款中途退出返回商户网站的地址 | |||
body.Set("quit_url", notiURL) | |||
body.Set("total_amount", amount) | |||
// product_code is 销售产品码,商家和支付宝签约的产品码 | |||
body.Set("product_code", "QUICK_WAP_WAY") | |||
//手机网站支付请求 | |||
payUrl, err := client.TradeWapPay(body) | |||
if err != nil { | |||
return "", logx.Warn(err) | |||
} | |||
return payUrl, nil | |||
} | |||
// TradeAppPay is 支付宝小程序本身支付 | |||
func TradeCreate(appID, priKey, subject, orderID, amount, notiURL, RSA, PKCS string, paySet *md.PayData) (*alipay.TradeCreateResponse, error) { | |||
//aliPayPublicKey := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wn1sU/8Q0rYLlZ6sq3enrPZw2ptp6FecHR2bBFLjJ+sKzepROd0bKddgj+Mr1ffr3Ej78mLdWV8IzLfpXUi945DkrQcOUWLY0MHhYVG2jSs/qzFfpzmtut2Cl2TozYpE84zom9ei06u2AXLMBkU6VpznZl+R4qIgnUfByt3Ix5b3h4Cl6gzXMAB1hJrrrCkq+WvWb3Fy0vmk/DUbJEz8i8mQPff2gsHBE1nMPvHVAMw1GMk9ImB4PxucVek4ZbUzVqxZXphaAgUXFK2FSFU+Q+q1SPvHbUsjtIyL+cLA6H/6ybFF9Ffp27Y14AHPw29+243/SpMisbGcj2KD+evBwIDAQAB" | |||
privateKey := priKey | |||
rsa_type := alipay.RSA2 | |||
pkcs_type := alipay.PKCS1 | |||
if RSA == "1" { | |||
rsa_type = alipay.RSA | |||
} | |||
if PKCS == "1" { | |||
pkcs_type = alipay.PKCS8 | |||
} | |||
if paySet.PayAliUseType == "1" { | |||
rsa_type = alipay.RSA2 | |||
pkcs_type = alipay.PKCS8 | |||
} | |||
//初始化支付宝客户端 | |||
// appId:应用ID | |||
// privateKey:应用私钥,支持PKCS1和PKCS8 | |||
// isProd:是否是正式环境 | |||
client := alipay.NewClient(appID, privateKey, true) | |||
//配置公共参数 | |||
client.SetCharset("utf-8"). | |||
SetSignType(rsa_type). | |||
SetPrivateKeyType(pkcs_type). | |||
SetNotifyUrl(notiURL) | |||
if paySet.PayAliUseType == "1" { | |||
appCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAppCertSn) | |||
if err != nil { | |||
fmt.Println(err) | |||
return nil, err | |||
} | |||
if appCertSN == "" { | |||
fmt.Println(err) | |||
return nil, err | |||
} | |||
client.SetAppCertSN(appCertSN) | |||
//aliPayRootCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayRootCertSn) | |||
//if err != nil { | |||
// fmt.Println(err) | |||
// return nil, err | |||
//} | |||
//if aliPayRootCertSN == "" { | |||
// fmt.Println(err) | |||
// return nil, err | |||
//} | |||
aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6" | |||
client.SetAliPayRootCertSN(aliPayRootCertSN) | |||
aliPayPublicCertSN, err := alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayrsaPublicKey) | |||
if err != nil { | |||
fmt.Println(err) | |||
return nil, err | |||
} | |||
if aliPayPublicCertSN == "" { | |||
fmt.Println(err) | |||
return nil, err | |||
} | |||
client.SetAliPayPublicCertSN(aliPayPublicCertSN) | |||
} | |||
//请求参数 | |||
body := make(gopay.BodyMap) | |||
body.Set("subject", subject) | |||
// 支付宝小程序支付时 buyer_id 为必传参数,需要提前获取,获取方法如下两种 | |||
// 1、alipay.SystemOauthToken() 返回取值:rsp.SystemOauthTokenResponse.UserId | |||
// 2、client.SystemOauthToken() 返回取值:aliRsp.SystemOauthTokenResponse.UserId | |||
buyer_id, err := client.SystemOauthToken(body) | |||
if err != nil { | |||
return nil, logx.Warn(err) | |||
} | |||
body.Set("buyer_id", buyer_id) | |||
body.Set("out_trade_no", orderID) | |||
body.Set("total_amount", amount) | |||
//创建订单 | |||
aliRsp, err := client.TradeCreate(body) | |||
if err != nil { | |||
return nil, logx.Warn(err) | |||
} | |||
logx.Warn("aliRsp:", *aliRsp) | |||
logx.Warn("aliRsp.TradeNo:", aliRsp.Response.TradeNo) | |||
return aliRsp, nil | |||
} |
@@ -0,0 +1,39 @@ | |||
package alipay | |||
import ( | |||
"applet/app/db" | |||
"applet/app/utils/cache" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/implement" | |||
"code.fnuoos.com/EggPlanet/egg_system_rules.git/enum" | |||
"errors" | |||
) | |||
func FacePrepareAlipayCode(method string, params map[string]string) (interface{}, error) { | |||
sysCfgDb := implement.NewSysCfgDb(db.Db, cache.GetPool().Get()) | |||
sysCfgMap := sysCfgDb.SysCfgFindWithDb(enum.AlipayAppId, enum.AlipayPrivateKey, enum.AlipayPublicKey, enum.AlipayPublicContentRSA2, enum.AlipayRootContent, enum.AppPublicContent) | |||
// 获取私钥和APPID | |||
var paySet = &PayData{ | |||
AlipayAppId: sysCfgMap[enum.AlipayAppId], | |||
AlipayPrivateKey: sysCfgMap[enum.AlipayPrivateKey], | |||
AlipayPublicKey: sysCfgMap[enum.AlipayPublicKey], | |||
AlipayPublicContentRSA2: sysCfgMap[enum.AlipayPublicContentRSA2], | |||
AlipayRootContent: sysCfgMap[enum.AlipayRootContent], | |||
AppPublicContent: sysCfgMap[enum.AppPublicContent], | |||
} | |||
notifyURL := "http://ddxq.izhim.com/api/v1/callback/alipay/face" | |||
var param interface{} | |||
var err error | |||
switch method { | |||
case "face_init": | |||
param, err = UserCertifyOpenInit(params["name"], params["id_num"], params["oid"], notifyURL, paySet) | |||
case "face_certify": | |||
param, err = UserCertifyOpenCertify(params["certify_id"], notifyURL, paySet) | |||
case "face_query": | |||
param, err = UserCertifyOpenQuery(params["certify_id"], notifyURL, paySet) | |||
default: | |||
return "", errors.New("失败") | |||
} | |||
return param, err | |||
} |
@@ -0,0 +1,228 @@ | |||
package alipay | |||
import ( | |||
"context" | |||
"crypto/rsa" | |||
"crypto/x509" | |||
"encoding/json" | |||
"encoding/pem" | |||
"errors" | |||
"fmt" | |||
"github.com/go-pay/crypto/xrsa" | |||
"github.com/go-pay/gopay" | |||
"github.com/go-pay/gopay/alipay" | |||
"github.com/go-pay/xtime" | |||
"github.com/syyongx/php2go" | |||
"strings" | |||
"time" | |||
) | |||
const ( | |||
// URL | |||
baseUrl = "https://openapi.alipay.com/gateway.do" | |||
sandboxBaseUrl = "https://openapi.alipaydev.com/gateway.do" | |||
baseUrlUtf8 = "https://openapi.alipay.com/gateway.do?charset=utf-8" | |||
sandboxBaseUrlUtf8 = "https://openapi.alipaydev.com/gateway.do?charset=utf-8" | |||
LocationShanghai = "Asia/Shanghai" | |||
PKCS1 PKCSType = 1 | |||
PKCS8 PKCSType = 2 | |||
RSA = "RSA" | |||
RSA2 = "RSA2" | |||
) | |||
type PKCSType uint8 | |||
type UserCertifyOpenInitData struct { | |||
AlipayUserCertifyOpenInitializeResponse struct { | |||
CertifyID interface{} `json:"certify_id"` | |||
Code interface{} `json:"code"` | |||
Msg interface{} `json:"msg"` | |||
} `json:"alipay_user_certify_open_initialize_response"` | |||
} | |||
type UserCertifyOpenQueryData struct { | |||
AlipayUserCertifyOpenQueryResponse struct { | |||
Code string `json:"code"` | |||
FailReason string `json:"fail_reason"` | |||
IdentityInfo string `json:"identity_info"` | |||
MaterialInfo string `json:"material_info"` | |||
Msg string `json:"msg"` | |||
Passed interface{} `json:"passed"` | |||
} `json:"alipay_user_certify_open_query_response"` | |||
Sign string `json:"sign"` | |||
} | |||
func commClient(notiURL string, paySet *PayData) (*alipay.Client, error) { | |||
client, _ := alipay.NewClient(paySet.AlipayAppId, paySet.AlipayPrivateKey, true) | |||
client.DebugSwitch = gopay.DebugOn | |||
//配置公共参数 | |||
client.SetCharset("utf-8"). | |||
SetNotifyUrl(notiURL) | |||
client.AutoVerifySign([]byte(paySet.AlipayPublicContentRSA2)) | |||
// 传入证书内容 | |||
err := client.SetCertSnByContent([]byte(paySet.AppPublicContent), []byte(paySet.AlipayRootContent), []byte(paySet.AlipayPublicContentRSA2)) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return client, nil | |||
} | |||
// UserCertifyOpenInit is 支付宝APP支身份认证初始化服务 | |||
// alipay.user.certify.open.initialize | |||
func UserCertifyOpenInit(realName, identityNum, orderID, notiURL string, paySet *PayData) (UserCertifyOpenInitData, error) { | |||
var param = UserCertifyOpenInitData{} | |||
//初始化支付宝客户端 | |||
// appID 是在支付宝申请的APPID | |||
// priKey 是支付宝私钥 | |||
// realName 是姓名 | |||
// identityNum 是身份证 | |||
// orderID 是智莺这边生成的订单id | |||
// notiURL 通知地址url | |||
// passback_params 回调通知参数 | |||
client, _ := commClient(notiURL, paySet) | |||
fmt.Println(client) | |||
merchantConfig := map[string]string{ | |||
"return_url": notiURL, | |||
} | |||
identityParam := map[string]string{ | |||
"identity_type": "CERT_INFO", | |||
"cert_type": "IDENTITY_CARD", | |||
"cert_name": realName, | |||
"cert_no": identityNum, | |||
} | |||
var bizContent = map[string]interface{}{ | |||
"biz_code": "FACE", | |||
"merchant_config": merchantConfig, | |||
"identity_param": identityParam, | |||
"outer_order_no": orderID, | |||
} | |||
//请求参数 | |||
bizContentJson, _ := json.Marshal(bizContent) | |||
bizContentStr := strings.ReplaceAll(string(bizContentJson), "\\u0026", "&") | |||
body := make(gopay.BodyMap) | |||
body.Set("biz_content", bizContentStr) | |||
err := client.PostAliPayAPISelfV2(context.Background(), body, "alipay.user.certify.open.initialize", ¶m) | |||
if err != nil { | |||
return param, err | |||
} | |||
return param, nil | |||
} | |||
// UserCertifyOpenQuery is 身份认证记录查询 | |||
// alipay.user.certify.open.query | |||
func UserCertifyOpenQuery(certifyId, notiURL string, paySet *PayData) (UserCertifyOpenQueryData, error) { | |||
var param = UserCertifyOpenQueryData{} | |||
//初始化支付宝客户端 | |||
// appID 是在支付宝申请的APPID | |||
// priKey 是支付宝私钥 | |||
// certifyId 是认证id 初始化获得 | |||
// notiURL 通知地址url | |||
// passback_params 回调通知参数 | |||
client, _ := commClient(notiURL, paySet) | |||
fmt.Println(client) | |||
var bizContent = map[string]interface{}{ | |||
"certify_id": certifyId, | |||
} | |||
//请求参数 | |||
bizContentJson, _ := json.Marshal(bizContent) | |||
bizContentStr := strings.ReplaceAll(string(bizContentJson), "\\u0026", "&") | |||
body := make(gopay.BodyMap) | |||
body.Set("biz_content", bizContentStr) | |||
//body.Set("timeout_express", "30m") | |||
err := client.PostAliPayAPISelfV2(context.Background(), body, "alipay.user.certify.open.query", ¶m) | |||
if err != nil { | |||
return param, err | |||
} | |||
return param, nil | |||
} | |||
// UserCertifyOpenCertify is 支付宝APP身份认证开始认证 | |||
// alipay.user.certify.open.initialize | |||
func UserCertifyOpenCertify(certifyId, notiURL string, paySet *PayData) (string, error) { | |||
//初始化支付宝客户端 | |||
// appID 是在支付宝申请的APPID | |||
// priKey 是支付宝私钥 | |||
// certifyId 是认证id 初始化获得 | |||
// orderID 是智莺这边生成的订单id | |||
// notiURL 通知地址url | |||
// passback_params 回调通知参数 | |||
client, _ := commClient(notiURL, paySet) | |||
fmt.Println(client) | |||
var bizContent = map[string]interface{}{ | |||
"certify_id": certifyId, | |||
} | |||
//请求参数 | |||
bizContentJson, _ := json.Marshal(bizContent) | |||
bizContentStr := strings.ReplaceAll(string(bizContentJson), "\\u0026", "&") | |||
body := make(gopay.BodyMap) | |||
body.Set("biz_content", bizContentStr) | |||
body.Set("method", "alipay.user.certify.open.certify") | |||
body = checkPublicParam(client, body) | |||
key := xrsa.FormatAlipayPrivateKey(paySet.AlipayPrivateKey) | |||
var block *pem.Block | |||
if block, _ = pem.Decode([]byte(key)); block == nil { | |||
return "", errors.New("获取失败") | |||
} | |||
pkcs8Key, err := x509.ParsePKCS8PrivateKey(block.Bytes) | |||
if err != nil { | |||
return "", errors.New("获取失败") | |||
} | |||
pk8, ok := pkcs8Key.(*rsa.PrivateKey) | |||
if !ok { | |||
return "", errors.New("获取失败") | |||
} | |||
keys := pk8 | |||
sign, err := alipay.GetRsaSign(body, body.GetString("sign_type"), keys) | |||
if err != nil { | |||
return "", fmt.Errorf("GetRsaSign Error: %v", err) | |||
} | |||
body.Set("sign", sign) | |||
var str = "https://openapi.alipay.com/gateway.do" | |||
for k, v := range body { | |||
if strings.Contains(str, "?") == false { | |||
str += "?" + k + "=" + php2go.URLEncode(v.(string)) | |||
} else { | |||
str += "&" + k + "=" + php2go.URLEncode(v.(string)) | |||
} | |||
} | |||
return str, nil | |||
} | |||
// 公共参数检查 | |||
func checkPublicParam(a *alipay.Client, bm gopay.BodyMap) gopay.BodyMap { | |||
bm.Set("format", "JSON") | |||
if bm.GetString("app_id") == "" && a.AppId != "" { | |||
bm.Set("app_id", a.AppId) | |||
} | |||
if bm.GetString("app_cert_sn") == "" && a.AppCertSN != "" { | |||
bm.Set("app_cert_sn", a.AppCertSN) | |||
} | |||
if bm.GetString("alipay_root_cert_sn") == "" && a.AliPayRootCertSN != "" { | |||
bm.Set("alipay_root_cert_sn", a.AliPayRootCertSN) | |||
} | |||
if bm.GetString("return_url") == "" && a.ReturnUrl != "" { | |||
bm.Set("return_url", a.ReturnUrl) | |||
} | |||
bm.Set("charset", "utf-8") | |||
if bm.GetString("charset") == "" && a.Charset != "" { | |||
bm.Set("charset", a.Charset) | |||
} | |||
bm.Set("sign_type", RSA2) | |||
if bm.GetString("sign_type") == "" && a.SignType != "" { | |||
bm.Set("sign_type", a.SignType) | |||
} | |||
bm.Set("timestamp", time.Now().Format(xtime.TimeLayout)) | |||
bm.Set("version", "1.0") | |||
if bm.GetString("notify_url") == "" && a.NotifyUrl != "" { | |||
bm.Set("notify_url", a.NotifyUrl) | |||
} | |||
if bm.GetString("app_auth_token") == "" && a.AppAuthToken != "" { | |||
bm.Set("app_auth_token", a.AppAuthToken) | |||
} | |||
return bm | |||
} |
@@ -0,0 +1,10 @@ | |||
package alipay | |||
type PayData struct { | |||
AlipayAppId string `json:"alipay_app_id" label:"支付宝商家应用appid"` | |||
AlipayPrivateKey string `json:"alipay_private_key" label:"支付宝商家应用私钥"` | |||
AlipayPublicKey string `json:"alipay_public_key" label:"支付宝商家应用公钥"` | |||
AlipayPublicContentRSA2 string `json:"alipay_public_content_rsa_2" label:"支付宝公钥证书"` | |||
AlipayRootContent string `json:"alipay_root_content" label:"支付宝根证书"` | |||
AppPublicContent string `json:"app_public_content" label:"应用公钥证书"` | |||
} |
@@ -9,6 +9,7 @@ type ConfigResp struct { | |||
PrivacyUrl string `json:"privacy_url" example:"隐私协议链接"` | |||
OssUrl string `json:"oss_url" example:"阿里云图片链接"` | |||
Guide []Guide `json:"guide"` | |||
DownUrl string `json:"down_url"` | |||
} | |||
type VersionResp struct { | |||
Version []Version `json:"version"` | |||
@@ -0,0 +1,28 @@ | |||
package md | |||
type RealNameAuthBasicData struct { | |||
AuthState string `json:"auth_state" example:"0未审核 1通过 2拒绝"` | |||
} | |||
type RealNameAuthAddRequest struct { | |||
RealName string `json:"real_name"` | |||
CardNo string `json:"card_no"` | |||
} | |||
type UserCertifyRequest struct { | |||
OrderId string `json:"order_id"` //支付订单 | |||
RealName string `json:"real_name" ` | |||
IdentityNum string `json:"identity_num" ` | |||
CertifyId string `json:"certify_id"` | |||
Uid string `json:"uid"` | |||
} | |||
type UserCertifyParams struct { | |||
RealName string `json:"real_name" ` | |||
IdentityNum string `json:"identity_num" ` | |||
OrdId string `json:"ord_id"` | |||
CertifyId string `json:"certify_id"` | |||
Uid string `json:"uid"` | |||
} | |||
type RealNameAuthResp struct { | |||
Oid string `json:"oid"` | |||
Url string `json:"url"` | |||
} |
@@ -56,6 +56,7 @@ func route(r *gin.RouterGroup) { | |||
r.GET("/article/html", hdl.ArticleHtml) //H5渲染的文章 | |||
rCallback := r.Group("/callback") | |||
{ | |||
rCallback.Any("/alipay/face", hdl.CallbackAlipayFace) //支付宝实名回调 | |||
rCallback.GET("/advertising/chuanshanjia", hdl.CallbackChuanshanjia) //穿山甲广告回调 | |||
rCallback.GET("/advertising/youlianghui", hdl.CallbackYoulianghui) //优量汇广告回调 | |||
} | |||
@@ -78,6 +79,8 @@ func route(r *gin.RouterGroup) { | |||
r.POST("/findPassword", hdl.FindPassword) //找回密码 | |||
r.POST("/inviteCode/userInfo", hdl.InviteCodeUserInfo) //邀请码查用户 | |||
} | |||
r.POST("/college/detail", hdl.CollegeDetail) // 文章详情 | |||
r.GET("/getModuleSetting", hdl.GetModuleSetting) // 获取页面样式 | |||
r.Use(mw.Auth) // 以下接口需要JWT验证 | |||
rComm(r.Group("/comm")) | |||
@@ -134,11 +137,11 @@ func route(r *gin.RouterGroup) { | |||
rWithdraw.GET("/index", hdl.WithdrawGetAmount) | |||
} | |||
} | |||
rCollege := r.Group("/college") //学院 | |||
{ | |||
rCollege.GET("/cate", hdl.CollegeCate) // 分类 | |||
rCollege.POST("/list", hdl.CollegeList) // 文章 | |||
rCollege.POST("/detail", hdl.CollegeDetail) // 文章详情 | |||
rCollege.POST("/like/add", hdl.CollegeLikeAdd) // 文章点赞 | |||
rCollege.POST("/like/cancel", hdl.CollegeLikeCancel) // 文章取消点赞 | |||
rCollege.POST("/share/add", hdl.CollegeShareAdd) // 文章分享记录数量 | |||
@@ -163,6 +166,11 @@ func route(r *gin.RouterGroup) { | |||
rIm.POST("/user/grabRedPackage", hdl.GrabRedPackage) // IM-领取红包 | |||
rIm.GET("/redPackageDetail", hdl.RedPackageDetail) // IM-红包详情 | |||
} | |||
rFaceRealName := r.Group("/faceRealName") // 实名认证 | |||
{ | |||
rFaceRealName.GET("/base", hdl.GetRealNameAuthBase) //实名认证基础 | |||
rFaceRealName.POST("/save", hdl.RealNameSave) | |||
} | |||
} | |||
func rComm(r *gin.RouterGroup) { | |||
@@ -7,6 +7,7 @@ import ( | |||
"applet/app/utils" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/implement" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/model" | |||
"fmt" | |||
"github.com/gin-gonic/gin" | |||
"time" | |||
) | |||
@@ -59,7 +60,7 @@ func CollegeList(c *gin.Context) { | |||
e.OutSuc(c, data, nil) | |||
return | |||
} | |||
func CollegeDetail(c *gin.Context) { | |||
func CollegeDetail(c *gin.Context, uid int) { | |||
eg := db.Db | |||
var req md.CollegeDetailReq | |||
err := c.ShouldBindJSON(&req) | |||
@@ -69,14 +70,13 @@ func CollegeDetail(c *gin.Context) { | |||
e.OutErr(c, err1.Code, err1.Error()) | |||
return | |||
} | |||
user := GetUser(c) | |||
NewArticleDb := implement.NewArticleDb(eg) | |||
article, _ := NewArticleDb.GetArticle(req.Id) | |||
data := md.CollegeDetailResp{} | |||
if article != nil { | |||
data = md.CollegeDetailResp{ | |||
Id: utils.IntToStr(article.Id), | |||
Url: "", | |||
Url: fmt.Sprintf("%s%s?article_id=%s", GetSysCfgStr("wap_host"), "/api/v1/article/html", utils.AnyToString(article.Id)), | |||
Title: article.Title, | |||
Content: article.Content, | |||
IsLike: "0", | |||
@@ -85,7 +85,7 @@ func CollegeDetail(c *gin.Context) { | |||
LikeCount: NumFormat(article.LikeCount), | |||
ForwardCount: NumFormat(article.ForwardCount), | |||
} | |||
count, _ := eg.Where("uid=? and article_id=?", user.Id, article.Id).Count(&model.ArticleUserLike{}) | |||
count, _ := eg.Where("uid=? and article_id=?", uid, article.Id).Count(&model.ArticleUserLike{}) | |||
if count > 0 { | |||
data.IsLike = "1" | |||
} | |||
@@ -0,0 +1,261 @@ | |||
package svc | |||
import ( | |||
"applet/app/db" | |||
"applet/app/e" | |||
"applet/app/lib/alipay" | |||
"applet/app/md" | |||
"applet/app/utils" | |||
"applet/app/utils/cache" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/implement" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/model" | |||
"encoding/json" | |||
"fmt" | |||
"github.com/gin-gonic/gin" | |||
"time" | |||
) | |||
func GetRealNameAuthBase(c *gin.Context) { | |||
var res = &md.RealNameAuthBasicData{ | |||
AuthState: "0", | |||
} | |||
res.AuthState = "0" | |||
//判断审核状态 | |||
eg := db.Db | |||
user := GetUser(c) | |||
NewUserRealNameAuthDb := implement.NewUserRealNameAuthDb(eg) | |||
list, _ := NewUserRealNameAuthDb.GetRealNameAuthByUid(utils.Int64ToStr(user.Id)) | |||
if list != nil { | |||
//如果是审核中的订单,判断是否人脸识别 调用人脸识别获取结果 | |||
if list.State == 0 && list.CertifyId != "" { | |||
state, _, _, err := GetCertifyQuery(c, utils.Int64ToStr(user.Id)) | |||
if err == nil { | |||
list.State = state | |||
} | |||
} | |||
res.AuthState = utils.IntToStr(list.State + 1) | |||
if list.State == 0 { //人脸识别 支付了但是没扫脸的情况 设置成没审核状态 | |||
res.AuthState = "0" | |||
} | |||
if list.IsPay == 0 { | |||
res.AuthState = "0" | |||
} | |||
} | |||
e.OutSuc(c, res, nil) | |||
return | |||
} | |||
func RealNameSave(c *gin.Context) { | |||
var args md.RealNameAuthAddRequest | |||
if err := c.ShouldBindJSON(&args); err != nil { | |||
e.OutErr(c, e.ERR_INVALID_ARGS, err) | |||
return | |||
} | |||
eg := db.Db | |||
user := GetUser(c) | |||
NewUserRealNameAuthDb := implement.NewUserRealNameAuthDb(eg) | |||
realData, _ := NewUserRealNameAuthDb.GetRealNameAuthByUidWithState(utils.Int64ToStr(user.Id), "1") | |||
if realData != nil { | |||
e.OutErr(c, 400, e.NewErr(400, "您已审核通过")) | |||
return | |||
} | |||
//判断该身份证被多少个人绑定过 | |||
count, _ := NewUserRealNameAuthDb.GetRealNameAuthCount(int(user.Id), args.CardNo) | |||
if count > 0 { | |||
e.OutErr(c, 400, e.NewErr(400, "该身份证已被绑定,绑定失败")) | |||
return | |||
} | |||
// 加锁 防止并发提取 | |||
mutexKey := fmt.Sprintf("realname:%s", utils.Int64ToStr(user.Id)) | |||
withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX") | |||
if err != nil { | |||
e.OutErr(c, 400, e.NewErr(400, "请稍后再试")) | |||
return | |||
} | |||
if withdrawAvailable != "OK" { | |||
e.OutErr(c, 400, e.NewErr(400000, "请稍后再试")) | |||
return | |||
} | |||
//调用初始化认证接口 | |||
leave := 17 - len(utils.Int64ToStr(user.Id)) | |||
outerOrderNo := "Egg" + utils.Int64ToStr(user.Id) + "T" + utils.Int64ToStr(time.Now().Unix()) + utils.RandPow(leave) | |||
var tmp = &model.UserRealNameAuth{ | |||
Uid: int(user.Id), | |||
RealName: args.RealName, | |||
CardNo: args.CardNo, | |||
Amount: utils.StrToFloat64(GetSysCfgStr("user_real_name_money")), | |||
AuditType: 1, | |||
UpdateTime: time.Now(), | |||
Oid: outerOrderNo, | |||
} | |||
isNeedPay := "1" | |||
list, _ := NewUserRealNameAuthDb.GetRealNameAuthByUid(utils.Int64ToStr(user.Id)) | |||
if list != nil { | |||
if args.RealName != list.RealName || args.CardNo != list.CardNo || list.AlipayOid == "" { | |||
list.AlipayOid = outerOrderNo | |||
list.CertifyId = "" | |||
} | |||
if list.IsPay != 1 && list.IsPay != 5 { | |||
//没付款的话,更新下订单号 | |||
list.Oid = outerOrderNo | |||
list.Amount = utils.StrToFloat64(GetSysCfgStr("user_real_name_money")) | |||
} | |||
if list.IsPay != 1 && utils.InArr(utils.IntToStr(tmp.IsPay), []string{"5", "6"}) { | |||
list.IsPay = tmp.IsPay | |||
list.Amount = 0 | |||
} | |||
if list.IsPay == 1 { | |||
isNeedPay = "0" | |||
} | |||
if list.State != 1 { | |||
list.State = 0 | |||
} | |||
if args.RealName != "" { | |||
list.RealName = args.RealName | |||
} | |||
if args.CardNo != "" { | |||
list.CardNo = args.CardNo | |||
} | |||
list.UpdateTime = time.Now() | |||
eg.Where("id=?", list.Id).Update(list) | |||
} else { | |||
tmp.CreateTime = time.Now() | |||
tmp.AlipayOid = outerOrderNo | |||
db.InsertComm(eg, tmp) | |||
list = tmp | |||
} | |||
//TODO 扣钱 自动用能量值抵扣 | |||
if isNeedPay == "1" { | |||
list.IsPay = 1 | |||
eg.Where("id=?", list.Id).Update(list) | |||
} | |||
//调用初始化认证接口 | |||
certifyID := list.CertifyId | |||
if certifyID != "" && list.State != 1 { | |||
c.Set("is_check", "1") | |||
state, _, _, _ := GetCertifyQuery(c, utils.Int64ToStr(user.Id)) | |||
if state == 1 { | |||
e.OutErr(c, 400, e.NewErr(400, "已实名")) | |||
return | |||
} | |||
} | |||
var url = "" | |||
if certifyID == "" || list.State == 2 || list.CreateTime.Unix() < time.Now().Unix()-20*3600 { | |||
var param = &md.UserCertifyRequest{ | |||
OrderId: outerOrderNo, | |||
RealName: list.RealName, | |||
IdentityNum: list.CardNo, | |||
Uid: utils.Int64ToStr(user.Id), | |||
} | |||
data, _ := AliFace(c, param) | |||
fmt.Println(data) | |||
tmpId, ok := data.AlipayUserCertifyOpenInitializeResponse.CertifyID.(string) | |||
if ok { | |||
certifyID = tmpId | |||
} | |||
} else { | |||
if list.AlipayOid != "" && list.State != 2 { | |||
outerOrderNo = list.AlipayOid | |||
} | |||
} | |||
//调用认证接口获取链接 | |||
if certifyID != "" { | |||
var param = &md.UserCertifyRequest{CertifyId: certifyID, Uid: utils.Int64ToStr(user.Id)} | |||
url, _ = AliFaceCheck(c, param) | |||
list.CertifyId = certifyID | |||
list.AlipayOid = outerOrderNo | |||
eg.Where("id=?", list.Id).Update(list) | |||
} | |||
e.OutSuc(c, md.RealNameAuthResp{Oid: outerOrderNo, Url: url}, nil) | |||
return | |||
} | |||
func AliFace(c *gin.Context, pay *md.UserCertifyRequest) (alipay.UserCertifyOpenInitData, error) { | |||
orderId := pay.OrderId //支付单号 | |||
payParams := map[string]string{ | |||
"oid": orderId, | |||
"name": pay.RealName, | |||
"id_num": pay.IdentityNum, | |||
} | |||
var data = alipay.UserCertifyOpenInitData{} | |||
r, err := alipay.FacePrepareAlipayCode("face_init", payParams) | |||
if err != nil { | |||
return data, err | |||
} | |||
tmp, ok := r.(alipay.UserCertifyOpenInitData) | |||
if ok { | |||
data = tmp | |||
} | |||
return data, nil | |||
} | |||
func AliFaceCheck(c *gin.Context, pay *md.UserCertifyRequest) (string, error) { | |||
payParams := map[string]string{ | |||
"certify_id": pay.CertifyId, | |||
} | |||
var data = "" | |||
r, err := alipay.FacePrepareAlipayCode("face_certify", payParams) | |||
utils.FilePutContents("face", utils.SerializeStr(r)) | |||
utils.FilePutContents("face", utils.SerializeStr(err)) | |||
if err != nil { | |||
return "", err | |||
} | |||
tmp, ok := r.(string) | |||
if ok { | |||
data = tmp | |||
} | |||
return data, nil | |||
} | |||
func GetCertifyQuery(c *gin.Context, uid string) (int, int, string, error) { | |||
eg := db.Db | |||
NewUserRealNameAuthDb := implement.NewUserRealNameAuthDb(eg) | |||
realNameAuth, _ := NewUserRealNameAuthDb.GetRealNameAuth(utils.StrToInt(uid)) | |||
if realNameAuth == nil { | |||
return 0, 2, "未支付金额,认证失败", e.NewErr(400, "未支付金额,认证失败") | |||
} | |||
if realNameAuth.CertifyId == "" { | |||
return 0, 2, "校验失败", e.NewErr(400, "校验失败") | |||
} | |||
var param = &md.UserCertifyRequest{CertifyId: realNameAuth.CertifyId} | |||
data, _ := AliFaceQuery(c, param) | |||
isTrueStr := "" | |||
tmpData, ok := data.AlipayUserCertifyOpenQueryResponse.Passed.(string) | |||
if ok { | |||
isTrueStr = tmpData | |||
} | |||
tmpData1, ok := data.AlipayUserCertifyOpenQueryResponse.Passed.([]string) | |||
if ok { | |||
if len(tmpData1) > 0 { | |||
isTrueStr = tmpData1[0] | |||
} | |||
} | |||
fmt.Println(isTrueStr) | |||
msg, _ := json.Marshal(data) | |||
realNameAuth.Msg = string(msg) | |||
if isTrueStr == "T" { | |||
realNameAuth.State = 1 | |||
eg.Where("id=?", realNameAuth.Id).Update(realNameAuth) | |||
} else if realNameAuth.State != 1 && isTrueStr == "F" && c.GetString("is_check") != "1" { | |||
realNameAuth.State = 2 | |||
eg.Where("id=?", realNameAuth.Id).Update(realNameAuth) | |||
} | |||
return realNameAuth.State, realNameAuth.State, realNameAuth.Msg, nil | |||
} | |||
func AliFaceQuery(c *gin.Context, pay *md.UserCertifyRequest) (alipay.UserCertifyOpenQueryData, error) { | |||
payParams := map[string]string{ | |||
"certify_id": pay.CertifyId, | |||
} | |||
var data = alipay.UserCertifyOpenQueryData{} | |||
r, err := alipay.FacePrepareAlipayCode("face_query", payParams) | |||
utils.FilePutContents("face", utils.SerializeStr(payParams)) | |||
utils.FilePutContents("face", utils.SerializeStr(r)) | |||
utils.FilePutContents("face", utils.SerializeStr(err)) | |||
if err != nil { | |||
return data, err | |||
} | |||
tmp, ok := r.(alipay.UserCertifyOpenQueryData) | |||
if ok { | |||
data = tmp | |||
} | |||
return data, nil | |||
} |
@@ -3,9 +3,11 @@ package utils | |||
import ( | |||
"fmt" | |||
"github.com/syyongx/php2go" | |||
"math/rand" | |||
"reflect" | |||
"sort" | |||
"strings" | |||
"time" | |||
) | |||
func Implode(glue string, args ...interface{}) string { | |||
@@ -25,6 +27,19 @@ func InArr(target string, str_array []string) bool { | |||
} | |||
return false | |||
} | |||
func RandPow(l int) string { | |||
var i = "1" | |||
for j := 0; j < l; j++ { | |||
i += "0" | |||
} | |||
k := StrToInt64(i) | |||
n := rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(k) | |||
ls := "%0" + IntToStr(l) + "v" | |||
str := fmt.Sprintf(ls, n) | |||
//min := int(math.Pow10(l - 1)) | |||
//max := int(math.Pow10(l) - 1) | |||
return str | |||
} | |||
// 把数组的值放到key里 | |||
func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) { | |||
@@ -32,12 +32,16 @@ require ( | |||
) | |||
require ( | |||
code.fnuoos.com/EggPlanet/egg_models.git v0.2.1-0.20241128030209-743f36ef9dad | |||
code.fnuoos.com/EggPlanet/egg_models.git v0.2.1-0.20241128110636-bdf6315267cb | |||
code.fnuoos.com/EggPlanet/egg_system_rules.git v0.0.4-0.20241128075251-3c7f4a91e52c | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_es.git v1.0.1-0.20241118083738-0f22da9ba0be | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.5 | |||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible | |||
github.com/gin-contrib/sessions v1.0.1 | |||
github.com/go-pay/crypto v0.0.1 | |||
github.com/go-pay/gopay v1.5.98 | |||
github.com/go-pay/util v0.0.4 | |||
github.com/go-pay/xtime v0.0.2 | |||
github.com/go-sql-driver/mysql v1.8.1 | |||
github.com/gocolly/colly v1.2.0 | |||
github.com/google/uuid v1.3.0 | |||
@@ -112,14 +116,14 @@ require ( | |||
go.uber.org/atomic v1.7.0 // indirect | |||
go.uber.org/multierr v1.6.0 // indirect | |||
golang.org/x/arch v0.7.0 // indirect | |||
golang.org/x/crypto v0.22.0 // indirect | |||
golang.org/x/crypto v0.23.0 // indirect | |||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect | |||
golang.org/x/net v0.24.0 // indirect | |||
golang.org/x/net v0.25.0 // indirect | |||
golang.org/x/sync v0.8.0 // indirect | |||
golang.org/x/sys v0.26.0 // indirect | |||
golang.org/x/text v0.15.0 // indirect | |||
golang.org/x/text v0.18.0 // indirect | |||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect | |||
golang.org/x/tools v0.20.0 // indirect | |||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect | |||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect | |||
google.golang.org/appengine v1.4.0 // indirect | |||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 // indirect | |||