diff --git a/config.yaml.sample b/config.yaml.sample index a44a84df..2113be3b 100644 --- a/config.yaml.sample +++ b/config.yaml.sample @@ -5,28 +5,33 @@ App: # APP基础设置项 DefaultContextTimeout: 60 DefaultPageSize: 10 MaxPageSize: 100 - SmsJuheKey: - SmsJuheTplID: - SmsJuheTplVal: "#code#=%d&#m#=%d" - AlipayAppID: - AlipayPrivateKey: -Runtime: # App运行时功能调节 - DisablePhoneVerify: False # 禁止绑定手机号码时验证短信验证码,为true时任意验证码都可以通过验证 Server: # 服务设置 RunMode: debug HttpIp: 0.0.0.0 HttpPort: 8008 ReadTimeout: 60 WriteTimeout: 60 -Log: # 日志 - LogType: zinc # 可选file或zinc - LogFileSavePath: storage/logs - LogFileName: app - LogFileExt: .log - LogZincHost: http://127.0.0.1:4080/es/_bulk - LogZincIndex: paopao-log - LogZincUser: admin - LogZincPassword: admin +Features: + Default: ["Sms", "Alipay", "Zinc", "MySQL", "Redis", "AliOSS", "LoggerZinc"] + Develop: ["Zinc", "MySQL", "AliOSS", "LoggerFile"] + Slim: ["Zinc", "MySQL", "Redis", "AliOSS", "LoggerFile"] + Sms: "SmsJuhe" +SmsJuhe: + Key: + TplID: + TplVal: "#code#=%d&#m#=%d" +Alipay: + AppID: + PrivateKey: +LoggerFile: # 使用File写日志 + SavePath: storage/logs + FileName: app + FileExt: .log +LoggerZinc: # 使用Zinc写日志 + Host: http://127.0.0.1:4080/es/_bulk + Index: paopao-log + User: admin + Password: admin JWT: # 鉴权加密 Secret: 18a6413dc4fe394c66345ebe501b2f26 Issuer: paopao-api @@ -36,14 +41,18 @@ Search: # 搜索配置 ZincIndex: paopao-data ZincUser: admin ZincPassword: admin -Storage: # 阿里云OSS存储配置 - AliossAccessKeyID: - AliossAccessKeySecret: - AliossEndpoint: - AliossBucket: - AliossDomain: -Database: # 数据库 - DBType: mysql +Zinc: # Zinc搜索配置 + Host: http://127.0.0.1:4080 + Index: paopao-data + User: admin + Password: admin +AliOSS: # 阿里云OSS存储配置 + AccessKeyID: + AccessKeySecret: + Endpoint: + Bucket: + Domain: +MySQL: # MySQL数据库 Username: root # 填写你的数据库账号 Password: root # 填写你的数据库密码 Host: 127.0.0.1:3306 diff --git a/global/setting.go b/global/setting.go index ac463109..f4d49a66 100644 --- a/global/setting.go +++ b/global/setting.go @@ -8,15 +8,26 @@ import ( ) var ( - ServerSetting *setting.ServerSettingS - AppSetting *setting.AppSettingS - RuntimeSetting *setting.RuntimeSettingS - DatabaseSetting *setting.DatabaseSettingS - RedisSetting *setting.RedisSettingS - SearchSetting *setting.SearchSettingS - AliossSetting *setting.AliossSettingS - JWTSetting *setting.JWTSettingS - LoggerSetting *setting.LoggerSettingS - Logger *logrus.Logger - Mutex *sync.Mutex + Features *setting.FeaturesSettingS + ServerSetting *setting.ServerSettingS + AppSetting *setting.AppSettingS + MySQLSetting *setting.MySQLSettingS + RedisSetting *setting.RedisSettingS + SmsJuheSetting *setting.SmsJuheSettings + AlipaySetting *setting.AlipaySettingS + ZincSetting *setting.ZincSettingS + AliOSSSetting *setting.AliOSSSettingS + JWTSetting *setting.JWTSettingS + LoggerFileSetting *setting.LoggerFileSettingS + LoggerZincSetting *setting.LoggerZincSettingS + Logger *logrus.Logger + Mutex *sync.Mutex ) + +func Cfg(key string) (string, bool) { + return Features.Cfg(key) +} + +func CfgIf(expression string) bool { + return Features.CfgIf(expression) +} diff --git a/init.go b/init.go index ac7a1178..713238ac 100644 --- a/init.go +++ b/init.go @@ -27,7 +27,7 @@ func init() { if err != nil { log.Fatalf("init.setupDBEngine err: %v", err) } - client := zinc.NewClient(global.SearchSetting) + client := zinc.NewClient(global.ZincSetting) service.Initialize(global.DBEngine, client) } @@ -37,40 +37,22 @@ func setupSetting() error { return err } - err = setting.ReadSection("Server", &global.ServerSetting) - if err != nil { - return err - } - err = setting.ReadSection("App", &global.AppSetting) - if err != nil { - return err - } - err = setting.ReadSection("Runtime", &global.RuntimeSetting) - if err != nil { - return err - } - err = setting.ReadSection("Log", &global.LoggerSetting) - if err != nil { - return err - } - err = setting.ReadSection("Database", &global.DatabaseSetting) - if err != nil { - return err - } - err = setting.ReadSection("Search", &global.SearchSetting) - if err != nil { - return err - } - err = setting.ReadSection("Redis", &global.RedisSetting) - if err != nil { - return err - } - err = setting.ReadSection("JWT", &global.JWTSetting) - if err != nil { - return err + global.Features = setting.FeaturesFrom("Features") + + objects := map[string]interface{}{ + "App": &global.AppSetting, + "Server": &global.ServerSetting, + "Alipay": &global.AlipaySetting, + "SmsJuhe": &global.SmsJuheSetting, + "LoggerFile": &global.LoggerFileSetting, + "LoggerZinc": &global.LoggerZincSetting, + "MySQL": &global.MySQLSetting, + "Zinc": &global.ZincSetting, + "Redis": &global.RedisSetting, + "JWT": &global.JWTSetting, + "AliOSS": &global.AliOSSSetting, } - err = setting.ReadSection("Storage", &global.AliossSetting) - if err != nil { + if err = setting.Unmarshal(objects); err != nil { return err } @@ -82,7 +64,7 @@ func setupSetting() error { } func setupLogger() error { - logger, err := logger.New(global.LoggerSetting) + logger, err := logger.New() if err != nil { return err } @@ -91,9 +73,10 @@ func setupLogger() error { return nil } +// setupDBEngine 暂时只支持MySQL func setupDBEngine() error { var err error - global.DBEngine, err = model.NewDBEngine(global.DatabaseSetting) + global.DBEngine, err = model.NewDBEngine(global.MySQLSetting) if err != nil { return err } diff --git a/internal/dao/user.go b/internal/dao/user.go index 3859f67c..0d4c8c03 100644 --- a/internal/dao/user.go +++ b/internal/dao/user.go @@ -127,9 +127,9 @@ func (d *dataServant) SendPhoneCaptcha(phone string) error { resp, err := client.R(). SetFormData(map[string]string{ "mobile": phone, - "tpl_id": global.AppSetting.SmsJuheTplID, - "tpl_value": fmt.Sprintf(global.AppSetting.SmsJuheTplVal, captcha, m), - "key": global.AppSetting.SmsJuheKey, + "tpl_id": global.SmsJuheSetting.TplID, + "tpl_value": fmt.Sprintf(global.SmsJuheSetting.TplVal, captcha, m), + "key": global.SmsJuheSetting.Key, }).Post(gateway) if err != nil { return err diff --git a/internal/model/model.go b/internal/model/model.go index 6010b1b2..67819b72 100644 --- a/internal/model/model.go +++ b/internal/model/model.go @@ -25,7 +25,7 @@ type Model struct { type ConditionsT map[string]interface{} -func NewDBEngine(databaseSetting *setting.DatabaseSettingS) (*gorm.DB, error) { +func NewDBEngine(databaseSetting *setting.MySQLSettingS) (*gorm.DB, error) { newLogger := logger.New( global.Logger, // io writer(日志输出的目标,前缀和日志包含的内容) logger.Config{ diff --git a/internal/routers/api/attachment.go b/internal/routers/api/attachment.go index 59bbc52f..9723cea8 100644 --- a/internal/routers/api/attachment.go +++ b/internal/routers/api/attachment.go @@ -97,14 +97,14 @@ func UploadAttachment(c *gin.Context) { randomPath := uuid.Must(uuid.NewV4()).String() ossSavePath := uploadType + "/" + GeneratePath(randomPath[:8]) + "/" + randomPath[9:] + fileExt - client, err := oss.New(global.AliossSetting.AliossEndpoint, global.AliossSetting.AliossAccessKeyID, global.AliossSetting.AliossAccessKeySecret) + client, err := oss.New(global.AliOSSSetting.Endpoint, global.AliOSSSetting.AccessKeyID, global.AliOSSSetting.AccessKeySecret) if err != nil { global.Logger.Errorf("oss.New err: %v", err) response.ToErrorResponse(errcode.FileUploadFailed) return } - bucket, err := client.Bucket(global.AliossSetting.AliossBucket) + bucket, err := client.Bucket(global.AliOSSSetting.Bucket) if err != nil { global.Logger.Errorf("client.Bucket err: %v", err) response.ToErrorResponse(errcode.FileUploadFailed) @@ -121,7 +121,7 @@ func UploadAttachment(c *gin.Context) { // 构造附件Model attachment := &model.Attachment{ FileSize: fileHeader.Size, - Content: "https://" + global.AliossSetting.AliossDomain + "/" + ossSavePath, + Content: "https://" + global.AliOSSSetting.Domain + "/" + ossSavePath, } if userID, exists := c.Get("UID"); exists { @@ -256,14 +256,14 @@ func DownloadAttachment(c *gin.Context) { } // 开始构造下载地址 - client, err := oss.New(global.AliossSetting.AliossEndpoint, global.AliossSetting.AliossAccessKeyID, global.AliossSetting.AliossAccessKeySecret) + client, err := oss.New(global.AliOSSSetting.Endpoint, global.AliOSSSetting.AccessKeyID, global.AliOSSSetting.AccessKeySecret) if err != nil { global.Logger.Errorf("oss.New err: %v", err) response.ToErrorResponse(errcode.DownloadReqError) return } - bucket, err := client.Bucket(global.AliossSetting.AliossBucket) + bucket, err := client.Bucket(global.AliOSSSetting.Bucket) if err != nil { global.Logger.Errorf("client.Bucket err: %v", err) response.ToErrorResponse(errcode.DownloadReqError) @@ -271,7 +271,7 @@ func DownloadAttachment(c *gin.Context) { } // 签名 - objectKey := strings.Replace(content.Content, "https://"+global.AliossSetting.AliossDomain+"/", "", -1) + objectKey := strings.Replace(content.Content, "https://"+global.AliOSSSetting.Domain+"/", "", -1) signedURL, err := bucket.SignURL(objectKey, oss.HTTPGet, 60) if err != nil { global.Logger.Errorf("client.SignURL err: %v", err) diff --git a/internal/routers/api/user.go b/internal/routers/api/user.go index dfbc5c8a..30b1da97 100644 --- a/internal/routers/api/user.go +++ b/internal/routers/api/user.go @@ -204,7 +204,7 @@ func ChangeAvatar(c *gin.Context) { user = u.(*model.User) } - if strings.Index(param.Avatar, "https://"+global.AliossSetting.AliossDomain) != 0 { + if strings.Index(param.Avatar, "https://"+global.AliOSSSetting.Domain) != 0 { response.ToErrorResponse(errcode.InvalidParams) return } @@ -238,13 +238,10 @@ func BindUserPhone(c *gin.Context) { return } - // 验证短信验证码 - if !global.RuntimeSetting.DisablePhoneVerify { - if err := service.CheckPhoneCaptcha(param.Phone, param.Captcha); err != nil { - global.Logger.Errorf("service.CheckPhoneCaptcha err: %v\n", err) - response.ToErrorResponse(err) - return - } + if err := service.CheckPhoneCaptcha(param.Phone, param.Captcha); err != nil { + global.Logger.Errorf("service.CheckPhoneCaptcha err: %v\n", err) + response.ToErrorResponse(err) + return } // 执行绑定 @@ -383,7 +380,7 @@ func GetUserRechargeLink(c *gin.Context) { } - client, err := alipay.New(global.AppSetting.AlipayAppID, global.AppSetting.AlipayPrivateKey, true) + client, err := alipay.New(global.AlipaySetting.AppID, global.AlipaySetting.PrivateKey, true) // 将 key 的验证调整到初始化阶段 if err != nil { global.Logger.Errorf("alipay.New err: %v\n", err) @@ -462,7 +459,7 @@ func AlipayNotify(c *gin.Context) { response := app.NewResponse(c) c.Request.ParseForm() - aliClient, err := alipay.New(global.AppSetting.AlipayAppID, global.AppSetting.AlipayPrivateKey, true) + aliClient, err := alipay.New(global.AlipaySetting.AppID, global.AlipaySetting.PrivateKey, true) // 将 key 的验证调整到初始化阶段 if err != nil { global.Logger.Errorf("alipay.New err: %v\n", err) diff --git a/internal/service/comment.go b/internal/service/comment.go index 9be69089..0d745eb8 100644 --- a/internal/service/comment.go +++ b/internal/service/comment.go @@ -116,7 +116,7 @@ func CreatePostComment(ctx *gin.Context, userID int64, param CommentCreationReq) for _, item := range param.Contents { // 检查附件是否是本站资源 if item.Type == model.CONTENT_TYPE_IMAGE || item.Type == model.CONTENT_TYPE_VIDEO || item.Type == model.CONTENT_TYPE_ATTACHMENT { - if strings.Index(item.Content, "https://"+global.AliossSetting.AliossDomain) != 0 { + if strings.Index(item.Content, "https://"+global.AliOSSSetting.Domain) != 0 { continue } } diff --git a/internal/service/post.go b/internal/service/post.go index e375fc03..a3711b73 100644 --- a/internal/service/post.go +++ b/internal/service/post.go @@ -68,7 +68,7 @@ func (p *PostContentItem) Check() error { // 检查附件是否是本站资源 if p.Type == model.CONTENT_TYPE_IMAGE || p.Type == model.CONTENT_TYPE_VIDEO || p.Type == model. CONTENT_TYPE_ATTACHMENT { - if strings.Index(p.Content, "https://"+global.AliossSetting.AliossDomain) != 0 { + if strings.Index(p.Content, "https://"+global.AliOSSSetting.Domain) != 0 { return fmt.Errorf("附件非本站资源") } } @@ -377,7 +377,7 @@ func GetPostCount(conditions *model.ConditionsT) (int64, error) { } func GetPostListFromSearch(q *core.QueryT, offset, limit int) ([]*model.PostFormated, int64, error) { - queryResult, err := ds.QueryAll(q, global.SearchSetting.ZincIndex, offset, limit) + queryResult, err := ds.QueryAll(q, global.ZincSetting.Index, offset, limit) if err != nil { return nil, 0, err } @@ -391,7 +391,7 @@ func GetPostListFromSearch(q *core.QueryT, offset, limit int) ([]*model.PostForm } func GetPostListFromSearchByQuery(query string, offset, limit int) ([]*model.PostFormated, int64, error) { - queryResult, err := ds.QuerySearch(global.SearchSetting.ZincIndex, query, offset, limit) + queryResult, err := ds.QuerySearch(global.ZincSetting.Index, query, offset, limit) if err != nil { return nil, 0, err } @@ -405,7 +405,7 @@ func GetPostListFromSearchByQuery(query string, offset, limit int) ([]*model.Pos } func PushPostToSearch(post *model.Post) { - indexName := global.SearchSetting.ZincIndex + indexName := global.ZincSetting.Index postFormated := post.Format() postFormated.User = &model.UserFormated{ @@ -456,7 +456,7 @@ func PushPostToSearch(post *model.Post) { } func DeleteSearchPost(post *model.Post) error { - indexName := global.SearchSetting.ZincIndex + indexName := global.ZincSetting.Index return ds.DelDoc(indexName, fmt.Sprintf("%d", post.ID)) } @@ -469,7 +469,7 @@ func PushPostsToSearch(c *gin.Context) { pages := math.Ceil(float64(totalRows) / float64(splitNum)) nums := int(pages) - indexName := global.SearchSetting.ZincIndex + indexName := global.ZincSetting.Index // 创建索引 ds.CreateSearchIndex(indexName) diff --git a/internal/service/service.go b/internal/service/service.go index b08d7fd6..5f50f546 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1,6 +1,7 @@ package service import ( + "github.com/rocboss/paopao-ce/global" "github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/dao" "github.com/rocboss/paopao-ce/pkg/zinc" @@ -8,9 +9,11 @@ import ( ) var ( - ds core.DataService + ds core.DataService + DisablePhoneVerify bool ) func Initialize(engine *gorm.DB, client *zinc.ZincClient) { ds = dao.NewDataService(engine, client) + DisablePhoneVerify = !global.CfgIf("Sms") } diff --git a/internal/service/user.go b/internal/service/user.go index dde7d49c..aa6c2f39 100644 --- a/internal/service/user.go +++ b/internal/service/user.go @@ -136,6 +136,11 @@ func CheckPassword(password string) error { // CheckPhoneCaptcha 验证手机验证码 func CheckPhoneCaptcha(phone, captcha string) *errcode.Error { + // 如果禁止phone verify 则允许通过任意验证码 + if DisablePhoneVerify { + return nil + } + c, err := ds.GetLatestPhoneCaptcha(phone) if err != nil { return errcode.ErrorPhoneCaptcha diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 07f5e8c6..105c6297 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -7,7 +7,6 @@ import ( "time" "github.com/rocboss/paopao-ce/global" - "github.com/rocboss/paopao-ce/pkg/setting" "github.com/sirupsen/logrus" "gopkg.in/natefinch/lumberjack.v2" "gopkg.in/resty.v1" @@ -31,7 +30,7 @@ type ZincLogHook struct { func (hook *ZincLogHook) Fire(entry *logrus.Entry) error { index := &ZincLogIndex{ Index: map[string]string{ - "_index": global.LoggerSetting.LogZincIndex, + "_index": global.LoggerZincSetting.Index, }, } indexBytes, _ := json.Marshal(index) @@ -49,9 +48,9 @@ func (hook *ZincLogHook) Fire(entry *logrus.Entry) error { if _, err := client.SetDisableWarn(true).R(). SetHeader("Content-Type", "application/json"). - SetBasicAuth(global.LoggerSetting.LogZincUser, global.LoggerSetting.LogZincPassword). + SetBasicAuth(global.LoggerZincSetting.User, global.LoggerZincSetting.Password). SetBody(logStr). - Post(global.LoggerSetting.LogZincHost); err != nil { + Post(global.LoggerZincSetting.Host); err != nil { fmt.Println(err.Error()) } @@ -62,19 +61,19 @@ func (hook *ZincLogHook) Levels() []logrus.Level { return logrus.AllLevels } -func New(s *setting.LoggerSettingS) (*logrus.Logger, error) { +func New() (*logrus.Logger, error) { log := logrus.New() log.Formatter = &logrus.JSONFormatter{} - switch s.LogType { - case setting.LogFileType: + if global.CfgIf("LoggerFile") { + s := global.LoggerFileSetting log.Out = &lumberjack.Logger{ - Filename: s.LogFileSavePath + "/" + s.LogFileName + s.LogFileExt, + Filename: s.SavePath + "/" + s.FileName + s.FileExt, MaxSize: 600, MaxAge: 10, LocalTime: true, } - case setting.LogZincType: + } else if global.CfgIf("LoggerZinc") { log.Out = io.Discard log.AddHook(&ZincLogHook{}) } diff --git a/pkg/setting/seting_test.go b/pkg/setting/seting_test.go new file mode 100644 index 00000000..a834f841 --- /dev/null +++ b/pkg/setting/seting_test.go @@ -0,0 +1,41 @@ +package setting + +import ( + "testing" +) + +func TestUseDefault(t *testing.T) { + suites := map[string][]string{ + "default": {"Sms", "Alipay", "Zinc", "MySQL", "Redis", "AliOSS", "LogZinc"}, + "develop": {"Zinc", "MySQL", "AliOSS", "LogFile"}, + "slim": {"Zinc", "MySQL", "Redis", "AliOSS", "LogFile"}, + } + kv := map[string]string{ + "sms": "SmsJuhe", + } + features := newFeatures(suites, kv) + for _, data := range []struct { + key string + expect string + exist bool + }{ + {"Sms", "SmsJuhe", true}, + {"Alipay", "", true}, + {"Zinc", "", true}, + {"Redis", "", true}, + {"Database", "", false}, + } { + if v, ok := features.Cfg(data.key); ok != data.exist || v != data.expect { + t.Errorf("key: %s expect: %s exist: %t got v: %s ok: %t", data.key, data.expect, data.exist, v, ok) + } + } + for exp, res := range map[string]bool{ + "Sms": true, + "Sms = SmsJuhe": true, + "SmsJuhe": false, + } { + if ok := features.CfgIf(exp); res != ok { + t.Errorf("CfgIf(%s) want %t got %t", exp, res, ok) + } + } +} diff --git a/pkg/setting/settting.go b/pkg/setting/settting.go index bb22198b..d8f8d965 100644 --- a/pkg/setting/settting.go +++ b/pkg/setting/settting.go @@ -1,6 +1,7 @@ package setting import ( + "strings" "time" "github.com/spf13/viper" @@ -16,6 +17,19 @@ type LogType string const LogFileType LogType = "file" const LogZincType LogType = "zinc" +type LoggerFileSettingS struct { + SavePath string + FileName string + FileExt string +} + +type LoggerZincSettingS struct { + Host string + Index string + User string + Password string +} + type LoggerSettingS struct { LogType LogType LogFileSavePath string @@ -44,22 +58,30 @@ type AppSettingS struct { MaxPageSize int IsShastaTestnet bool TronApiKeys []string - SmsJuheKey string - SmsJuheTplID string - SmsJuheTplVal string - AlipayAppID string - AlipayPrivateKey string } -type RuntimeSettingS struct { - DisablePhoneVerify bool +type AlipaySettingS struct { + AppID string + PrivateKey string } -type SearchSettingS struct { - ZincHost string - ZincIndex string - ZincUser string - ZincPassword string +type SmsJuheSettings struct { + Key string + TplID string + TplVal string +} + +type FeaturesSettingS struct { + kv map[string]string + suites map[string][]string + features map[string]string +} + +type ZincSettingS struct { + Host string + Index string + User string + Password string } type DatabaseSettingS struct { @@ -75,6 +97,20 @@ type DatabaseSettingS struct { MaxIdleConns int MaxOpenConns int } + +type MySQLSettingS struct { + UserName string + Password string + Host string + DBName string + TablePrefix string + Charset string + ParseTime bool + LogLevel logger.LogLevel + MaxIdleConns int + MaxOpenConns int +} + type AliossSettingS struct { AliossAccessKeyID string AliossAccessKeySecret string @@ -83,6 +119,14 @@ type AliossSettingS struct { AliossDomain string } +type AliOSSSettingS struct { + AccessKeyID string + AccessKeySecret string + Endpoint string + Bucket string + Domain string +} + type RedisSettingS struct { Host string Password string @@ -117,3 +161,92 @@ func (s *Setting) ReadSection(k string, v interface{}) error { return nil } + +func (s *Setting) Unmarshal(objects map[string]interface{}) error { + for k, v := range objects { + err := s.vp.UnmarshalKey(k, v) + if err != nil { + return err + } + } + return nil +} + +func (s *Setting) FeaturesFrom(k string) *FeaturesSettingS { + sub := s.vp.Sub(k) + keys := sub.AllKeys() + + suites := make(map[string][]string) + kv := make(map[string]string, len(keys)) + for _, key := range sub.AllKeys() { + val := sub.Get(key) + switch v := val.(type) { + case string: + kv[key] = v + case []interface{}: + suites[key] = sub.GetStringSlice(key) + } + } + return newFeatures(suites, kv) +} + +func newFeatures(suites map[string][]string, kv map[string]string) *FeaturesSettingS { + features := &FeaturesSettingS{ + suites: suites, + kv: kv, + } + features.UseDefault() + return features +} + +func (f *FeaturesSettingS) UseDefault() { + defaultSuite := f.suites["default"] + f.Use(defaultSuite, true) +} + +func (f *FeaturesSettingS) Use(suite []string, noDefault bool) error { + if noDefault { + f.features = make(map[string]string) + } + features := f.flatFeatures(suite) + for _, feature := range features { + feature = strings.ToLower(feature) + f.features[feature] = f.kv[feature] + } + return nil +} + +func (f *FeaturesSettingS) flatFeatures(suite []string) []string { + features := make([]string, 0, len(suite)+10) + for s := suite[:]; len(s) > 0; s = s[:len(s)-1] { + if items, exist := f.suites[s[0]]; exist { + s = append(s, items...) + } + features = append(features, s[0]) + s[0] = s[len(s)-1] + } + return features +} + +// Cfg get value by key if exsit +func (f *FeaturesSettingS) Cfg(key string) (string, bool) { + key = strings.ToLower(key) + value, exist := f.features[key] + return value, exist +} + +// CfgIf check expression is true. if expression just have a string like +// `Sms` is mean `Sms` whether define in suite feature settings. expression like +// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value +// is `SmsJuhe`` +func (f *FeaturesSettingS) CfgIf(expression string) bool { + kv := strings.Split(expression, "=") + key := strings.Trim(strings.ToLower(kv[0]), " ") + v, ok := f.features[key] + if len(kv) == 2 && ok && strings.Trim(kv[1], " ") == v { + return true + } else if len(kv) == 1 && ok { + return true + } + return false +} diff --git a/pkg/zinc/zinc.go b/pkg/zinc/zinc.go index a7d9cc8d..f6d2de9f 100644 --- a/pkg/zinc/zinc.go +++ b/pkg/zinc/zinc.go @@ -71,12 +71,12 @@ type HitItem struct { } // NewClient 获取ZincClient新实例 -func NewClient(conf *setting.SearchSettingS) *ZincClient { +func NewClient(conf *setting.ZincSettingS) *ZincClient { return &ZincClient{ ZincClientConfig: &ZincClientConfig{ - ZincHost: conf.ZincHost, - ZincUser: conf.ZincUser, - ZincPassword: conf.ZincPassword, + ZincHost: conf.Host, + ZincUser: conf.User, + ZincPassword: conf.Password, }, } }