O

opp

opp (opportunity) 机会手机服务端

庄敏学提交了 · dc33f96a 合并分支 'dev' 到 'master'

目录

项目说明

opp (opportunity) : 机会app服务端项目; 企业员工可以主动的把机会展示出来,另外有员工能把展示的机会抓 住、变现,从而形成自主的供需循环。使企业的运转正向向前进

代码声明

命名规范

1.包名

*
package名和目录保持一致,需避免和标准库冲突
小写
*
package comm

2.命名

package pkg

*1.错误*
/*
定义在包的首部,所有错误都定义在一起,
并且以Err开头
*/
var ErrFooBar = fmt.Errorf("pkg: ...")

*2.变量*
/*
采用驼峰命名
*/
var fooBar int

*3.常量*
/*
大写+下划线
*/
var(
    FOO = 1
    BAR = 2
    FOO_BAR = 3
)

*4.结构*
/*
采用驼峰命名法
*/
type FooBar struct{
    foo int
    Bar string
}


*5.方法接口*
/*
采用驼峰命名法
非对外方法,首字母需为小写
*/
func foo(){}
func Foo(){}

3.目录结构

* conf          //配置
  * dev.conf
  * prod.conf
* controller    //控制器
  * v1
    * auth.go
* internal
  * repository  //存储层
    * user.go
    * *_mock.go
* model         //模型
* protocol      //协议层
* routers       //路由
* service       //逻辑层
  * auth
* static        //静态数据
* views         //视图

* main.go
* Dockerfile
* README.md
* *.sh         //脚本

项目约定

  1. 入参跟返回值都要定义一个协议结构 protocol.XxxRequest *protocol.XxxResponse,方便扩展
  2. 函数方法的变量都定义在函数的头几行 var( ... )
  3. 服务调用尽量封装成接口,方便测试扩展 比如:ISmsServe{ Send() error }
  4. 公用的基础代码库,需要做一下封装放在 gocomm ,方便在其他项目中调用
  5. 可以使用代码生成固定格式, 项目地址 脚本:.\gencode.exe new -c Auth -m Login
package  pkg
//Login
func(this *AuthController)Login(){
    var msg *protocol.ResponseMessage
    defer func(){
        this.Resp(msg)
    }()
    var request *protocol.LoginRequest
    if err:=json.Unmarshal(this.ByteBody,&request);err!=nil{
        log.Error(err)
        msg = protocol.ReturnResponse(1)
        return
    }
    if b,m :=this.Valid(request);!b{
        msg = m
        return
    }
    msg = this.GenMessage(auth.Login(request))
}

/*Login */
type LoginRequest struct {
    Xxx string`json:"xxx" valid:"Required"`
}
type LoginResponse struct {
}

func Login(request *protocol.LoginRequest)(rsp *protocol.LoginResponse,err error){
    var (

    )
    rsp =&protocol.LoginResponse{}
    return
}

注意事项

  1. 启动一个 groutine(eg:go func(){}()),需要在函数内进行 recover,不然 groutine 里面 panic,会导致外部程序一起崩溃掉;
  2. 当接受者是 map, chan, func, 不要使用指针传递,因为它们本身就是引用类型
  3. 当接受者类型是一个结构体并且很庞大,或者是一个大数组,建议使用指针传递来提高性能,其他场景使用值传递即可
  4. 当接受者是一个结构体,并且包含了 sync.Mutex 或者类似的用于同步的成员。必须使用指针传递,避免成员拷贝
  5. 当函数内部需要修改接受者,必须使用指针传递
  6. 声明空的 slice 应该使用下面的格式: var t []string 不要使用 t := []string{} ,前者声明了一个 nil slice 而后者是一个长度为 0 的非 nil 的 slice。