新增微信公众平台对接
This commit is contained in:
parent
b58489a053
commit
b4039aab81
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,4 +14,5 @@
|
||||
*.log
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
# vendor/
|
||||
.DS_Store/
|
||||
BIN
api/.DS_Store
vendored
Normal file
BIN
api/.DS_Store
vendored
Normal file
Binary file not shown.
@ -10,4 +10,5 @@ type Api struct {
|
||||
// version1 v1版本
|
||||
type version1 struct {
|
||||
UserDoctor v1.UserDoctor // 角色数据
|
||||
WeChat v1.WeChat // 微信数据
|
||||
}
|
||||
|
||||
79
api/controller/v1/weChat.go
Normal file
79
api/controller/v1/weChat.go
Normal file
@ -0,0 +1,79 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
v1 "hospital-open-api/api/requests/v1"
|
||||
"hospital-open-api/api/responses"
|
||||
"hospital-open-api/config"
|
||||
"hospital-open-api/extend/weChat/Scheme"
|
||||
"hospital-open-api/global"
|
||||
"hospital-open-api/utils"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type WeChat struct{}
|
||||
|
||||
// GetScheme 获取页面加密scheme码
|
||||
func (r *WeChat) GetScheme(c *gin.Context) {
|
||||
WeChatRequest := v1.WeChatRequest{}
|
||||
req := WeChatRequest.GetScheme
|
||||
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := global.Validate.Struct(req); err != nil {
|
||||
responses.FailWithMessage(utils.Translate(err), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证path参数
|
||||
if strings.Count(req.Path, "/") != 3 || !strings.HasPrefix(req.Path, "/") || strings.HasSuffix(req.Path, "/") {
|
||||
responses.FailWithMessage("path格式错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 验证query参数
|
||||
// 定义正则表达式,匹配 k1=v1&k2=v2 这种格式
|
||||
pattern := `^([a-zA-Z0-9_-]+=[a-zA-Z0-9_-]+&)*([a-zA-Z0-9_-]+=[a-zA-Z0-9_-]+)$`
|
||||
reg := regexp.MustCompile(pattern)
|
||||
res := reg.MatchString(req.Query)
|
||||
if !res {
|
||||
responses.FailWithMessage("query格式错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断环境
|
||||
envVersion := "trial"
|
||||
if config.C.Env == "prod" {
|
||||
envVersion = "release"
|
||||
}
|
||||
|
||||
fmt.Println(req.Query)
|
||||
|
||||
// 构建请求数据
|
||||
JumpWxaData := &Scheme.GetSchemeJumpWxaRequest{
|
||||
Path: req.Path,
|
||||
Query: req.Query,
|
||||
EnvVersion: envVersion,
|
||||
}
|
||||
|
||||
GetSchemeRequest := &Scheme.GetSchemeRequest{
|
||||
JumpWxa: JumpWxaData,
|
||||
ExpireType: 1,
|
||||
ExpireTime: 0,
|
||||
ExpireInterval: req.ExpireInterval,
|
||||
}
|
||||
|
||||
openLink, err := GetSchemeRequest.GetScheme(1)
|
||||
if err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
responses.OkWithData(openLink, c)
|
||||
}
|
||||
12
api/requests/v1/WeChat.go
Normal file
12
api/requests/v1/WeChat.go
Normal file
@ -0,0 +1,12 @@
|
||||
package v1
|
||||
|
||||
type WeChatRequest struct {
|
||||
GetScheme // 获取页面加密scheme码
|
||||
}
|
||||
|
||||
// GetScheme 获取页面加密scheme码
|
||||
type GetScheme struct {
|
||||
Path string `json:"path" form:"path" validate:"required" label:"页面路径"`
|
||||
Query string `json:"query" form:"query" validate:"required" label:"参数"`
|
||||
ExpireInterval int `json:"expire_interval" form:"expire_interval" validate:"required" label:"有效天数"`
|
||||
}
|
||||
@ -80,8 +80,10 @@ func basicRouter(r *gin.Engine, api controller.Api) {
|
||||
func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
v1Group := r.Group("/v1")
|
||||
{
|
||||
// 用户
|
||||
userGroup := v1Group.Group("/user")
|
||||
{
|
||||
// 医生
|
||||
doctorGroup := userGroup.Group("/doctor")
|
||||
{
|
||||
// 获取医生详情
|
||||
@ -91,5 +93,12 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
||||
doctorGroup.GET("/multi", api.V1.UserDoctor.GetMultiDoctor)
|
||||
}
|
||||
}
|
||||
|
||||
// 微信
|
||||
wechatGroup := v1Group.Group("/wechat")
|
||||
{
|
||||
// 生成页面加密scheme码
|
||||
wechatGroup.POST("/scheme", api.V1.WeChat.GetScheme)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
78
extend/weChat/Scheme/Scheme.go
Normal file
78
extend/weChat/Scheme/Scheme.go
Normal file
@ -0,0 +1,78 @@
|
||||
package Scheme
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hospital-open-api/extend/weChat"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetSchemeJumpWxaRequest 跳转到的目标小程序信息
|
||||
type GetSchemeJumpWxaRequest struct {
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
// envVersion 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"
|
||||
EnvVersion string `json:"env_version"`
|
||||
}
|
||||
|
||||
// GetSchemeRequest 请求参数
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/url-scheme/urlscheme.generate.html#请求参数
|
||||
type GetSchemeRequest struct {
|
||||
JumpWxa *GetSchemeJumpWxaRequest `json:"jump_wxa"`
|
||||
ExpireType int `json:"expire_type"`
|
||||
ExpireTime int64 `json:"expire_time"`
|
||||
ExpireInterval int `json:"expire_interval"`
|
||||
}
|
||||
|
||||
// GetSchemeResponse 获取加密scheme码返回数据
|
||||
type GetSchemeResponse struct {
|
||||
OpenLink string `json:"openlink"`
|
||||
|
||||
weChat.CommonError
|
||||
}
|
||||
|
||||
// GetScheme 获取加密scheme码
|
||||
func (r *GetSchemeRequest) GetScheme(userType int) (string, error) {
|
||||
// 初始化配置
|
||||
weChatConfig := weChat.GetConfig(userType)
|
||||
|
||||
// 获取token
|
||||
accessToken, err := weChatConfig.GetAccessToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s?access_token=%s", "https://api.weixin.qq.com/wxa/generatescheme", accessToken)
|
||||
|
||||
// 将请求数据转换为 JSON
|
||||
requestBody, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 去除json的转义
|
||||
requestBody = []byte(strings.Replace(string(requestBody), "\\u0026", "&", -1))
|
||||
|
||||
body, err := weChat.PostRequest(url, requestBody)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
}
|
||||
|
||||
var GetSchemeResponse GetSchemeResponse
|
||||
err = json.Unmarshal(body, &GetSchemeResponse)
|
||||
if err != nil {
|
||||
// json解析失败
|
||||
return "", err
|
||||
}
|
||||
|
||||
if GetSchemeResponse.ErrCode != 0 || GetSchemeResponse.ErrMsg != "ok" {
|
||||
return "", errors.New(GetSchemeResponse.ErrMsg)
|
||||
}
|
||||
|
||||
if GetSchemeResponse.OpenLink == "" {
|
||||
return "", errors.New("失败")
|
||||
}
|
||||
|
||||
return GetSchemeResponse.OpenLink, nil
|
||||
}
|
||||
1
extend/weChat/WeChat.go
Normal file
1
extend/weChat/WeChat.go
Normal file
@ -0,0 +1 @@
|
||||
package weChat
|
||||
149
extend/weChat/base.go
Normal file
149
extend/weChat/base.go
Normal file
@ -0,0 +1,149 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/leeqvip/gophp"
|
||||
"hospital-open-api/config"
|
||||
"hospital-open-api/global"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CommonError 微信返回的通用错误 json
|
||||
type CommonError struct {
|
||||
ErrCode int64 `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
type GetAccessTokenResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int64 `json:"expires_in"`
|
||||
|
||||
CommonError
|
||||
}
|
||||
|
||||
type WeChatConfig struct {
|
||||
AppId string `json:"app_id"`
|
||||
AppSecret string `json:"app_secret"`
|
||||
}
|
||||
|
||||
// GetConfig 初始化配置
|
||||
func GetConfig(userType int) *WeChatConfig {
|
||||
weChatConfig := &WeChatConfig{}
|
||||
if userType == 1 {
|
||||
// 患者
|
||||
weChatConfig.AppId = config.C.Wechat.PatientAppId
|
||||
weChatConfig.AppSecret = config.C.Wechat.PatientAppSecret
|
||||
} else if userType == 2 {
|
||||
// 医生/药师
|
||||
weChatConfig.AppId = config.C.Wechat.DoctorAppId
|
||||
weChatConfig.AppSecret = config.C.Wechat.DoctorAppSecret
|
||||
}
|
||||
|
||||
return weChatConfig
|
||||
}
|
||||
|
||||
// GetAccessToken 获取access_token
|
||||
func (c WeChatConfig) GetAccessToken() (string, error) {
|
||||
// 检测缓存是否存在access_token
|
||||
redisKey := "c:official_account.access_token." + c.AppId + "." + c.AppSecret
|
||||
accessToken, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
||||
if accessToken != "" {
|
||||
// 存在缓存,反序列化
|
||||
result, err := gophp.Unserialize([]byte(accessToken))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var ok bool
|
||||
accessToken, ok = result.(string)
|
||||
if !ok {
|
||||
return "", errors.New("失败")
|
||||
}
|
||||
} else {
|
||||
// 不存在缓存,重新获取
|
||||
var body []byte
|
||||
|
||||
grantType := "client_credential"
|
||||
|
||||
// 构建 URL
|
||||
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s", grantType, c.AppId,
|
||||
c.AppSecret)
|
||||
|
||||
body, err := GetRequest(url)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
}
|
||||
|
||||
var GetAccessTokenResponse GetAccessTokenResponse
|
||||
err = json.Unmarshal(body, &GetAccessTokenResponse)
|
||||
if err != nil {
|
||||
return "", errors.New(err.Error())
|
||||
}
|
||||
|
||||
if GetAccessTokenResponse.ErrCode != 0 {
|
||||
return "", errors.New(GetAccessTokenResponse.ErrMsg)
|
||||
}
|
||||
|
||||
accessToken = GetAccessTokenResponse.AccessToken
|
||||
expiresIn := GetAccessTokenResponse.ExpiresIn
|
||||
|
||||
// 序列化
|
||||
redisValue, _ := gophp.Serialize(accessToken)
|
||||
|
||||
// 增加缓存
|
||||
global.Redis.Set(context.Background(), redisKey, string(redisValue),
|
||||
time.Duration(expiresIn-1500)*time.Second)
|
||||
}
|
||||
|
||||
if accessToken == "" {
|
||||
return "", errors.New("失败")
|
||||
}
|
||||
|
||||
return accessToken, nil
|
||||
}
|
||||
|
||||
// GetRequest 发送 GET 请求并返回响应内容和错误(如果有)
|
||||
func GetRequest(url string) ([]byte, error) {
|
||||
// 发送 GET 请求
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
// 读取响应内容
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
// PostRequest 统一请求
|
||||
func PostRequest(url string, requestBody []byte) ([]byte, error) {
|
||||
// 发起 POST 请求
|
||||
resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
||||
6
go.mod
6
go.mod
@ -15,9 +15,7 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.15.1
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/leeqvip/gophp v1.1.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.17
|
||||
@ -50,7 +48,6 @@ require (
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
@ -73,7 +70,6 @@ require (
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
|
||||
12
go.sum
12
go.sum
@ -145,10 +145,6 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -204,8 +200,6 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
@ -237,6 +231,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/leeqvip/gophp v1.1.1 h1:+HNBayDVEKnaON0+qj/goDjlZ4Bos7hrdy6/Cb5v5M8=
|
||||
github.com/leeqvip/gophp v1.1.1/go.mod h1:DRoO5E9Sk+t4/3LGPCH4QZ/arcASXk9VsqdeTXLgYC4=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
@ -252,8 +248,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
||||
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
@ -346,8 +340,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
|
||||
33
utils/unserialize.go
Normal file
33
utils/unserialize.go
Normal file
@ -0,0 +1,33 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Unserialize 反序列化 PHP 序列化的字符串
|
||||
func Unserialize(data string) (string, error) {
|
||||
// 使用正则表达式找到字符串值
|
||||
re := regexp.MustCompile(`s:(\d+):"(.*?)";`)
|
||||
match := re.FindStringSubmatch(data)
|
||||
if len(match) != 3 {
|
||||
return "", errors.New("invalid input format")
|
||||
}
|
||||
|
||||
// 解析字符串长度
|
||||
length, err := strconv.Atoi(match[1])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 解析字符串值
|
||||
value := match[2]
|
||||
|
||||
// 检查字符串长度是否与值长度匹配
|
||||
if len(value) != length {
|
||||
return "", errors.New("string length does not match")
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user