

### validator

[GitHub地址](github.com/go-playground/validator)

包验证器，可以用于验证参数是否符合规则，比如下方的比较验证，还有其他可以查看网址的详细介绍
go-zero自带的有校验器，可以使用

| Tag  | Description           |
| ---- | --------------------- |
| eq   | Equals                |
| gt   | Greater than          |
| gte  | Greater than or equal |
| lt   | Less Than             |
| lte  | Less Than or Equal    |
| ne   | Not Equal             |



### goverter

[GitHub地址](https://github.com/jmattheis/goverter)

类型转换器，可以用于类型的转换，比如下面的代码

```go
func (l *CreatePopupLogic) CreatePopup(in *backgroundrpcmodel.ResPopup) (*backgroundrpcmodel.ResResult, error) {
    _, err := l.svcCtx.PopupModel.Insert(l.ctx, u.Convert.SysPopupR2S(in.Info))
    if err != nil {
       return nil, rerr.NewFromSQL(err)
    }
    return &backgroundrpcmodel.ResResult{
       Result: true,
    }, nil
}
```

使用

```
goverter gen .
```



### asynq

[GitHub网址](https://github.com/hibiken/asynq)

- 入队流程

  ```go
  payload := &jobtype.xxxPayload{}
  payloadByte, err := jsoniter.Marshal(payload)
  if err != nil {
  	logt.Error("xxx jsoniter.Marshal err:", err)
  	return nil, zerr.New(rescode.DataFormatConversionError)
  }
  	_, err = l.svcCtx.AsynqClient.Enqueue(asynq.NewTask(jobtype.xxx, payloadBytes, asynq.Queue(consts.QueueLow)))
  if err != nil {
  	logt.Error("xxx enqueue err:", err)
  	return nil, zerr.New(rescode.EnqueueErr)
  }
  ```

- 自行定义了队列优先级，在入队的时候可以加参数进行选择

  ```
  consts.QueueCritical: 6,
  consts.QueueDefault:  3,
  consts.QueueLow:      1,
  ```

- 处理前流程（反序列化,获取数据）

  ```go
  var payload jobtype.xxx
  err := json.Unmarshal(task.Payload(), &payload)
  if err != nil {
      logt.Error("xxx unmarshal payload err:", err)
      return zerr.New(rescode.DataFormatConversionError)
  }
  ```



### gorm

[官网文档](https://gorm.io/zh_CN/docs/)

**使用gorm + sqlx，但是复用sql连接**

```go
func NewServiceContext(c config.Config) *ServiceContext {
    logx.Infof("Cache config: %+v", c.CacheRedis)

    gormDB, err := gorm.Open(postgres.Open(c.Database.DataSource), &gorm.Config{})
    if err != nil {
       msg := fmt.Sprintf("连接数据库失败 %s ", err.Error())
       logx.Error(msg)
       panic(msg)
    }
    sqlDB, err := gormDB.DB()
    if err != nil {
       msg := fmt.Sprintf("获取底层连接失败: %s", err.Error())
       logx.Error(msg)
       panic(msg)
    }
    sqlxConn := sqlx.NewSqlConnFromDB(sqlDB)
    return &ServiceContext{
       Config:        c,
       UserAuthModel: models.NewUserAuthModel(sqlxConn, c.CacheRedis, gormDB),
    }
}
```



### excelize

读写Excel的Go库

[github](https://github.com/qax-os/excelize)

#### 创建工作簿

```go
    f := excelize.NewFile()
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
    // 创建一个新的Sheet,返回的index为该工作簿的索引
    index, err := f.NewSheet("SheetName")
    if err != nil {
        return fmt.Errorf("创建Sheet失败: %w", err)
    }
```

#### 打开文件

```go
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		return fmt.Errorf("打开 Excel失败: %w", err)
	}
	defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
```

#### 写入cell值

```go
  f.SetCellValue("SheetName", "B2", 100)
```

#### 设置工作簿默认活动工作表

```go
f.SetActiveSheet(index)
```

#### 创建或更新excel表

```go
    if err := f.SaveAs("Book1.xlsx"); err != nil {
        return fmt.Errorf("保存失败: %w", err)
    }
```

#### 获取指定cell值

```go
    cell, err := f.GetCellValue("Sheet1", "B2")
    if err != nil {
        return fmt.Errorf("读取cell失败: %w", err)
    }
    fmt.Println(cell)
```

#### 获取所有工作簿的cell值（二维数组）

```go
    rows, err := f.GetRows("Sheet1")
    if err != nil {
        return fmt.Errorf("读取失败: %w", err)
    }
    for _, row := range rows {
        for _, colCell := range row {
            fmt.Print(colCell, "\t")
        }
        fmt.Println()
    }
```

