提交 f2ebe6f0 authored 作者: mooncake's avatar mooncake

update

上级 fe03d45d
...@@ -38,7 +38,9 @@ func New() *gin.Engine { ...@@ -38,7 +38,9 @@ func New() *gin.Engine {
copier.Copy(&auth, c.Auth) copier.Copy(&auth, c.Auth)
}) })
validator.InstallTranslations() if err := validator.InstallTranslations(); err != nil {
logger.Fatalf("%+v", err)
}
r := gin.New() r := gin.New()
r.Use(middleware.CustomRecoveryWithLogger(logger.Get())) r.Use(middleware.CustomRecoveryWithLogger(logger.Get()))
......
package base
// import "strings"
// type Condition interface {
// SetWhere(k string, v []interface{})
// SetOr(k string, v []interface{})
// SetOrder(k string)
// SetJoinOn(t, on string) Condition
// }
// type GormCondition struct {
// GormPublic
// Join []*GormJoin
// }
// type GormPublic struct {
// Where map[string][]interface{}
// Order []string
// Or map[string][]interface{}
// }
// type GormJoin struct {
// Type string
// JoinOn string
// GormPublic
// }
// func (e *GormJoin) SetJoinOn(t, on string) Condition {
// return nil
// }
// func (e *GormPublic) SetWhere(k string, v []interface{}) {
// if e.Where == nil {
// e.Where = make(map[string][]interface{})
// }
// e.Where[k] = v
// }
// func (e *GormPublic) SetOr(k string, v []interface{}) {
// if e.Or == nil {
// e.Or = make(map[string][]interface{})
// }
// e.Or[k] = v
// }
// func (e *GormPublic) SetOrder(k string) {
// if e.Order == nil {
// e.Order = make([]string, 0)
// }
// e.Order = append(e.Order, k)
// }
// func (e *GormCondition) SetJoinOn(t, on string) Condition {
// if e.Join == nil {
// e.Join = make([]*GormJoin, 0)
// }
// join := &GormJoin{
// Type: t,
// JoinOn: on,
// GormPublic: GormPublic{},
// }
// e.Join = append(e.Join, join)
// return join
// }
// type resolveSearchTag struct {
// Type string
// Column string
// Table string
// On []string
// Join string
// }
// // makeTag 解析search的tag标签
// func makeTag(tag string) *resolveSearchTag {
// r := &resolveSearchTag{}
// tags := strings.Split(tag, ";")
// var ts []string
// for _, t := range tags {
// ts = strings.Split(t, ":")
// if len(ts) == 0 {
// continue
// }
// switch ts[0] {
// case "type":
// if len(ts) > 1 {
// r.Type = ts[1]
// }
// case "column":
// if len(ts) > 1 {
// r.Column = ts[1]
// }
// case "table":
// if len(ts) > 1 {
// r.Table = ts[1]
// }
// case "on":
// if len(ts) > 1 {
// r.On = ts[1:]
// }
// case "join":
// if len(ts) > 1 {
// r.Join = ts[1]
// }
// }
// }
// return r
// }
package base
// const (
// OrderIgnoreCount = "ignore_count"
// )
// type IBaseDao interface {
// DB() *gorm.DB
// Create(ctx context.Context, m any) error
// CreateTx(ctx context.Context, tx *gorm.DB, model any) error
// Save(ctx context.Context, model any) error
// SaveTx(ctx context.Context, tx *gorm.DB, model any) error
// UpdateWhere(ctx context.Context, model any, where any, updates map[string]any) error
// UpdateWhereTx(ctx context.Context, tx *gorm.DB, model any, where any, updates map[string]any) error
// UpdateWhereModel(ctx context.Context, where any, updates any) error
// UpdateWhereModelTx(ctx context.Context, tx *gorm.DB, where any, updates any) error
// UpdateById(ctx context.Context, model any) error
// UpdateByIdTx(ctx context.Context, tx *gorm.DB, model any) error
// DelModel(ctx context.Context, model any) error
// DelWhereTx(ctx context.Context, tx *gorm.DB, model any) error
// DelWhereMap(ctx context.Context, model any, where map[string]any) error
// DelWhereMapTx(ctx context.Context, tx *gorm.DB, model any, where map[string]any) error
// DelIds(ctx context.Context, model any, ids any) error
// DelIdsTx(ctx context.Context, tx *gorm.DB, model any, ids any) error
// Get(ctx context.Context, model any, conds ...interface{}) error
// GetByWhere(ctx context.Context, where any, models any) error
// GetByMap(ctx context.Context, where map[string]any, models any) error
// PageQuery(pageSize int, cb func(pageSize, offset int, size *int) error) error
// Transaction(fc func(tx *gorm.DB) error, opts ...*sql.TxOptions) error
// }
// func NewDao(db *gorm.DB) *BaseDao {
// return &BaseDao{
// db: db,
// }
// }
// type BaseDao struct {
// db *gorm.DB
// }
// func (x *BaseDao) DB() *gorm.DB {
// return x.db
// }
// func (x *BaseDao) Transaction(fc func(tx *gorm.DB) error, opts ...*sql.TxOptions) error {
// err := x.DB().Transaction(fc, opts...)
// if err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (x *BaseDao) PageQuery(pageSize int, cb func(pageSize, offset int, size *int) error) error {
// pageIndex := 1
// size := 0
// if pageSize == 0 {
// pageSize = 1000
// }
// for {
// offset := (pageIndex - 1) * pageSize
// if err := cb(pageSize, offset, &size); err != nil {
// return err
// }
// if size == 0 || size < pageSize {
// break
// }
// pageIndex++
// }
// return nil
// }
// /*
// * 创建 结构体 m
// */
// func (s *BaseDao) Create(ctx context.Context, m any) error {
// if err := s.DB().WithContext(ctx).Create(m).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (s *BaseDao) CreateTx(ctx context.Context, tx *gorm.DB, model any) error {
// if err := tx.WithContext(ctx).Create(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 更新整个模型 结构体model 注意空值
// */
// func (s *BaseDao) Save(ctx context.Context, model any) error {
// if err := s.DB().WithContext(ctx).Save(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (s *BaseDao) SaveTx(ctx context.Context, tx *gorm.DB, model any) error {
// if err := tx.WithContext(ctx).Save(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 条件跟新
// */
// func (s *BaseDao) UpdateWhere(ctx context.Context, model any, where any, updates map[string]any) error {
// if err := s.DB().WithContext(ctx).Model(model).Where(where).Updates(updates).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (s *BaseDao) UpdateWhereTx(ctx context.Context, tx *gorm.DB, model any, where any, updates map[string]any) error {
// if err := tx.WithContext(ctx).Model(model).Where(where).Updates(updates).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 模型更新
// * 注意!!!零值不会更新,建议使用 UpdateWhere、UpdateWhereTx
// */
// func (s *BaseDao) UpdateWhereModel(ctx context.Context, where any, updates any) error {
// if err := s.DB().WithContext(ctx).Where(where).Updates(updates).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 模型更新
// * 注意!!!零值不会更新,建议使用 UpdateWhere、UpdateWhereTx
// */
// func (s *BaseDao) UpdateWhereModelTx(ctx context.Context, tx *gorm.DB, where any, updates any) error {
// if err := tx.WithContext(ctx).Where(where).Updates(updates).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 根据模型id更新
// * 注意!!!零值不会更新,建议使用 UpdateWhere、UpdateWhereTx
// */
// func (s *BaseDao) UpdateById(ctx context.Context, model any) error {
// if err := s.DB().WithContext(ctx).Updates(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 根据模型id更新
// * 注意!!!零值不会更新,建议使用 UpdateWhere、UpdateWhereTx
// */
// func (s *BaseDao) UpdateByIdTx(ctx context.Context, tx *gorm.DB, model any) error {
// if err := tx.WithContext(ctx).Updates(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// // DelModel model id 不能为空
// func (s *BaseDao) DelModel(ctx context.Context, model any) error {
// if err := s.DB().WithContext(ctx).Delete(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (s *BaseDao) DelWhereTx(ctx context.Context, tx *gorm.DB, model any) error {
// if err := tx.WithContext(ctx).Delete(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 条件删除,模型 where 为map
// */
// func (s *BaseDao) DelWhereMap(ctx context.Context, model any, where map[string]any) error {
// if err := s.DB().WithContext(ctx).Where(where).Delete(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (s *BaseDao) DelWhereMapTx(ctx context.Context, tx *gorm.DB, model any, where map[string]any) error {
// if err := tx.WithContext(ctx).Where(where).Delete(model).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * id 可以是xsf.ID 也可以是[]xsf.ID
// */
// func (s *BaseDao) DelIds(ctx context.Context, model any, ids any) error {
// if err := s.DB().WithContext(ctx).Delete(model, ids).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// func (s *BaseDao) DelIdsTx(ctx context.Context, tx *gorm.DB, model any, ids any) error {
// if err := tx.WithContext(ctx).Delete(model, ids).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 根据id获取模型
// */
// func (s *BaseDao) Get(ctx context.Context, model any, conds ...interface{}) error {
// if err := s.DB().WithContext(ctx).First(model, conds...).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /**
// * 条件查询
// * where: where 查询条件model
// * models: 代表查询返回的model数组
// */
// func (s *BaseDao) GetByWhere(ctx context.Context, where any, models any) error {
// if err := s.DB().WithContext(ctx).Where(where).Find(models).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /**
// * 列表条件查询
// * where: 条件查询
// * models: 代表查询返回的model数组
// */
// func (s *BaseDao) GetByMap(ctx context.Context, where map[string]any, models any) error {
// if err := s.DB().WithContext(ctx).Where(where).Find(models).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /**
// * 条数查询
// * model: 查询条件
// * count: 查询条数
// */
// func (s *BaseDao) Count(ctx context.Context, model any, count *int64) error {
// if err := s.DB().WithContext(ctx).Model(model).Where(model).Count(count).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /**
// * 条数查询
// * model: 查询条件
// * count: 查询条数
// */
// func (s *BaseDao) CountByMap(ctx context.Context, where map[string]any, model any, count *int64) error {
// if err := s.DB().WithContext(ctx).Model(model).Where(where).Count(count).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /**
// * 查询
// * where 实现Query接口
// */
// func (s *BaseDao) Query(ctx context.Context, where Query, models any) error {
// if err := s.DB().WithContext(ctx).Scopes(s.MakeCondition(where)).Find(models).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// // Page 分页查询
// func (s *BaseDao) Page(ctx context.Context, where Query, models any, limit, offset int) error {
// if err := s.DB().WithContext(ctx).Scopes(s.MakeCondition(where)).Limit(limit).Offset(offset).Find(models).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 分页获取
// */
// func (s *BaseDao) QPage(ctx context.Context, where any, data any, total *int64, limit, offset int) error {
// if err := s.DB().WithContext(ctx).Where(where).Limit(limit).Offset(offset).
// Find(data).Limit(-1).Offset(-1).Count(total).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 分页获取
// */
// func (s *BaseDao) QueryPage(ctx context.Context, where Query, models any, total *int64, limit, offset int) error {
// if err := s.DB().WithContext(ctx).Scopes(s.MakeCondition(where)).Limit(limit).Offset(offset).
// Find(models).Limit(-1).Offset(-1).Count(total).Error; err != nil {
// return xerror.New(err.Error())
// }
// return nil
// }
// /*
// * 分页组装
// */
// func (s *BaseDao) Paginate(pageSize, pageIndex int) func(db *gorm.DB) *gorm.DB {
// return func(db *gorm.DB) *gorm.DB {
// offset := (pageIndex - 1) * pageSize
// if offset < 0 {
// offset = 0
// }
// return db.Offset(offset).Limit(pageSize)
// }
// }
// /**
// * chunk 查询
// */
// func (s *BaseDao) Chunk(ctx context.Context, db *gorm.DB, size int, callback func(records []map[string]interface{}) error) error {
// var offset int
// for {
// var records []map[string]interface{}
// // 检索 size 条记录
// if err := db.WithContext(ctx).Limit(size).Offset(offset).Find(&records).Error; err != nil {
// return xerror.New(err.Error())
// }
// // 如果没有更多记录,则退出循环
// if len(records) == 0 {
// break
// }
// // 调用回调函数处理记录
// if err := callback(records); err != nil {
// return err
// }
// // 更新偏移量
// offset += size
// }
// return nil
// }
// /**
// * 查询条件组装
// */
// func (s *BaseDao) MakeCondition(q Query) func(db *gorm.DB) *gorm.DB {
// return func(db *gorm.DB) *gorm.DB {
// condition := &GormCondition{
// GormPublic: GormPublic{},
// Join: make([]*GormJoin, 0),
// }
// driver := "mysql"
// ResolveSearchQuery(driver, q, condition, q.TableName())
// for _, join := range condition.Join {
// if join == nil {
// continue
// }
// db = db.Joins(join.JoinOn)
// for k, v := range join.Where {
// db = db.Where(k, v...)
// }
// for k, v := range join.Or {
// db = db.Or(k, v...)
// }
// for _, o := range join.Order {
// db = db.Order(o)
// }
// }
// for k, v := range condition.Where {
// db = db.Where(k, v...)
// }
// for k, v := range condition.Or {
// db = db.Or(k, v...)
// }
// for _, o := range condition.Order {
// db = db.Order(o)
// }
// return db
// }
// }
package base
// /*
// * 条件查询结构体,结果体非零值字段将查询
// * @Param type
// * eq 等于(默认不填都可以)
// * like 包含
// * gt / gte 大于 / 大于等于
// * lt / lte 小于 / 小于等于
// * left / ileft :like xxx%
// * right / iright : like %xxx
// * in
// * isnull
// * order 排序 e.g. order[key]=desc order[key]=asc
// * "-" 忽略该字段
// * @Param table
// * table 不填默认取 TableName值
// * @Param column
// * column 不填以结构体字段
// * eg:
// * type ExampleQuery struct{
// * Name string `json:"name" query:"type:like;column:name;table:exampale"`
// * Status int `json:"status" query:"type:gt"`
// * }
// * func (ExampleQuery) TableName() string {
// * return "ExampleQuery"
// * }
// */
// type Query interface {
// TableName() string
// }
// const (
// // FromQueryTag tag标记
// FromQueryTag = "query"
// // Mysql 数据库标识
// Mysql = "mysql"
// // Postgres 数据库标识
// Postgres = "pgsql"
// )
// // ResolveSearchQuery 解析
// /**
// * eq 等于(默认不填都可以)
// * like 包含
// * gt / gte 大于 / 大于等于
// * lt / lte 小于 / 小于等于
// * left / ileft :like xxx%
// * right / iright : like %xxx
// * in
// * isnull
// * order 排序 e.g. order[key]=desc order[key]=asc
// */
// func ResolveSearchQuery(driver string, q any, condition Condition, pTName string) {
// qType := reflect.TypeOf(q)
// qValue := reflect.ValueOf(q)
// var tag string
// var ok bool
// var t *resolveSearchTag
// var tname string
// if cur, ok := q.(Query); ok {
// if cur.TableName() == "" {
// tname = pTName
// } else {
// tname = cur.TableName()
// }
// } else {
// tname = pTName
// }
// if qType.Kind() == reflect.Ptr {
// qType = qType.Elem()
// }
// if qType.Kind() != reflect.Struct {
// // fmt.Printf("SeachQuery field undefined tag of type %s, expect type is struct\n", qType.Name())
// return
// }
// for i := 0; i < qType.NumField(); i++ {
// tag, ok = "", false
// tag, ok = qType.Field(i).Tag.Lookup(FromQueryTag)
// if !ok {
// //递归调用
// ResolveSearchQuery(driver, qValue.Field(i).Interface(), condition, tname)
// continue
// }
// switch tag {
// case "-":
// continue
// }
// if qValue.Field(i).IsZero() {
// continue
// }
// t = makeTag(tag)
// if t.Column == "" {
// t.Column = snakeCase(qType.Field(i).Name, false)
// }
// if t.Table == "" {
// t.Table = tname
// }
// //解析 Postgres `语法不支持,单独适配
// if driver == Postgres {
// pgSql(driver, t, condition, qValue, i, tname)
// } else {
// otherSql(driver, t, condition, qValue, i, tname)
// }
// }
// }
// type QueryTag string
// const (
// EQ QueryTag = "eq"
// LIKE QueryTag = "like"
// ILIKE QueryTag = "ilike"
// LEFT QueryTag = "left"
// ILEFT QueryTag = "ileft"
// RIGHT QueryTag = "right"
// IRIGHT QueryTag = "iright"
// GT QueryTag = "gt"
// GTE QueryTag = "gte"
// LT QueryTag = "lt"
// LTE QueryTag = "lte"
// IN QueryTag = "in"
// ISNULL QueryTag = "isnull"
// ISNOTNULL QueryTag = "isnotnull"
// ORDER QueryTag = "order"
// JOIN QueryTag = "join"
// )
// func pgSql(driver string, t *resolveSearchTag, condition Condition, qValue reflect.Value, i int, tname string) {
// if t.Type == "" {
// condition.SetWhere(fmt.Sprintf("%s.%s = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// }
// qtag := QueryTag(t.Type)
// switch qtag {
// case EQ:
// condition.SetWhere(fmt.Sprintf("%s.%s = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case ILIKE:
// condition.SetWhere(fmt.Sprintf("%s.%s ilike ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String() + "%"})
// return
// case LIKE:
// condition.SetWhere(fmt.Sprintf("%s.%s like ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String() + "%"})
// return
// case GT:
// condition.SetWhere(fmt.Sprintf("%s.%s > ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case GTE:
// condition.SetWhere(fmt.Sprintf("%s.%s >= ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case LT:
// condition.SetWhere(fmt.Sprintf("%s.%s < ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case LTE:
// condition.SetWhere(fmt.Sprintf("%s.%s <= ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case ILEFT:
// condition.SetWhere(fmt.Sprintf("%s.%s ilike ?", t.Table, t.Column), []interface{}{qValue.Field(i).String() + "%"})
// return
// case LEFT:
// condition.SetWhere(fmt.Sprintf("%s.%s like ?", t.Table, t.Column), []interface{}{qValue.Field(i).String() + "%"})
// return
// case IRIGHT:
// condition.SetWhere(fmt.Sprintf("%s.%s ilike ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String()})
// return
// case RIGHT:
// condition.SetWhere(fmt.Sprintf("%s.%s like ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String()})
// return
// case IN:
// condition.SetWhere(fmt.Sprintf("%s.%s in (?)", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case ISNULL:
// if !(qValue.Field(i).IsZero() && qValue.Field(i).IsNil()) {
// condition.SetWhere(fmt.Sprintf("%s.%s is null", t.Table, t.Column), make([]interface{}, 0))
// }
// return
// case ISNOTNULL:
// if !(qValue.Field(i).IsZero() && qValue.Field(i).IsNil()) {
// condition.SetWhere(fmt.Sprintf("%s.%s is not null", t.Table, t.Column), make([]interface{}, 0))
// }
// return
// case ORDER:
// switch strings.ToLower(qValue.Field(i).String()) {
// case "desc", "asc":
// condition.SetOrder(fmt.Sprintf("%s.%s %s", t.Table, t.Column, qValue.Field(i).String()))
// }
// return
// case JOIN:
// //左关联
// join := condition.SetJoinOn(t.Type, fmt.Sprintf(
// "left join %s on %s.%s = %s.%s", t.Join, t.Join, t.On[0], t.Table, t.On[1],
// ))
// ResolveSearchQuery(driver, qValue.Field(i).Interface(), join, tname)
// return
// default:
// condition.SetWhere(fmt.Sprintf("%s.%s = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// }
// }
// func otherSql(driver string, t *resolveSearchTag, condition Condition, qValue reflect.Value, i int, tname string) {
// if t.Type == "" {
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// }
// qtag := QueryTag(t.Type)
// switch qtag {
// case EQ:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case GT:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` > ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case GTE:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` >= ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case LT:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` < ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case LTE:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` <= ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case LEFT:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` like ?", t.Table, t.Column), []interface{}{qValue.Field(i).String() + "%"})
// return
// case LIKE:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` like ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String() + "%"})
// return
// case RIGHT:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` like ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String()})
// return
// case IN:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` in (?)", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// return
// case ISNULL:
// if !(qValue.Field(i).IsZero() && qValue.Field(i).IsNil()) {
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` is null", t.Table, t.Column), make([]interface{}, 0))
// }
// return
// case ISNOTNULL:
// if !(qValue.Field(i).IsZero() && qValue.Field(i).IsNil()) {
// condition.SetWhere(fmt.Sprintf("%s.%s is not null", t.Table, t.Column), make([]interface{}, 0))
// }
// return
// case ORDER:
// val := strings.TrimSpace(qValue.Field(i).String())
// if detectSQLInjection(val) {
// logger.Error("detect SQL injection", logger.String("sql order segment", val))
// return
// }
// if val != "" {
// orderColumns := strings.Split(val, ",")
// var orders []string
// for _, column := range orderColumns {
// if strings.HasPrefix(column, "-") {
// column = column[1:] + " desc"
// } else {
// column += " asc"
// }
// column = fmt.Sprintf("%s.%s", t.Table, column)
// orders = append(orders, column)
// }
// orderSegmet := strings.Join(orders, ",")
// condition.SetOrder(orderSegmet)
// } else {
// switch strings.ToLower(qValue.Field(i).String()) {
// case "desc", "asc":
// condition.SetOrder(fmt.Sprintf("`%s`.`%s` %s", t.Table, t.Column, qValue.Field(i).String()))
// }
// }
// return
// case JOIN:
// //左关联
// join := condition.SetJoinOn(t.Type, fmt.Sprintf(
// "left join `%s` on `%s`.`%s` = `%s`.`%s`",
// t.Join,
// t.Join,
// t.On[0],
// t.Table,
// t.On[1],
// ))
// ResolveSearchQuery(driver, qValue.Field(i).Interface(), join, tname)
// return
// default:
// condition.SetWhere(fmt.Sprintf("`%s`.`%s` = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
// }
// }
// var (
// orderReg = regexp.MustCompile(`order\[([^\]]+)\]=([^=]+)`)
// detectSQLInjectionRe = regexp.MustCompile(`['";]+|UNION|SELECT|INSERT|UPDATE|DELETE|DROP|GRANT|EXEC|CREATE|ALTER|TRUNCATE|COUNT|\*|--|\/\*|;|\+|\/`)
// )
// func parseOrder(order string) (string, string, bool) {
// matches := orderReg.FindStringSubmatch(order)
// if len(matches) == 3 {
// column := matches[1]
// value := matches[2]
// return strings.TrimSpace(column), strings.TrimSpace(value), true
// } else {
// return "", "", false
// }
// }
// func CameCaseToUnderscore(s string) string {
// var output []rune
// for i, r := range s {
// if i == 0 {
// output = append(output, unicode.ToLower(r))
// continue
// }
// if unicode.IsUpper(r) {
// output = append(output, '_')
// }
// output = append(output, unicode.ToLower(r))
// }
// return string(output)
// }
// func castOrder(order string) string {
// order = strings.ToLower(order)
// switch order {
// case "desc":
// return "desc"
// case "asc":
// return "asc"
// default:
// return ""
// }
// }
// func detectSQLInjection(input string) bool {
// return detectSQLInjectionRe.MatchString(input)
// }
// /**
// * 驼峰转蛇形 snake string
// **/
// func snakeCase(s string, allMode bool) string {
// num := len(s)
// data := make([]byte, 0, num*2)
// for i := 0; i < num; i++ {
// d := s[i]
// // or通过ASCII码进行大小写的转化
// // 65-90(A-Z),97-122(a-z)
// //判断如果字母为大写的A-Z就在前面拼接一个_
// if d >= 'A' && d <= 'Z' {
// if i > 0 {
// if allMode {
// data = append(data, '_', d+32)
// } else {
// if s[i-1] >= 'A' && s[i-1] <= 'Z' {
// data = append(data, d+32)
// } else {
// data = append(data, '_', d+32)
// }
// }
// } else {
// data = append(data, d+32)
// }
// } else {
// data = append(data, d)
// }
// }
// //ToLower把大写字母统一转小写
// return string(data[:])
// }
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
"gitlab.wanzhuangkj.com/tush/xpkg/pkg/cache" "gitlab.wanzhuangkj.com/tush/xpkg/pkg/cache"
"gitlab.wanzhuangkj.com/tush/xpkg/pkg/encoding" "gitlab.wanzhuangkj.com/tush/xpkg/pkg/encoding"
"gitlab.wanzhuangkj.com/tush/xpkg/pkg/xerrors/xerror" "gitlab.wanzhuangkj.com/tush/xpkg/pkg/xerrors/xerror"
"gitlab.wanzhuangkj.com/tush/xpkg/xutils" utils "gitlab.wanzhuangkj.com/tush/xpkg/xutils"
"gitlab.wanzhuangkj.com/tush/xpkg/xutils/xsf" "gitlab.wanzhuangkj.com/tush/xpkg/xutils/xsf"
) )
...@@ -68,8 +68,7 @@ func (x *OCache[T]) Set(ctx context.Context, id xsf.ID, data *T, duration time.D ...@@ -68,8 +68,7 @@ func (x *OCache[T]) Set(ctx context.Context, id xsf.ID, data *T, duration time.D
return nil return nil
} }
cacheKey := getCacheKey(x.KeyPrefix, id.Int64()) cacheKey := getCacheKey(x.KeyPrefix, id.Int64())
err := x.Cache.Set(ctx, cacheKey, data, duration) if err := x.Cache.Set(ctx, cacheKey, data, duration); err != nil {
if err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
return nil return nil
...@@ -81,8 +80,7 @@ func (x *OCache[T]) Get(ctx context.Context, id xsf.ID) (*T, error) { ...@@ -81,8 +80,7 @@ func (x *OCache[T]) Get(ctx context.Context, id xsf.ID) (*T, error) {
} }
var data *T var data *T
cacheKey := getCacheKey(x.KeyPrefix, id.Int64()) cacheKey := getCacheKey(x.KeyPrefix, id.Int64())
err := x.Cache.Get(ctx, cacheKey, &data) if err := x.Cache.Get(ctx, cacheKey, &data); err != nil {
if err != nil {
return nil, xerror.New(err.Error()) return nil, xerror.New(err.Error())
} }
return data, nil return data, nil
...@@ -142,8 +140,7 @@ func (x *OCache[T]) MultiGet(ctx context.Context, ids []xsf.ID) (map[xsf.ID]int, ...@@ -142,8 +140,7 @@ func (x *OCache[T]) MultiGet(ctx context.Context, ids []xsf.ID) (map[xsf.ID]int,
func (x *OCache[T]) Del(ctx context.Context, id xsf.ID) error { func (x *OCache[T]) Del(ctx context.Context, id xsf.ID) error {
cacheKey := x.KeyPrefix + utils.Int64ToStr(id.Int64()) cacheKey := x.KeyPrefix + utils.Int64ToStr(id.Int64())
err := x.Cache.Del(ctx, cacheKey) if err := x.Cache.Del(ctx, cacheKey); err != nil {
if err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
return nil return nil
...@@ -158,8 +155,7 @@ func (x *OCache[T]) Dels(ctx context.Context, ids []xsf.ID) error { ...@@ -158,8 +155,7 @@ func (x *OCache[T]) Dels(ctx context.Context, ids []xsf.ID) error {
cacheKey := x.KeyPrefix + utils.Int64ToStr(id.Int64()) cacheKey := x.KeyPrefix + utils.Int64ToStr(id.Int64())
keys = append(keys, cacheKey) keys = append(keys, cacheKey)
} }
err := x.Cache.Del(ctx, keys...) if err := x.Cache.Del(ctx, keys...); err != nil {
if err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
return nil return nil
...@@ -167,8 +163,7 @@ func (x *OCache[T]) Dels(ctx context.Context, ids []xsf.ID) error { ...@@ -167,8 +163,7 @@ func (x *OCache[T]) Dels(ctx context.Context, ids []xsf.ID) error {
func (x *OCache[T]) SetPlaceholder(ctx context.Context, id xsf.ID) error { func (x *OCache[T]) SetPlaceholder(ctx context.Context, id xsf.ID) error {
cacheKey := x.KeyPrefix + utils.Int64ToStr(id.Int64()) cacheKey := x.KeyPrefix + utils.Int64ToStr(id.Int64())
err := x.Cache.SetCacheWithNotFound(ctx, cacheKey) if err := x.Cache.SetCacheWithNotFound(ctx, cacheKey); err != nil {
if err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
return nil return nil
......
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
"gitlab.wanzhuangkj.com/tush/xpkg/pkg/sgorm/query" "gitlab.wanzhuangkj.com/tush/xpkg/pkg/sgorm/query"
"gitlab.wanzhuangkj.com/tush/xpkg/pkg/xerrors/xerror" "gitlab.wanzhuangkj.com/tush/xpkg/pkg/xerrors/xerror"
"gitlab.wanzhuangkj.com/tush/xpkg/xcommon/ocache" "gitlab.wanzhuangkj.com/tush/xpkg/xcommon/ocache"
"gitlab.wanzhuangkj.com/tush/xpkg/xutils" utils "gitlab.wanzhuangkj.com/tush/xpkg/xutils"
ctxutils "gitlab.wanzhuangkj.com/tush/xpkg/xutils/ctxutils" ctxutils "gitlab.wanzhuangkj.com/tush/xpkg/xutils/ctxutils"
setutils "gitlab.wanzhuangkj.com/tush/xpkg/xutils/setutils" setutils "gitlab.wanzhuangkj.com/tush/xpkg/xutils/setutils"
"gitlab.wanzhuangkj.com/tush/xpkg/xutils/xsf" "gitlab.wanzhuangkj.com/tush/xpkg/xutils/xsf"
...@@ -215,9 +215,7 @@ func (x *ODao[T]) updByIDTx(ctx context.Context, tx *gorm.DB, id xsf.ID, upd any ...@@ -215,9 +215,7 @@ func (x *ODao[T]) updByIDTx(ctx context.Context, tx *gorm.DB, id xsf.ID, upd any
return nil return nil
} }
var table T var table T
if err := tx.WithContext(ctx).Model(&table). if err := tx.WithContext(ctx).Model(&table).Where("id = ?", id).Updates(upd).Error; err != nil {
Where("id = ?", id).
Updates(upd).Error; err != nil {
return xerror.New(err.Error()) return xerror.New(err.Error())
} }
_ = x.deleteCache(ctx, id) _ = x.deleteCache(ctx, id)
......
package validator
// // Translation 设置Translation
// func Translation() gin.HandlerFunc {
// en := en.New()
// zh := zh.New()
// universalTranslator := ut.New(zh, zh, en)
// valid := validator.New()
// _ = valid.RegisterValidation("mobile", func(fl validator.FieldLevel) bool {
// regex := regexp2.MustCompile(`^1[3456789]\d{9}$`, 0)
// phone := fl.Field().String()
// matched, err := regex.MatchString(phone)
// if err != nil {
// return false
// }
// return matched
// })
// //自定义电话验证方法
// _ = valid.RegisterValidation("phone", func(fl validator.FieldLevel) bool {
// regex := regexp2.MustCompile(`^(\d{3,4}-)?\d{6,11}$`, 0)
// phone := fl.Field().String()
// matched, err := regex.MatchString(phone)
// if err != nil {
// return false
// }
// return matched
// })
// //自定义图片验证方法
// _ = valid.RegisterValidation("image", func(fl validator.FieldLevel) bool {
// file := fl.Field().Interface()
// if fileHeader, ok := file.(multipart.FileHeader); ok {
// contentType := fileHeader.Header.Get("content-type")
// for _, t := range []string{"image/jpeg", "image/png", "image/gif"} {
// if strings.HasPrefix(contentType, t) {
// return true
// }
// }
// }
// return false
// })
// return func(c *gin.Context) {
// //根据参数取翻译器实例
// locale := c.DefaultQuery("locale", "zh")
// trans, _ := universalTranslator.GetTranslator(locale)
// switch locale {
// case "en":
// _ = en_translations.RegisterDefaultTranslations(valid, trans)
// valid.RegisterTagNameFunc(func(fld reflect.StructField) string {
// return fld.Tag.Get("encomment")
// })
// default:
// _ = zh_translations.RegisterDefaultTranslations(valid, trans)
// valid.RegisterTagNameFunc(func(fld reflect.StructField) string {
// return fld.Tag.Get("comment")
// })
// _ = valid.RegisterTranslation("mobile", trans, func(ut ut.Translator) error {
// return ut.Add("mobile", "{0}填写不正确", true)
// }, func(ut ut.Translator, fe validator.FieldError) string {
// t, _ := ut.T("mobile", fe.Field())
// return t
// })
// _ = valid.RegisterTranslation("phone", trans, func(ut ut.Translator) error {
// return ut.Add("phone", "{0}填写不正确", true)
// }, func(ut ut.Translator, fe validator.FieldError) string {
// t, _ := ut.T("phone", fe.Field())
// return t
// })
// _ = valid.RegisterTranslation("image", trans, func(ut ut.Translator) error {
// return ut.Add("image", "请上传{0}", true)
// }, func(ut ut.Translator, fe validator.FieldError) string {
// t, _ := ut.T("image", fe.Field())
// return t
// })
// }
// c.Set(CtxKey_Translator, trans)
// c.Set(CtxKey_Validator, valid)
// c.Next()
// }
// }
...@@ -6,18 +6,76 @@ import ( ...@@ -6,18 +6,76 @@ import (
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
zhTranslations "github.com/go-playground/validator/v10/translations/zh" zhTranslations "github.com/go-playground/validator/v10/translations/zh"
"gitlab.wanzhuangkj.com/tush/xpkg/pkg/logger" "gitlab.wanzhuangkj.com/tush/xpkg/pkg/xerrors/xerror"
) )
var Trans ut.Translator var (
Trans ut.Translator
fieldValidators = make(map[string]*FieldValidator)
)
// func init() {
// fv := FieldValidator{
// Key: "xtimeformat",
// Validation: func(fl validator.FieldLevel) bool {
// // field := fl.Field()
// // dateStr := field.String()
// // _, err := time.Parse("2006-01-02", dateStr)
// field := fl.Field()
// param := fl.Param()
// fmt.Println(field.Kind())
// for i := 0; i < field.NumField(); i++ {
// fmt.Println(field.Field(i))
// }
// if field.Kind() == reflect.String {
// _, err := time.Parse(param, field.String())
// return err == nil
// }
// return false
// },
// RegisterTranslation: func(ut ut.Translator) error {
// return ut.Add("xtimeformat", "{0} 必须是一个有效的日期,格式为 YYYY-MM-DD", true)
// },
// Translation: func(ut ut.Translator, fe validator.FieldError) string {
// t, _ := ut.T("xtimeformat", fe.Field())
// return t
// },
// }
// AddFieldValidator(&fv)
// }
func AddFieldValidator(v ...*FieldValidator) {
for _, item := range v {
fieldValidators[item.Key] = item
}
}
func InstallTranslations() { type FieldValidator struct {
Key string
Validation validator.Func
RegisterTranslation validator.RegisterTranslationsFunc
Translation validator.TranslationFunc
}
func InstallTranslations() error {
if v, ok := binding.Validator.Engine().(*validator.Validate); ok { if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
zhT := zh.New() zhT := zh.New()
uni := ut.New(zhT, zhT) uni := ut.New(zhT, zhT)
Trans, _ = uni.GetTranslator("zh") Trans, _ = uni.GetTranslator("zh")
if err := zhTranslations.RegisterDefaultTranslations(v, Trans); err != nil { if err := zhTranslations.RegisterDefaultTranslations(v, Trans); err != nil {
logger.Error("register translation failed ", logger.Err(err)) return xerror.Wrap(err, "register translation failed ")
}
for _, fv := range fieldValidators {
if err := v.RegisterValidation(fv.Key, fv.Validation); err != nil {
return err
}
if err := v.RegisterTranslation(fv.Key, Trans, fv.RegisterTranslation, fv.Translation); err != nil {
return err
}
} }
} }
return nil
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论