mirror of
https://github.com/eolinker/apinto
synced 2025-09-26 21:01:19 +08:00
145 lines
4.0 KiB
Go
145 lines
4.0 KiB
Go
package extra_params_v2
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/eolinker/eosc"
|
|
|
|
dynamic_params "github.com/eolinker/apinto/drivers/plugins/extra-params_v2/dynamic-params"
|
|
http_service "github.com/eolinker/eosc/eocontext/http-context"
|
|
)
|
|
|
|
type Config struct {
|
|
Params []*ExtraParam `json:"params" label:"参数列表"`
|
|
RequestBodyType string `json:"request_body_type" enum:"form-data,json,multipart-formdata" label:"请求体类型"`
|
|
ErrorType string `json:"error_type" enum:"text,json" label:"报错输出格式"`
|
|
}
|
|
|
|
func (c *Config) doCheck() error {
|
|
c.ErrorType = strings.ToLower(c.ErrorType)
|
|
if c.ErrorType != "text" && c.ErrorType != "json" {
|
|
c.ErrorType = "text"
|
|
}
|
|
|
|
for _, param := range c.Params {
|
|
if param.Name == "" {
|
|
return fmt.Errorf(paramNameErrInfo)
|
|
}
|
|
|
|
param.Position = strings.ToLower(param.Position)
|
|
if param.Position != "query" && param.Position != "header" && param.Position != "body" {
|
|
return fmt.Errorf(paramPositionErrInfo, param.Position)
|
|
}
|
|
|
|
param.Conflict = strings.ToLower(param.Conflict)
|
|
if param.Conflict != paramOrigin && param.Conflict != paramConvert && param.Conflict != paramError {
|
|
param.Conflict = paramConvert
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type ExtraParam struct {
|
|
Name string `json:"name" label:"参数名"`
|
|
Type string `json:"type" label:"参数类型" enum:"string,int,float,bool,$datetime,$md5,$timestamp,$concat"`
|
|
Position string `json:"position" enum:"header,query,body" label:"参数位置"`
|
|
Value []string `json:"value" label:"参数值列表"`
|
|
Conflict string `json:"conflict" label:"参数冲突时的处理方式" enum:"origin,convert,error"`
|
|
}
|
|
|
|
type baseParam struct {
|
|
header []*paramInfo
|
|
query []*paramInfo
|
|
body []*paramInfo
|
|
}
|
|
|
|
func generateBaseParam(params []*ExtraParam) *baseParam {
|
|
b := &baseParam{
|
|
header: make([]*paramInfo, 0),
|
|
query: make([]*paramInfo, 0),
|
|
body: make([]*paramInfo, 0),
|
|
}
|
|
for _, param := range params {
|
|
switch param.Position {
|
|
case positionHeader:
|
|
b.header = append(b.header, newParamInfo(param.Name, param.Value, param.Type, param.Conflict))
|
|
case positionQuery:
|
|
b.query = append(b.query, newParamInfo(param.Name, param.Value, param.Type, param.Conflict))
|
|
case positionBody:
|
|
b.body = append(b.body, newParamInfo(param.Name, param.Value, param.Type, param.Conflict))
|
|
}
|
|
}
|
|
return b
|
|
}
|
|
|
|
func newParamInfo(name string, value []string, typ string, conflict string) *paramInfo {
|
|
d := ¶mInfo{name: name, value: strings.Join(value, ""), conflict: conflict, valueType: typ}
|
|
valueLen := len(d.value)
|
|
if strings.HasPrefix(typ, "$") {
|
|
factory, has := dynamic_params.Get(typ)
|
|
if has {
|
|
driver, err := factory.Create(name, value)
|
|
if err == nil {
|
|
d.driver = driver
|
|
}
|
|
}
|
|
} else if valueLen > 1 && d.value[0] == '$' {
|
|
// 系统变量
|
|
d.systemValue = true
|
|
d.value = d.value[1:valueLen]
|
|
}
|
|
return d
|
|
}
|
|
|
|
type paramInfo struct {
|
|
name string
|
|
valueType string
|
|
systemValue bool
|
|
value string
|
|
driver dynamic_params.IDynamicDriver
|
|
conflict string
|
|
}
|
|
|
|
func (b *paramInfo) Build(ctx http_service.IHttpContext, contentType string, params interface{}) (string, interface{}, error) {
|
|
value, err := b.build(ctx, contentType, params)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
switch b.valueType {
|
|
case "int":
|
|
v, err := strconv.Atoi(value)
|
|
return value, v, err
|
|
case "float":
|
|
v, err := strconv.ParseFloat(value, 64)
|
|
return value, v, err
|
|
case "bool":
|
|
v, err := strconv.ParseBool(value)
|
|
return value, v, err
|
|
default:
|
|
return value, nil, nil
|
|
}
|
|
}
|
|
|
|
func (b *paramInfo) build(ctx http_service.IHttpContext, contentType string, params interface{}) (string, error) {
|
|
if b.driver == nil {
|
|
if b.systemValue {
|
|
return eosc.ReadStringFromEntry(ctx.GetEntry(), b.value), nil
|
|
}
|
|
return b.value, nil
|
|
}
|
|
value, err := b.driver.Generate(ctx, contentType, params)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
switch v := value.(type) {
|
|
case string:
|
|
return v, nil
|
|
case int, int32, int64:
|
|
return fmt.Sprintf("%d", v), nil
|
|
}
|
|
return "", nil
|
|
}
|