修改课程教师

This commit is contained in:
2025-11-02 23:52:32 +08:00
parent 0ad87b1488
commit 886672f820
5 changed files with 146 additions and 65 deletions

View File

@@ -6,6 +6,8 @@ package course_teacher
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/JACKYMYPERSON/hldrCenter/config"
"github.com/JACKYMYPERSON/hldrCenter/internal/course_teacher/internal/logic/course_teacher"
@@ -18,10 +20,19 @@ import (
func DeleteCourseTeacherHandler(cfg *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.DeleteCourseTeacherReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
pathParts := strings.Split(r.URL.Path, "/")
fmt.Println(pathParts)
if len(pathParts) < 3 { // 确保路径格式正确
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format"))
return
}
idStr := pathParts[3]
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID"))
return
}
req.Id = int(id)
mysqlCfg := cfg.MySQL
dsn := fmt.Sprintf(

View File

@@ -6,6 +6,8 @@ package course_teacher
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/JACKYMYPERSON/hldrCenter/config"
"github.com/JACKYMYPERSON/hldrCenter/internal/course_teacher/internal/logic/course_teacher"
@@ -18,10 +20,19 @@ import (
func GetCourseTeacherHandler(cfg *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetCourseTeacherReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
pathParts := strings.Split(r.URL.Path, "/")
fmt.Println(pathParts)
if len(pathParts) < 3 { // 确保路径格式正确
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format"))
return
}
idStr := pathParts[3]
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID"))
return
}
req.Id = int(id)
mysqlCfg := cfg.MySQL
dsn := fmt.Sprintf(

View File

@@ -5,7 +5,6 @@ package course_teacher
import (
"context"
"database/sql"
"fmt"
"github.com/JACKYMYPERSON/hldrCenter/config"
@@ -32,57 +31,62 @@ func NewListCourseTeacherLogic(ctx context.Context, cfg *config.Config, model mo
}
func (l *ListCourseTeacherLogic) ListCourseTeacher(req *types.ListCourseTeacherReq) (resp *types.ListCourseTeacherResp, err error) {
// 1. 参数校验(补充validate标签外的业务校验
// 1. 强化参数校验(覆盖所有可能的无效参数
if req.Page < 1 {
return nil, fmt.Errorf("参数错误页码必须≥1")
}
if req.PageSize < 1 || req.PageSize > 100 {
return nil, fmt.Errorf("参数错误每页条数必须在1-100之间")
}
if req.CourseId < 0 { // 新增禁止负数课程ID无实际业务意义
return nil, fmt.Errorf("参数错误课程ID不能为负数")
}
// 2. 转换筛选参数为int64适配Model层字段类型
courseId := int64(req.CourseId)
teacherId := int64(req.TeacherId)
// 2. 转换筛选参数适配Model层int64字段类型)
courseId := int64(req.CourseId) // 0表示不按课程ID筛选Model层会忽略
// 3. 计算分页参数(offset = (page-1)*pageSize
// 3. 计算分页参数(标准分页公式,避免偏移量为负
offset := (req.Page - 1) * req.PageSize
if offset < 0 { // 兜底防止极端情况下offset为负
offset = 0
}
// 4. 调用Model层查询总条数按筛选条件
total, err := l.model.CountByConditions(l.ctx, courseId, teacherId)
// 4. 查询符合条件的总条数无teacher_id筛选仅可选按course_id
total, err := l.model.CountByConditions(l.ctx, courseId)
if err != nil {
return nil, fmt.Errorf("查询教师总条数失败:%w", err)
}
// 5. 调用Model层查询当前页数据按筛选条件+分页+排序)
// 5. 修复调用:参数类型/数量严格对齐Model层函数定义
// Model层函数签名FindByConditionsWithPage(ctx, courseId(int64), pageSize(int), offset(int))
teachers, err := l.model.FindByConditionsWithPage(
l.ctx,
courseId, // 课程ID筛选0表示不筛选
teacherId, // 教师ID筛选0表示不筛选
req.PageSize, // 每页条数
offset, // 偏移量
courseId, // 课程IDint64匹配Model层
req.PageSize, // 每页条数int无需转int64直接传req.PageSize
offset, // 偏移量int匹配Model层
)
if err != nil {
return nil, fmt.Errorf("查询教师列表失败:%w", err)
}
// 6. 转换Model数据为响应列表处理sql.NullString和int64→int
// 6. 数据转换(统一处理sql.NullString类型,避免空值异常
var list []types.GetCourseTeacherResp
for _, t := range teachers {
list = append(list, types.GetCourseTeacherResp{
Id: int(t.Id), // int64→int
CourseId: int(t.CourseId), // int64→int
TeacherId: int(t.TeacherId), // int64→int
Id: int(t.Id),
CourseId: int(t.CourseId),
TeacherId: int(t.TeacherId),
Name: t.Name,
Title: t.Title, // sql.NullString→string
Avatar: t.Avatar, // sql.NullString→string
Intro: NullStringToString(t.Intro), // sql.NullString→string
Sort: int(t.Sort), // int64→int
Title: t.Title,
Avatar: t.Avatar,
Intro: NullStringToString(t.Intro),
Sort: int(t.Sort),
})
}
// 7. 构造响应
// 7. 构造标准响应
resp = &types.ListCourseTeacherResp{
Total: int(total), // 总条数int64→int
Total: int(total),
List: list,
Page: req.Page,
PageSize: req.PageSize,
@@ -90,15 +94,3 @@ func (l *ListCourseTeacherLogic) ListCourseTeacher(req *types.ListCourseTeacherR
return resp, nil
}
func StringToNullString(s string) sql.NullString {
if s != "" {
return sql.NullString{
String: s,
Valid: true,
}
}
return sql.NullString{
Valid: false, // 空字符串时标记为无效,数据库存 NULL
}
}

View File

@@ -5,6 +5,9 @@ package course_teacher
import (
"context"
"database/sql"
"errors"
"fmt"
"github.com/JACKYMYPERSON/hldrCenter/config"
"github.com/JACKYMYPERSON/hldrCenter/internal/course_teacher/internal/model"
@@ -30,7 +33,86 @@ func NewUpdateCourseTeacherLogic(ctx context.Context, cfg *config.Config, model
}
func (l *UpdateCourseTeacherLogic) UpdateCourseTeacher(req *types.UpdateCourseTeacherReq) (resp *types.UpdateCourseTeacherResp, err error) {
// todo: add your logic here and delete this line
return
// 1. 基础参数校验确保ID有效
if req.Id <= 0 {
return nil, fmt.Errorf("参数错误关联ID必须为正整数")
}
// 2. 查询原记录(确保记录存在)
// 注意此处假设Model层有FindOne方法根据ID查询单条记录
original, err := l.model.FindOne(l.ctx, int64(req.Id))
if err != nil {
if errors.Is(err, model.ErrNotFound) { // 假设Model层定义了ErrNotFound表示记录不存在
return nil, fmt.Errorf("课程教师关联记录不存在ID: %d", req.Id)
}
return nil, fmt.Errorf("查询原记录失败:%w", err)
}
// 3. 构建更新数据(仅更新请求中提供的非空/有效字段)
updateData := &model.CourseTeacher{
Id: int64(req.Id), // 必须携带ID用于WHERE条件
// 基础字段默认沿用原记录,后续按需覆盖
CourseId: original.CourseId,
TeacherId: original.TeacherId,
Name: original.Name,
Title: original.Title,
Avatar: original.Avatar,
Intro: original.Intro,
Sort: original.Sort,
}
// 3.1 可选更新课程ID若请求中提供了有效值
if req.CourseId > 0 {
updateData.CourseId = int64(req.CourseId)
}
// 3.2 可选更新教师ID若请求中提供了有效值
if req.TeacherId > 0 {
updateData.TeacherId = int64(req.TeacherId)
}
// 3.3 可选更新:教师姓名(若请求中提供了非空值)
if req.Name != "" {
updateData.Name = req.Name
}
// 3.4 可选更新:教师头衔(若请求中提供了非空值)
if req.Title != "" {
updateData.Title = req.Title
}
// 3.5 可选更新头像URL若请求中提供了非空值
if req.Avatar != "" {
updateData.Avatar = req.Avatar
}
// 3.6 可选更新:教师简介(若请求中提供了非空值,允许清空)
if req.Intro != "" { // 注意:若需允许清空简介,此处直接赋值(空字符串也会更新)
updateData.Intro = StringToNullString(req.Intro)
}
// 3.7 可选更新:排序值(若请求中提供了有效值)
if req.Sort >= 0 { // 符合validate规则min=0
updateData.Sort = int64(req.Sort)
}
// 4. 调用Model层执行更新
err = l.model.Update(l.ctx, updateData)
if err != nil {
return nil, fmt.Errorf("更新课程教师关联记录失败:%w", err)
}
// 5. 构建成功响应
resp = &types.UpdateCourseTeacherResp{
Message: fmt.Sprintf("课程教师关联记录ID: %d更新成功", req.Id),
}
return resp, nil
}
func StringToNullString(s string) sql.NullString {
if s != "" {
return sql.NullString{String: s, Valid: true}
}
return sql.NullString{Valid: false}
}

View File

@@ -28,10 +28,10 @@ type (
FindOne(ctx context.Context, id int64) (*CourseTeacher, error)
Update(ctx context.Context, data *CourseTeacher) error
Delete(ctx context.Context, id int64) error
CountByConditions(ctx context.Context, courseId, teacherId int64) (int64, error)
CountByConditions(ctx context.Context, courseId int64) (int64, error)
FindByConditionsWithPage(
ctx context.Context,
courseId, teacherId int64,
courseId int64,
pageSize, offset int,
) ([]*CourseTeacher, error)
}
@@ -67,7 +67,7 @@ func (m *defaultCourseTeacherModel) Delete(ctx context.Context, id int64) error
}
func (m *defaultCourseTeacherModel) FindOne(ctx context.Context, id int64) (*CourseTeacher, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", courseTeacherRows, m.table)
query := fmt.Sprintf("select %s from %s where `course_id` = ? limit 1", courseTeacherRows, m.table)
var resp CourseTeacher
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
@@ -92,74 +92,59 @@ func (m *defaultCourseTeacherModel) Update(ctx context.Context, data *CourseTeac
return err
}
func (m *defaultCourseTeacherModel) CountByConditions(ctx context.Context, courseId, teacherId int64) (int64, error) {
func (m *defaultCourseTeacherModel) CountByConditions(ctx context.Context, courseId int64) (int64, error) { // 移除teacherId参数
var count int64
baseQuery := fmt.Sprintf("select count(*) from %s", m.table)
// 构造筛选条件(支持单条件/多条件/无筛选)
var whereClauses []string
var args []interface{}
// 只保留course_id的筛选如果需要删除teacher_id的筛选逻辑
if courseId > 0 {
whereClauses = append(whereClauses, "`course_id` = ?")
args = append(args, courseId)
}
if teacherId > 0 {
whereClauses = append(whereClauses, "`teacher_id` = ?")
args = append(args, teacherId)
}
// 拼接完整查询语句
if len(whereClauses) > 0 {
baseQuery += " where " + strings.Join(whereClauses, " and ")
}
// 执行查询
err := m.conn.QueryRowCtx(ctx, &count, baseQuery, args...)
return count, err
}
// FindByConditionsWithPage 实现按条件分页查询
func (m *defaultCourseTeacherModel) FindByConditionsWithPage(
ctx context.Context,
courseId, teacherId int64,
courseId int64, // 移除teacherId参数
pageSize, offset int,
) ([]*CourseTeacher, error) {
var teachers []*CourseTeacher
baseQuery := fmt.Sprintf("select %s from %s", courseTeacherRows, m.table)
// 构造筛选条件同CountByConditions
var whereClauses []string
var args []interface{}
// 只保留course_id的筛选如果需要删除teacher_id的筛选逻辑
if courseId > 0 {
whereClauses = append(whereClauses, "`course_id` = ?")
args = append(args, courseId)
}
if teacherId > 0 {
whereClauses = append(whereClauses, "`teacher_id` = ?")
args = append(args, teacherId)
}
// 拼接分页和排序按sort升序确保展示顺序一致
// 分页参数
pageQuery := " order by `sort` asc limit ?, ?"
args = append(args, offset, pageSize) // 补充分页参数
args = append(args, offset, pageSize)
// 拼接完整查询语句
if len(whereClauses) > 0 {
baseQuery += " where " + strings.Join(whereClauses, " and ") + pageQuery
} else {
baseQuery += pageQuery
}
// 执行查询
err := m.conn.QueryRowsCtx(ctx, &teachers, baseQuery, args...)
if err != nil {
return nil, err
}
return teachers, nil
}
func (m *defaultCourseTeacherModel) tableName() string {
return m.table
}