提交 ea1c2441 authored 作者: mooncake9527's avatar mooncake9527

update

上级 e06545fc
package convertUtils package convert_utils
import "strconv" import "strconv"
......
package xeg package eg_utils
import ( import (
"context" "context"
...@@ -16,14 +16,13 @@ func Do(ctx context.Context, fns ...FnCtx) error { ...@@ -16,14 +16,13 @@ func Do(ctx context.Context, fns ...FnCtx) error {
} }
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()
g, ctx := errgroup.WithContext(ctx) eg, ctx := errgroup.WithContext(ctx)
for _, fn := range fns { for _, fn := range fns {
g.Go(func() error { eg.Go(func() error {
return fn(ctx) return fn(ctx)
}) })
} }
err := g.Wait() if err := eg.Wait(); err != nil {
if err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
return nil return nil
...@@ -35,14 +34,13 @@ func DoWithTimeout(timeout time.Duration, fns ...FnCtx) error { ...@@ -35,14 +34,13 @@ func DoWithTimeout(timeout time.Duration, fns ...FnCtx) error {
} }
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel() defer cancel()
g, ctx := errgroup.WithContext(ctx) eg, ctx := errgroup.WithContext(ctx)
for _, fn := range fns { for _, fn := range fns {
g.Go(func() error { eg.Go(func() error {
return fn(ctx) return fn(ctx)
}) })
} }
err := g.Wait() if err := eg.Wait(); err != nil {
if err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
return nil return nil
......
package httpUtils
import (
"net/http"
"time"
)
type Request struct {
method string
url string
params map[string]interface{}
headers map[string]string
body any
bodyJSON any
timeout time.Duration
retry uint
request *http.Request
response *http.Response
err error
}
func New() *Request {
return &Request{
request: &http.Request{},
headers: map[string]string{},
params: map[string]interface{}{},
}
}
func (req *Request) SetURL(path string) *Request {
req.url = path
return req
}
func (req *Request) SetParams(params map[string]any) *Request {
if req.params == nil {
req.params = params
} else {
for k, v := range params {
req.params[k] = v
}
}
return req
}
func (req *Request) SetParam(k string, v interface{}) *Request {
if req.params == nil {
req.params = make(map[string]interface{})
}
req.params[k] = v
return req
}
func (req *Request) SetBody(body interface{}) *Request {
switch v := body.(type) {
case string:
req.body = v
case []byte:
req.body = string(v)
default:
req.bodyJSON = body
}
return req
}
func (req *Request) SetHeader(k, v string) *Request {
if req.headers == nil {
req.headers = make(map[string]string)
}
req.headers[k] = v
return req
}
func (req *Request) SetTimeout(t time.Duration) *Request {
req.timeout = t
return req
}
func (req *Request) SetRetry(retry uint) *Request {
req.retry = retry
return req
}
func (req *Request) SetContentType(a string) *Request {
req.SetHeader("Content-Type", a)
return req
}
package jsonUtils package json_utils
import ( import (
"bytes" "bytes"
......
package mapUtils package map_utils
import ( import (
"encoding/json" "encoding/json"
......
...@@ -16,7 +16,7 @@ import ( ...@@ -16,7 +16,7 @@ import (
"gitlab.wanzhuangkj.com/tush/xpkg/logger" "gitlab.wanzhuangkj.com/tush/xpkg/logger"
merge "gitlab.wanzhuangkj.com/tush/xpkg/merger" merge "gitlab.wanzhuangkj.com/tush/xpkg/merger"
"gitlab.wanzhuangkj.com/tush/xpkg/utils/ctxUtils" "gitlab.wanzhuangkj.com/tush/xpkg/utils/ctxUtils"
"gitlab.wanzhuangkj.com/tush/xpkg/utils/jsonUtils" "gitlab.wanzhuangkj.com/tush/xpkg/utils/json_utils"
"gitlab.wanzhuangkj.com/tush/xpkg/utils/retryUtils" "gitlab.wanzhuangkj.com/tush/xpkg/utils/retryUtils"
"gitlab.wanzhuangkj.com/tush/xpkg/utils/xsf" "gitlab.wanzhuangkj.com/tush/xpkg/utils/xsf"
"gitlab.wanzhuangkj.com/tush/xpkg/utils/xtime" "gitlab.wanzhuangkj.com/tush/xpkg/utils/xtime"
...@@ -101,7 +101,7 @@ func Init(schema string, isProd bool) { ...@@ -101,7 +101,7 @@ func Init(schema string, isProd bool) {
} }
insertFn := func() error { insertFn := func() error {
if err := WebLogDao.CreateSliceSilent(ctx, ors); err != nil { if err := WebLogDao.CreateSliceSilent(ctx, ors); err != nil {
logger.Error("[webLog] insert fail detail", ctxUtils.CtxTraceIDField(ctx)) logger.Error("[webLog] insert fail detail", logger.Err(err), ctxUtils.CtxTraceIDField(ctx))
return err return err
} }
return nil return nil
...@@ -123,21 +123,21 @@ func Init(schema string, isProd bool) { ...@@ -123,21 +123,21 @@ func Init(schema string, isProd bool) {
} }
func AddAsync(ctx context.Context, traceNo, operate string, req *entity.CopyHttpReq, rsp *entity.CopyHttpRsp) { func AddAsync(ctx context.Context, traceNo, operate string, req *entity.CopyHttpReq, rsp *entity.CopyHttpRsp) {
op := &WebLog{} wl := &WebLog{}
op.ID = xsf.GenerateID() wl.ID = xsf.GenerateID()
op.CompanyID = ctxUtils.GetCtxCompanyID(ctx) wl.CompanyID = ctxUtils.GetCtxCompanyID(ctx)
op.UserID = ctxUtils.GetCtxUID(ctx) wl.UserID = ctxUtils.GetCtxUID(ctx)
op.TraceID = ctxUtils.GetCtxTid(ctx) wl.TraceID = ctxUtils.GetCtxTid(ctx)
op.Operate = operate wl.Operate = operate
op.CreatedAt = xtime.Now() wl.CreatedAt = xtime.Now()
if req != nil { if req != nil {
op.Req = jsonUtils.ToJSONStringPtr(req) wl.Req = json_utils.ToJSONStringPtr(req)
} }
if rsp != nil { if rsp != nil {
op.Rsp = jsonUtils.ToJSONStringPtr(rsp) wl.Rsp = json_utils.ToJSONStringPtr(rsp)
} }
go func() { go func() {
merger.Add(op) merger.Add(wl)
}() }()
} }
...@@ -179,10 +179,6 @@ const TBWebLog = "web_log" ...@@ -179,10 +179,6 @@ const TBWebLog = "web_log"
func (WebLog) TableName() string { func (WebLog) TableName() string {
return TBWebLog return TBWebLog
} }
func (x WebLog) GetOrder() string {
return "id asc"
}
func (x *WebLog) BeforeCreate(tx *gorm.DB) (err error) { func (x *WebLog) BeforeCreate(tx *gorm.DB) (err error) {
if x.CreatedAt.IsZero() { if x.CreatedAt.IsZero() {
x.CreatedAt = xtime.Now() x.CreatedAt = xtime.Now()
......
...@@ -2,8 +2,8 @@ DROP TABLE if EXISTS `web_log`; ...@@ -2,8 +2,8 @@ DROP TABLE if EXISTS `web_log`;
CREATE TABLE `web_log` ( CREATE TABLE `web_log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID eg[10001]', `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID eg[10001]',
`company_id` bigint(20) unsigned DEFAULT NULL COMMENT '公司ID eg[20001]', `company_id` bigint(20) DEFAULT NULL COMMENT '公司ID eg[20001]',
`user_id` bigint(20) unsigned DEFAULT NULL COMMENT '用户ID eg[30001]', `user_id` bigint(20) DEFAULT NULL COMMENT '用户ID eg[30001]',
`operate` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL DEFAULT '' COMMENT '操作 eg[用户登出]', `operate` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL DEFAULT '' COMMENT '操作 eg[用户登出]',
`trace_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL DEFAULT '' COMMENT '溯源id eg[TRACE_ID12345]', `trace_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL DEFAULT '' COMMENT '溯源id eg[TRACE_ID12345]',
`req` json DEFAULT NULL COMMENT '请求 eg[]', `req` json DEFAULT NULL COMMENT '请求 eg[]',
......
...@@ -77,8 +77,6 @@ func NowPtr() *DateTime { ...@@ -77,8 +77,6 @@ func NowPtr() *DateTime {
return &j return &j
} }
const TimeFormat = "2006-01-02 15:04:05"
// Value insert timestamp into mysql need this function. // Value insert timestamp into mysql need this function.
func (t DateTime) Value() (driver.Value, error) { func (t DateTime) Value() (driver.Value, error) {
var zeroTime time.Time var zeroTime time.Time
......
package xtime
//
//const (
// Layout_YYYYMMMDDHHMMSS = "20060102150405"
// Layout_DateTimeWithMS = "2006-01-02 15:04:05.000"
// Layout_DateTime = "2006-01-02 15:04:05"
// Layout_Date = "2006-01-02"
// Layout_Time = "15:04:05"
//)
//
//// 定义time.Time的别名
//type DateTime time.Time
//
//func (ct *DateTime) UnmarshalParam(src string) error {
// field, _ := reflect.TypeOf(ct).Elem().FieldByName("DateTime")
// format := field.Tag.Get("format")
// if format == "" {
// format = time.DateTime
// }
// t, err := time.Parse(format, src)
// if err != nil {
// return fmt.Errorf("time format should be %s", format)
// }
// *ct = DateTime(t)
// return nil
//}
//
//// 自定义json序列化
//func (x DateTime) MarshalJSON() ([]byte, error) {
// if x.IsZero() {
// return []byte(`""`), nil
// }
// field, _ := reflect.TypeOf(x).Elem().FieldByName("DateTime")
// format := field.Tag.Get("format")
// if format == "" {
// format = "2006-01-02 15:04:05"
// }
// var jsonTimeStr = fmt.Sprintf(`"%s"`, time.Time(x).Format(format))
// return []byte(jsonTimeStr), nil
//}
//
//// 自定义json反序列化
//func (x *DateTime) UnmarshalJSON(data []byte) error {
// if len(data) == 0 || string(data) == `""` {
// *x = DateTime{}
// return nil
// }
// field, _ := reflect.TypeOf(x).Elem().FieldByName("DateTime")
// format := field.Tag.Get("format")
// if format == "" {
// format = "2006-01-02 15:04:05"
// }
// t, err := time.Parse(format, string(data))
// if err != nil {
// return err
// }
// *x = DateTime(t)
// return nil
//}
//
//func (x DateTime) Time() time.Time {
// return time.Time(x)
//}
//
//func (x DateTime) IsZero() bool {
// return x.Time().IsZero()
//}
//func (x DateTime) IsNotZero() bool {
// return !x.IsZero()
//}
//
//func NewDateTime(t time.Time) DateTime {
// return DateTime(t)
//}
//
//func Now() DateTime {
// return DateTime(time.Now())
//}
//
//func NowPtr() *DateTime {
// j := DateTime(time.Now())
// return &j
//}
//
//const TimeFormat = "2006-01-02 15:04:05"
//
//// Value insert timestamp into mysql need this function.
//func (t DateTime) Value() (driver.Value, error) {
// var zeroTime time.Time
// if time.Time(t).UnixNano() == zeroTime.UnixNano() {
// return nil, nil
// }
// return time.Time(t), nil
//}
//
//// Scan value of time.Time
//func (t *DateTime) Scan(v interface{}) error {
// value, ok := v.(time.Time)
// if ok {
// *t = DateTime(value)
// return nil
// }
// return fmt.Errorf("can not convert %v to timestamp", v)
//}
//
//func BeginOfDay(t time.Time) DateTime {
// y, m, d := t.Date()
// begin := time.Date(y, m, d, 0, 0, 0, 0, t.Location())
// return DateTime(begin)
//}
//
//func EndOfDay(t time.Time) DateTime {
// y, m, d := t.Date()
// end := time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
// return DateTime(end)
//}
//
//func TodayBegin() DateTime {
// t := time.Now()
// y, m, d := t.Date()
// begin := time.Date(y, m, d, 0, 0, 0, 0, t.Location())
// return DateTime(begin)
//}
//
//func TodayEnd() DateTime {
// t := time.Now()
// y, m, d := t.Date()
// end := time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
// return DateTime(end)
//}
//
//var durationRegex = regexp.MustCompile(`(\d+)([a-zA-Z]+)`)
//
//func ParseExtendedDuration(s string) (time.Duration, error) {
// matches := durationRegex.FindAllStringSubmatch(s, -1)
// if len(matches) == 0 {
// return 0, fmt.Errorf("invalid format: %q", s)
// }
//
// // 验证完整匹配
// var matched string
// for _, m := range matches {
// matched += m[0]
// }
// if matched != s {
// return 0, fmt.Errorf("invalid characters in duration: %q", s)
// }
//
// var total time.Duration
// for _, match := range matches {
// numStr := match[1]
// unit := match[2]
// // unit := strings.ToUpper(match[2])
// num, err := strconv.ParseInt(numStr, 10, 64)
// if err != nil {
// return 0, fmt.Errorf("invalid number %q: %v", numStr, err)
// }
//
// var d time.Duration
// switch unit {
// case "d", "D":
// d = time.Duration(num) * 24 * time.Hour
// case "w", "W":
// d = time.Duration(num) * 7 * 24 * time.Hour
// case "M":
// d = time.Duration(num) * 30 * 24 * time.Hour
// case "y", "Y":
// d = time.Duration(num) * 365 * 24 * time.Hour
// default:
// // 回退到标准库解析
// if dur, err := time.ParseDuration(match[0]); err == nil {
// d = dur
// } else {
// return 0, fmt.Errorf("unknown unit %q", unit)
// }
// }
// total += d
// }
//
// return total, nil
//}
//
//const (
// Layout_YYYY = "2006"
// Layout_YYYYMM = "2006-01"
// Layout_YYYYMMDD = "2006-01-02"
// Layout_YYYYMMDD2 = "2006/01/02"
// Layout_YYYYMMDD3 = "20060102"
// Layout_YYYYMMDDHHmmSS = "2006-01-02 15:04:05"
//)
//
//var (
// LocBeiJing, _ = time.LoadLocation("Asia/Shanghai")
//)
//
//func (x DateTime) Format(layout string) string {
// return x.Time().Format(layout)
//}
//func (x DateTime) FormatYYYYMMDDHHmmSS() string {
// return x.Time().Format(Layout_YYYYMMDDHHmmSS)
//}
//
//// const TimeFormat = "2006-01-02 15:04:05"
//
//// // Value insert timestamp into mysql need this function.
//// func (t DateTime) Value() (driver.Value, error) {
//// var zeroTime time.Time
//// if time.Time(t).UnixNano() == zeroTime.UnixNano() {
//// return nil, nil
//// }
//// return time.Time(t), nil
//// }
//
//// // Scan value of time.Time
//// func (t *DateTime) Scan(v interface{}) error {
//// value, ok := v.(time.Time)
//// if ok {
//// *t = DateTime(value)
//// return nil
//// }
//// return fmt.Errorf("can not convert %v to timestamp", v)
//// }
//
//func (x DateTime) Date() DateTime {
// y, m, d := x.Time().Date()
// trimmedTime := time.Date(y, m, d, 0, 0, 0, 0, x.Time().Location())
// return NewDateTime(trimmedTime)
//}
//
//func (x DateTime) WeekStart() DateTime {
// return x.WeekEnd().AddDate(0, 0, -6)
//}
//
//func (x DateTime) WeekEnd() DateTime {
// weekday := int(x.Time().Weekday())
// if weekday == 0 {
// weekday = 7
// }
// return x.AddDate(0, 0, +7-weekday)
//}
//
//func (t0 DateTime) MonthStart() DateTime {
// year, month, _ := t0.Time().Date()
// t1 := time.Date(year, month, 1, 0, 0, 0, 0, t0.Time().Location())
// return DateTime(t1)
//}
//
//func (t0 DateTime) MonthEnd() DateTime {
// year, month, _ := t0.Time().Date()
// t1 := time.Date(year, month+1, 0, 0, 0, 0, 0, t0.Time().Location())
// return DateTime(t1)
//}
//
//func (t DateTime) AddDate(y, m, d int) DateTime {
// return DateTime(t.Time().AddDate(y, m, d))
//}
//
//// WeekDay 1-7 周一到周日
//func (x DateTime) WeekDay() int {
// return ((int(x.Time().Weekday()) + 6) % 7) + 1
//}
//
//// 1-31 1号到31号
//func (x DateTime) Day() int {
// return int(x.Time().Day())
//}
//
//// 1-12 1月到12月
//func (x DateTime) Month() int {
// return int(x.Time().Month())
//}
//
//// 1970年到现在第几年
//func (x DateTime) Year() int {
// return int(x.Time().Year())
//}
//func (x DateTime) After(t1 DateTime) bool {
// return x.Time().After(t1.Time())
//}
//
//// 转为北京时间
//func (x DateTime) LocalBeiJing() DateTime {
// return DateTime(x.Time().In(LocBeiJing))
//}
//
//func (x DateTime) Local() DateTime {
// return DateTime(x.Time().In(time.Local))
//}
//
//func (x DateTime) Quarter() int {
// return (int(x.Time().Month())-1)/3 + 1
//}
//
//func ParseYYYYMMDD(value string) DateTime {
// t, err := time.Parse(Layout_YYYYMMDD, value)
// if err != nil {
// return DateTime{}
// }
// return DateTime(t)
//}
//func ParseYYYYMMDDHHmmSS(value string) DateTime {
// t, err := time.Parse(Layout_YYYYMMDDHHmmSS, value)
// if err != nil {
// return DateTime{}
// }
// return DateTime(t)
//}
//
//func ParseTime(layout, value string) (DateTime, error) {
// t, err := time.Parse(layout, value)
// if err != nil {
// return DateTime{}, err
// }
// return DateTime(t), nil
//}
//
//func IsSameDay(t1, t2 DateTime) bool {
// t1Local := t1.Local()
// t2Local := t2.Local()
// return t1Local.Year() == t2Local.Year() &&
// t1Local.Month() == t2Local.Month() &&
// t1Local.Day() == t2Local.Day()
//}
//
//// 是否同一周
//func IsSameWeek(t0, t1 DateTime) bool {
// y1, w1 := t0.Time().Local().ISOWeek()
// y2, w2 := t1.Time().Local().ISOWeek()
// return y1 == y2 && w1 == w2
//}
//func NotSameWeek(t0, t1 DateTime) bool {
// return !IsSameWeek(t0, t1)
//}
//
//// 是否同一个月
//func IsSameMonth(t0, t1 DateTime) bool {
// return t0.Month() == t1.Month()
//}
//func NotSameMonth(t0, t1 DateTime) bool {
// return !IsSameMonth(t0, t1)
//}
//
//// 是否同一季度
//func IsSameQuarter(t0, t1 DateTime) bool {
// return t0.Quarter() == t1.Quarter()
//}
//func NotSameSeason(t0, t1 DateTime) bool {
// return !IsSameQuarter(t0, t1)
//}
//
//// 是否同一年
//func IsSameYear(t0, t1 DateTime) bool {
// return t0.Time().Year() == t1.Time().Year()
//}
//func NotSameYear(t0, t1 DateTime) bool {
// return !IsSameYear(t0, t1)
//}
//
//func DayBeforeYesterday() DateTime {
// return DateTime(time.Now().AddDate(0, 0, -2))
//}
//
//func Yesterday() DateTime {
// return DateTime(time.Now().AddDate(0, 0, -1))
//}
//
//func Today() DateTime {
// return DateTime(time.Now())
//}
//
//func (t0 DateTime) PreviousQuarter(n int) DateTime {
// month := t0.Month()
// quarterStartMonth := time.Month((int(month)-1)/3*3 + 1)
// currentQuarterStart := time.Date(
// t0.Year(), quarterStartMonth, 1,
// 0, 0, 0, 0, t0.Time().Location(),
// )
// return DateTime(currentQuarterStart.AddDate(0, -3*n, 0))
//}
//
//func (t0 DateTime) FormatYYYYQT() string {
// month := t0.Month()
// quarter := (int(month)-1)/3 + 1
// return fmt.Sprintf("%s_%d", t0.Format(Layout_YYYY), quarter)
//}
//
//func DaysBetween(t0, t1 DateTime) int {
// t2 := time.Date(t0.Year(), t0.Time().Month(), t0.Day(), 0, 0, 0, 0, t0.Time().Location())
// t3 := time.Date(t1.Year(), t1.Time().Month(), t1.Day(), 0, 0, 0, 0, t1.Time().Location())
// diff := t2.Sub(t3)
// days := int(diff.Hours() / 24)
// return days
//}
package xtime
import (
"testing"
"time"
)
func TestParseExtendedDuration(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
want time.Duration
wantErr bool
}{
{name: "1", args: args{s: "1d"}, want: 24 * time.Hour, wantErr: false},
{name: "2", args: args{s: "2w"}, want: 2 * 7 * 24 * time.Hour, wantErr: false},
{name: "3", args: args{s: "3M"}, want: 3 * 30 * 24 * time.Hour, wantErr: false},
{name: "4", args: args{s: "4y"}, want: 4 * 365 * 24 * time.Hour, wantErr: false},
{name: "5", args: args{s: "1d2h"}, want: 26 * time.Hour, wantErr: false},
{name: "6", args: args{s: "1W3D"}, want: (7 + 3) * 24 * time.Hour, wantErr: false},
{name: "7", args: args{s: "30m"}, want: 30 * time.Minute, wantErr: false},
{name: "7", args: args{s: "20s"}, want: 20 * time.Second, wantErr: false},
{name: "7", args: args{s: "20ms"}, want: 20 * time.Millisecond, wantErr: false},
{name: "8", args: args{s: "1x"}, want: 0, wantErr: true},
{name: "9", args: args{s: "invalid"}, want: 0, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseExtendedDuration(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("ParseExtendedDuration() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("ParseExtendedDuration() = %v, want %v", got, tt.want)
}
})
}
}
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.wanzhuangkj.com/tush/xpkg/gin/response" "gitlab.wanzhuangkj.com/tush/xpkg/gin/response"
"gitlab.wanzhuangkj.com/tush/xpkg/httpcli" "gitlab.wanzhuangkj.com/tush/xpkg/httpcli"
"gitlab.wanzhuangkj.com/tush/xpkg/utils/mapUtils" "gitlab.wanzhuangkj.com/tush/xpkg/utils/map_utils"
"gitlab.wanzhuangkj.com/tush/xpkg/xcommon/validator" "gitlab.wanzhuangkj.com/tush/xpkg/xcommon/validator"
) )
...@@ -102,7 +102,7 @@ func (x *ControllerTester) After(t *testing.T) { ...@@ -102,7 +102,7 @@ func (x *ControllerTester) After(t *testing.T) {
func (x *ControllerTester) CommonHttp(method, URL string, in any, reply *response.Result) error { func (x *ControllerTester) CommonHttp(method, URL string, in any, reply *response.Result) error {
if method == http.MethodDelete || method == http.MethodGet { if method == http.MethodDelete || method == http.MethodGet {
in = mapUtils.StructToMapWithJsonTag(in) in = map_utils.StructToMapWithJsonTag(in)
} }
if err := x.client.NewRequest(). if err := x.client.NewRequest().
SetHeaders(x.Headers). SetHeaders(x.Headers).
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论