# Your rule content

- You can @ files here
- You can use markdown but dont have to

# Logic 实现规范

## 目录结构
```
app/main/api/internal/logic/
├── admin_notification/           # 通知管理模块
│   ├── admincreatenotificationlogic.go    # 创建通知
│   ├── admindeletnotificationlogic.go     # 删除通知
│   ├── admingetnotificationdetaillogic.go # 获取通知详情
│   ├── admingetnotificationlistlogic.go   # 获取通知列表
│   └── adminupdatenotificationlogic.go    # 更新通知
└── [其他模块]/
```

## Logic 实现规范

### 1. 基础结构
每个 Logic 文件都应包含以下基础结构：
```go
package [模块名]

import (
    "context"
    "sim-server/app/main/api/internal/svc"
    "sim-server/app/main/api/internal/types"
    "sim-server/common/xerr"
    "github.com/pkg/errors"
    "github.com/zeromicro/go-zero/core/logx"
)

type [操作名]Logic struct {
    logx.Logger
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func New[操作名]Logic(ctx context.Context, svcCtx *svc.ServiceContext) *[操作名]Logic {
    return &[操作名]Logic{
        Logger: logx.WithContext(ctx),
        ctx:    ctx,
        svcCtx: svcCtx,
    }
}
```

### 2. 增删改查实现规范

#### 2.1 创建操作（Create）
```go
func (l *[操作名]Logic) [操作名](req *types.[操作名]Req) (resp *types.[操作名]Resp, err error) {
    // 1. 数据转换和验证
    data := &model.[表名]{
        Field1: req.Field1,
        Field2: req.Field2,
        // ... 其他字段映射
    }

    // 2. 数据库操作
    result, err := l.svcCtx.[表名]Model.Insert(l.ctx, nil, data)
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "创建[操作对象]失败, err: %v, req: %+v", err, req)
    }

    // 3. 返回结果
    id, _ := result.LastInsertId()
    return &types.[操作名]Resp{Id: id}, nil
}
```

#### 2.2 删除操作（Delete）
```go
func (l *[操作名]Logic) [操作名](req *types.[操作名]Req) (resp *types.[操作名]Resp, err error) {
    // 1. 查询记录是否存在
    record, err := l.svcCtx.[表名]Model.FindOne(l.ctx, req.Id)
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "查找[操作对象]失败, err: %v, id: %d", err, req.Id)
    }

    // 2. 执行删除操作（软删除）
    err = l.svcCtx.[表名]Model.DeleteSoft(l.ctx, nil, record)
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "删除[操作对象]失败, err: %v, id: %d", err, req.Id)
    }

    // 3. 返回结果
    return &types.[操作名]Resp{Success: true}, nil
}
```

#### 2.3 更新操作（Update）
```go
func (l *[操作名]Logic) [操作名](req *types.[操作名]Req) (resp *types.[操作名]Resp, err error) {
    // 1. 查询记录是否存在
    record, err := l.svcCtx.[表名]Model.FindOne(l.ctx, req.Id)
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "查找[操作对象]失败, err: %v, id: %d", err, req.Id)
    }

    // 2. 更新字段（使用指针判断是否更新）
    if req.Field1 != nil {
        record.Field1 = *req.Field1
    }
    if req.Field2 != nil {
        record.Field2 = *req.Field2
    }
    // ... 其他字段更新

    // 3. 执行更新操作
    _, err = l.svcCtx.[表名]Model.Update(l.ctx, nil, record)
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "更新[操作对象]失败, err: %v, req: %+v", err, req)
    }

    // 4. 返回结果
    return &types.[操作名]Resp{Success: true}, nil
}
```

#### 2.4 查询详情（GetDetail）
```go
func (l *[操作名]Logic) [操作名](req *types.[操作名]Req) (resp *types.[操作名]Resp, err error) {
    // 1. 查询记录
    record, err := l.svcCtx.[表名]Model.FindOne(l.ctx, req.Id)
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "查找[操作对象]失败, err: %v, id: %d", err, req.Id)
    }

    // 2. 构建响应
    resp = &types.[操作名]Resp{
        Id:         record.Id,
        Field1:     record.Field1,
        Field2:     record.Field2,
        CreateTime: record.CreateTime.Format("2006-01-02 15:04:05"),
        UpdateTime: record.UpdateTime.Format("2006-01-02 15:04:05"),
    }

    // 3. 处理可选字段（如时间字段）
    if record.OptionalField.Valid {
        resp.OptionalField = record.OptionalField.Time.Format("2006-01-02")
    }

    return resp, nil
}
```

#### 2.5 查询列表（GetList）
```go
func (l *[操作名]Logic) [操作名](req *types.[操作名]Req) (resp *types.[操作名]Resp, err error) {
    // 1. 构建查询条件
    builder := l.svcCtx.[表名]Model.SelectBuilder()
    
    // 2. 添加查询条件（使用指针判断是否添加条件）
    if req.Field1 != nil {
        builder = builder.Where("field1 LIKE ?", "%"+*req.Field1+"%")
    }
    if req.Field2 != nil {
        builder = builder.Where("field2 = ?", *req.Field2)
    }
    // ... 其他查询条件

    // 3. 执行分页查询
    list, total, err := l.svcCtx.[表名]Model.FindPageListByPageWithTotal(
        l.ctx, builder, req.Page, req.PageSize, "id DESC")
    if err != nil {
        return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), 
            "查询[操作对象]列表失败, err: %v, req: %+v", err, req)
    }

    // 4. 构建响应列表
    items := make([]types.[列表项类型], 0, len(list))
    for _, item := range list {
        listItem := types.[列表项类型]{
            Id:         item.Id,
            Field1:     item.Field1,
            Field2:     item.Field2,
            CreateTime: item.CreateTime.Format("2006-01-02 15:04:05"),
            UpdateTime: item.UpdateTime.Format("2006-01-02 15:04:05"),
        }
        // 处理可选字段
        if item.OptionalField.Valid {
            listItem.OptionalField = item.OptionalField.Time.Format("2006-01-02")
        }
        items = append(items, listItem)
    }

    // 5. 返回结果
    return &types.[操作名]Resp{
        Total: total,
        Items: items,
    }, nil
}
```

### 3. 错误处理规范
1. 使用 `errors.Wrapf` 包装错误
2. 使用 `xerr.NewErrCode` 创建业务错误
3. 错误信息应包含：
   - 操作类型（创建/更新/删除/查询）
   - 具体错误描述
   - 相关参数信息（ID、请求参数等）

### 4. 时间处理规范
1. 时间格式化：
   - 日期时间：`"2006-01-02 15:04:05"`
   - 仅日期：`"2006-01-02"`
2. 可选时间字段处理：
   ```go
   if field.Valid {
       resp.Field = field.Time.Format("2006-01-02")
   }
   ```

### 5. 数据库操作规范
1. 查询条件构建：
   ```go
   builder := l.svcCtx.[表名]Model.SelectBuilder()
   builder = builder.Where("field = ?", value)
   ```
2. 分页查询：
   ```go
   list, total, err := l.svcCtx.[表名]Model.FindPageListByPageWithTotal(
       ctx, builder, page, pageSize, "id DESC")
   ```
3. 事务处理：
   ```go
   err = l.svcCtx.[表名]Model.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
       // 事务操作
       return nil
   })
   ```

### 6. 并发处理规范
```go
var mu sync.Mutex
err = mr.MapReduceVoid(func(source chan<- interface{}) {
    // 并发处理
}, func(item interface{}, writer mr.Writer[struct{}], cancel func(error)) {
    // 处理单个项目
}, func(pipe <-chan struct{}, cancel func(error)) {
    // 完成处理
})
```

### 7. 注意事项
1. 所有数据库操作必须进行错误处理
2. 更新操作必须使用指针类型判断字段是否更新
3. 查询列表必须支持分页
4. 时间字段必须统一格式化
5. 可选字段必须进行空值判断
6. 保持代码风格统一，添加必要的注释
7. 涉及多表操作时使用事务
8. 并发操作时注意使用互斥锁保护共享资源
9. 错误处理必须使用 errors.Wrapf 和 xerr 包
10. 时间类型统一使用 "2006-01-02 15:04:05" 格式

# Your rule content

- You can @ files here
- You can use markdown but dont have to
