www.toutiao.im
mygo |-bin |-pkg |-src |-go.web.red |-comm_log comm_log.go |-handler red_handler.go red_parameter_validate.go user_handler.go |-module db_init.go user_module.go |-system_cfg system_cfg_process.go |-system_notify system_notify_process.go conf.ini web.go
comm_log.go
package comm_log import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "time" ) var default_log *Zlog type Zlog struct { zap_log *zap.SugaredLogger curr_log_level zap.AtomicLevel } func Init(program_name,log_level_str,log_path string) *Zlog { encoder_cfg := zapcore.EncoderConfig{ TimeKey: "T",LevelKey: "L",NameKey: "N",CallerKey: "C",MessageKey: "M",StacktraceKey: "S",LineEnding: zapcore.DefaultLineEnding,EncodeLevel: zapcore.CapitalLevelEncoder,EncodeTime: time_encoder,EncodeDuration: zapcore.StringDurationEncoder,EncodeCaller: zapcore.ShortCallerEncoder,} log_level := zap.NewAtomicLevel() log_level.UnmarshalText([]byte(log_level_str)) custom_cfg := zap.Config{ Level: log_level,Development: true,Encoding: "console",EncoderConfig: encoder_cfg,OutputPaths: []string{log_path},ErrorOutputPaths: []string{"stderr"},} logger,_ := custom_cfg.Build() new_logger := logger.Named(program_name) sugar := new_logger.Sugar() default_log = &Zlog{ zap_log: sugar,curr_log_level : log_level,} return default_log } func Sync() { default_log.zap_log.Sync() } func Debug(msg string,keysAndValues ...interface{}) { default_log.zap_log.Debugw(msg,keysAndValues...) } func Info(msg string,keysAndValues ...interface{}) { default_log.zap_log.Infow(msg,keysAndValues...) } func Warn(msg string,keysAndValues ...interface{}) { default_log.zap_log.Warnw(msg,keysAndValues...) } func Error(msg string,keysAndValues ...interface{}) { default_log.zap_log.Errorw(msg,keysAndValues...) } func Set_log_level(log_level string) { default_log.curr_log_level.UnmarshalText([]byte(log_level)) } func Get_log_level() string { return default_log.curr_log_level.String() } func time_encoder(t time.Time,enc zapcore.PrimitiveArrayEncoder) { enc.AppendString("[" + t.Format("2006-01-02 15:04:05") + "]") }
red_handler.go
package handler import "github.com/labstack/echo" // http response status_code const( SUCCESS = "0" DBERROR = "1" SERVERERROR = "2" REQUESTERROR = "3" ) const DATAFORMAT = "2006-01-02 15:04:05" type ( Base_req_entity struct { TrackId string `validate:"lte_len=20"` } Base_res_entity struct { Status_code string `json:"status_code"` } ) type Red_handle interface { Access_path() string Support_method() []string Handler(cont echo.Context) error } type Red_com_handle struct { Path string Handler_works map[string]func(echo.Context)(error) } func (this *Red_com_handle)Access_path() string { return this.Path } func (this *Red_com_handle)Support_method() []string { sup_methods := []string{} for method,_ := range this.Handler_works { sup_methods = append(sup_methods,method) } return sup_methods } func (this *Red_com_handle)Handler(cont echo.Context) (ret error) { return this.Handler_works[cont.Request().Method](cont) }
red_parameter_validate.go
package handler import ( "github.com/go-playground/validator" "reflect" "strconv" "unicode/utf8" "fmt" ) var Validate *validator.Validate func init() { Validate = validator.New() Validate.RegisterValidation("lte_len",LteLengthOf) } func LteLengthOf(fl validator.FieldLevel) bool { field := fl.Field() param := fl.Param() switch field.Kind() { case reflect.String: p,_ := strconv.ParseInt(param,64) return int64(utf8.RuneCountInString(field.String())) <= p } panic(fmt.Sprintf("Bad field type %T",field.Interface())) }
user_handler.go
package handler import ( "github.com/labstack/echo" "net/http" "fmt" "go.web.red/module" ) var User_default *User_entity func init() { User_default = &User_entity{ module: new(module.User),Red_com_handle: Red_com_handle{ Path: "user",Handler_works: make(map[string]func(echo.Context)(error)),},} User_default.Handler_works[echo.GET] = User_default.get User_default.Handler_works[echo.POST] = User_default.post User_default.Handler_works[echo.DELETE] = User_default.delete User_default.Handler_works[echo.PUT] = User_default.put } type User_entity struct { Red_com_handle module *module.User } type ( User_param struct { Name string `json:"name" validate:"required,lte_len=50"` Age int `json:"age"` Address string `json:"address"` Status int `json:"status"` Created string `json:"create_time"` Modified string `json:"update_time"` } User_param_all struct { User_param Id int `json:"id" validate:"required,lte_len=10"` } User_get_req struct { Base_req_entity Id int Status int } User_get_res struct { Base_res_entity Users []User_param_all `json:"users"` } User_post_req struct { Base_req_entity User_param } User_put_req struct { Base_req_entity User_param_all } User_delete_req struct { Base_req_entity Id int `validate:"required"` } ) func (entity *User_entity) get(cont echo.Context) error { req := User_get_req{ Base_req_entity: Base_req_entity{ TrackId: cont.QueryParam("trackId"),Id: cont.QueryParam("id"),Status: cont.QueryParam("status"),} res := User_get_res{} if err := Validate.Struct(&req); err != nil { res.Status_code = REQUESTERROR return cont.JSON(http.StatusBadRequest,res) } queryParams := map[string]interface{}{} queryParams["status"] = req.Status users,err := entity.module.Query(req.TrackId,queryParams) if err != nil { res.Status_code = DBERROR return cont.JSON(http.StatusBadRequest,res) } if len(users) == 0 { res.Users = []User_param_all{} } else { for _,user := range users { res.Users = append(res.Users,User_param_all{ User_param: User_param{ Name: user.Name,Age: user.Age,Address: user.Address,Status: user.Status,Modified: user.Modified.Format(DATAFORMAT),Created: user.Created.Format(DATAFORMAT),Id: user.Id,}) } } res.Status_code = SUCCESS return cont.JSON(http.StatusOK,res) } func (entity *User_entity) post(cont echo.Context) error { req := new(User_post_req) res := new(Base_res_entity) if err := cont.Bind(req); err != nil { fmt.Println(err.Error()) res.Status_code = REQUESTERROR return cont.JSON(http.StatusBadRequest,res) } req.TrackId = cont.QueryParam("trackId") if err := Validate.Struct(req); err != nil { fmt.Println(err.Error()) res.Status_code = REQUESTERROR return cont.JSON(http.StatusBadRequest,res) } user := module.User{ Name: req.Name,Age: req.Age,Address: req.Address,Status: req.Status,} err := entity.module.Save(req.TrackId,user) if err != nil { fmt.Println(err.Error()) res.Status_code = DBERROR return cont.JSON(http.StatusBadRequest,res) } res.Status_code = SUCCESS return cont.JSON(http.StatusOK,res) } func (entity *User_entity) delete(cont echo.Context) error { req := User_delete_req{ Base_req_entity: Base_req_entity{ TrackId: cont.QueryParam("trackId"),} res := Base_res_entity{} if err := Validate.Struct(&req); err != nil { res.Status_code = REQUESTERROR return cont.JSON(http.StatusBadRequest,res) } err := entity.module.Delete(req.TrackId,req.Id) if err != nil { res.Status_code = DBERROR return cont.JSON(http.StatusBadRequest,res) } func (entity *User_entity) put(cont echo.Context) error { req := new(User_put_req) res := new(Base_res_entity) if err := cont.Bind(req); err != nil { fmt.Println(err.Error()) res.Status_code = REQUESTERROR return cont.JSON(http.StatusBadRequest,res) } user := module.User{ Id: req.Id,Name: req.Name,} err := entity.module.Update(req.TrackId,res) }
db_init.go
package module import ( "github.com/go-sql-driver/MysqL" "github.com/jinzhu/gorm" "time" "fmt" "errors" "go.web.red/system_cfg" ) var Db_instance *gorm.DB var ( SAVE_AFFECTED_ZERO_ERROR = errors.New("save affected row 0") UPDATE_AFFECTED_ZERO_ERROR = errors.New("update affected row 0") DELETE_AFFECTED_ZERO_ERROR = errors.New("delete affected row 0") ) const ( STATUS_NORMAL = 1 STATUS_SUSPEND = 2 STATUS_ABANDON = 3 ) func init() { ip,_ := system_cfg.System_cfg.GetValue("MysqL","ip") port,"port") user,"user") pwd,"pwd") db,"db") dsn := MysqL.Config{ Addr: ip+":"+port,User: user,Passwd: pwd,Net: "tcp",DBName: db,Params: map[string]string{"charset": "utf8","parseTime": "True","loc": "Local"},Timeout: time.Duration(5 * time.Second),} db,err := gorm.Open("MysqL",dsn.FormatDSN()) if err != nil { fmt.Println(err) panic(err.Error()) } Db_instance = db }
user_module.go
package module import ( "time" ) type User struct { Id int `grom:"primary_key"` Name string `grom:"not null;unique"` Age int `grom:"not null"` Address string Status int `grom:"not null"` Created time.Time `gorm:"column:created"` Modified time.Time `gorm:"column:modified"` } func (user *User) Save(trackId string,user User) error { res := Db_instance.Create(&user) if res.Error != nil { return res.Error } if res.RowsAffected == 0 { return SAVE_AFFECTED_ZERO_ERROR } return nil } func (user *User) Update(trackId string,user User) error { record := User{} updates := map[string]interface{}{ "name": user.Name,"age": user.Age,"address": user.Address,"status": user.Status,} res := Db_instance.Model(&record).Where("id=?",user.Id).Update(updates) if res.Error != nil { return res.Error } if res.RowsAffected == 0 { return UPDATE_AFFECTED_ZERO_ERROR } return nil } func (user *User) Delete(trackId string,id int) error { record := User{} res := Db_instance.Where("id=?",id).Delete(record) if res.Error != nil { return res.Error } if res.RowsAffected == 0 { return DELETE_AFFECTED_ZERO_ERROR } return nil } func (user *User) Query(trackId string,queryParams map[string]interface{}) ([]User,error) { records := [] User{} res := Db_instance.Where(queryParams).Find(&records) if res.Error != nil { return []User{},res.Error } return records,nil }
system_cfg_process.go
package system_cfg import ( "github.com/Unknwon/goconfig" "log" "fmt" "os" "path/filepath" ) var System_cfg *goconfig.ConfigFile func init() { fileAbsPath := filepath.Dir(os.Args[0]) fmt.Printf("current path = %s\n",fileAbsPath) cfg,err := goconfig.LoadConfigFile(fileAbsPath + "/conf.ini") if err != nil{ log.Fatalf("load config conf.ini error = %s",err) } System_cfg = cfg }
system_notify_process.go
package system_notify import ( "strings" "github.com/go-gomail/gomail" "html/template" "bytes" "os_adv_engine/system_cfg" "strconv" "fmt" "encoding/json" "net/http" "io/IoUtil" ) type CsNotify interface { SendNotify(string,string) bool } var notifyList []CsNotify func init() { smtp_s_str,_ := system_cfg.System_cfg.GetValue("email_notify","smtp_server") smtp_p_str,"smtp_port") sender_str,"sender") passwd_str,"passwd") receivers := []string{} receiveRSStr,"receivers") for _,receiverStr := range strings.Split(receiveRSStr,";") { receivers = append(receivers,strings.TrimSpace(receiverStr)) } smtp_p_int,_ := strconv.Atoi(smtp_p_str) en := &EmailNotify{ smtp_s: smtp_s_str,smtp_p: smtp_p_int,fromer: sender_str,toers: receivers,ccers: []string{},e_user: strings.Split(sender_str,"@")[0],e_passwd: passwd_str,} notifyList = append(notifyList,en) ln := &LanxinNotify{ app_id:"",app_secret:"",host:"",tousers:"",ln) } func Notify(title string,content string) { for _,value := range notifyList { value.SendNotify(title,content) } } type ( EmailNotify struct { smtp_s string smtp_p int fromer string toers []string ccers []string e_user string e_passwd string } LanxinNotify struct { app_id string app_secret string host string tousers string } ) func (ln * LanxinNotify)SendNotify(title string,content string) bool { return true } func (en *EmailNotify)SendNotify(title string,content string) bool { msg := gomail.NewMessage() msg.SetHeader("From",en.fromer) msg.SetHeader("To",en.toers...) msg.SetHeader("Subject",title) msg.SetBody("text/html",en.renderNotify(content)) mailer := gomail.NewDialer(en.smtp_s,en.smtp_p,en.e_user,en.e_passwd) if err := mailer.DialAndSend(msg); err != nil { panic(err) } return true } func (en *EmailNotify) renderNotify(content string) string { tplStr := `<html> <body> {{.}} </table> </body> </html>` outBuf := &bytes.Buffer{} tpl := template.New("email notify template") tpl,_ = tpl.Parse(tplStr) tpl.Execute(outBuf,content) return outBuf.String() } func httpGet(url string) string{ resp,err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() body,err := IoUtil.ReadAll(resp.Body) return fmt.Sprintf(string(body)) }
web.go
package main import ( "github.com/labstack/echo" "github.com/go-playground/validator" "strings" "log" "go.web.red/red_handler" ) type ( handle_entity struct { h_func_set []string handler func(echo.Context)(error) } handle_bundle struct { root_url string api_ver string h_path_set map[string]handle_entity validate *validator.Validate } ) var Default_hb *handle_bundle func init() { Default_hb = &handle_bundle{ root_url: "/ads/api",api_ver: "v1",h_path_set: make(map[string]handle_entity),} var handlers []handler.Red_handle handlers = append(handlers,) } func main() { es := echo.New() for path,entity := range Default_hb.h_path_set { paths := []string{Default_hb.root_url,Default_hb.api_ver,path} full_path := strings.Join(paths,"/") es.Match(entity.h_func_set,full_path,entity.handler) } log.Fatalln(es.Start(":8888")) }
conf.ini
[email_notify] smtp_server = smtp.qq.com smtp_port = 25 sender = xx@qq.com passwd = receivers = yy@qq.com;zz@qq.com [MysqL] ip = port = user = pwd = db =
代码见 http://git.toutiao.im