diff --git a/server/internal/social_service/handler/socialService/deletesocialservicehandler.go b/server/internal/social_service/handler/socialService/deletesocialservicehandler.go index 5da10a2f..359b4f98 100644 --- a/server/internal/social_service/handler/socialService/deletesocialservicehandler.go +++ b/server/internal/social_service/handler/socialService/deletesocialservicehandler.go @@ -6,6 +6,8 @@ package socialService import ( "fmt" "net/http" + "strconv" + "strings" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service/internal/logic/socialService" @@ -18,10 +20,19 @@ import ( func DeleteSocialServiceHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.DeleteSocialServiceReq - if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + pathParts := strings.Split(r.URL.Path, "/") + 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 + } + fmt.Println("idStr:", idStr) + req.Id = id mysqlCfg := cfg.MySQL dsn := fmt.Sprintf( diff --git a/server/internal/social_service/handler/socialService/getsocialservicehandler.go b/server/internal/social_service/handler/socialService/getsocialservicehandler.go index 0bd9559d..fc21ce3e 100644 --- a/server/internal/social_service/handler/socialService/getsocialservicehandler.go +++ b/server/internal/social_service/handler/socialService/getsocialservicehandler.go @@ -6,6 +6,8 @@ package socialService import ( "fmt" "net/http" + "strconv" + "strings" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service/internal/logic/socialService" @@ -18,10 +20,19 @@ import ( func GetSocialServiceHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.GetSocialServiceReq - if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + pathParts := strings.Split(r.URL.Path, "/") + 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 + } + fmt.Println("idStr:", idStr) + req.Id = id mysqlCfg := cfg.MySQL dsn := fmt.Sprintf( diff --git a/server/internal/social_service/internal/types/types.go b/server/internal/social_service/internal/types/types.go index 7ebfe66a..18ff075c 100644 --- a/server/internal/social_service/internal/types/types.go +++ b/server/internal/social_service/internal/types/types.go @@ -56,8 +56,8 @@ type ListSocialServiceData struct { } type ListSocialServiceReq struct { - Page int `json:"page" form:"page" validate:"min=1"` // 页码(默认1) - PageSize int `json:"page_size" form:"page_size" validate:"min=1,max=100"` // 每页条数(默认10,最大100) + Page int `json:"page" validate:"min=1"` // 页码(默认1) + PageSize int `json:"page_size" validate:"min=1,max=100"` // 每页条数(默认10,最大100) } type ListSocialServiceResp struct { @@ -83,17 +83,17 @@ type SocialService struct { } type UpdateSocialServiceReq struct { - Id int64 `json:"-" path:"id" validate:"min=1"` // 社会服务ID(路径参数,必填) - Title string `json:"title,omitempty"` // 标题 - Subtitle string `json:"subtitle,omitempty"` // 副标题 - CoverUrl string `json:"cover_url,omitempty"` // 封面图片URL - Intro string `json:"intro,omitempty"` // 简介(纯文字) - Content string `json:"content,omitempty"` // 内容(Markdown格式) - ImageEditors string `json:"image_editors,omitempty"` // 图片编辑者名单(逗号分隔) - TextEditors string `json:"text_editors,omitempty"` // 文字编辑者名单(逗号分隔) - ChiefEditor string `json:"chief_editor,omitempty"` // 总编辑 - Proofreaders string `json:"proofreaders,omitempty"` // 校对者名单(逗号分隔) - Reviewers string `json:"reviewers,omitempty"` // 审核者名单(逗号分隔) + Id int64 `json:"id" validate:"min=1"` // 社会服务ID(路径参数,必填) + Title string `json:"title,omitempty"` // 标题 + Subtitle string `json:"subtitle,omitempty"` // 副标题 + CoverUrl string `json:"cover_url,omitempty"` // 封面图片URL + Intro string `json:"intro,omitempty"` // 简介(纯文字) + Content string `json:"content,omitempty"` // 内容(Markdown格式) + ImageEditors string `json:"image_editors,omitempty"` // 图片编辑者名单(逗号分隔) + TextEditors string `json:"text_editors,omitempty"` // 文字编辑者名单(逗号分隔) + ChiefEditor string `json:"chief_editor,omitempty"` // 总编辑 + Proofreaders string `json:"proofreaders,omitempty"` // 校对者名单(逗号分隔) + Reviewers string `json:"reviewers,omitempty"` // 审核者名单(逗号分隔) } type UpdateSocialServiceResp struct { diff --git a/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramhandler.go b/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramhandler.go index 2e404176..be12e7f6 100644 --- a/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramhandler.go +++ b/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramhandler.go @@ -6,6 +6,8 @@ package socialServiceGovernmentProgram import ( "fmt" "net/http" + "strconv" + "strings" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram" @@ -18,10 +20,19 @@ import ( func DeleteSocialServiceGovernmentProgramHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.DeleteSocialServiceGovernmentProgramReq - if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + pathParts := strings.Split(r.URL.Path, "/") + if len(pathParts) < 4 { // 确保路径格式正确 + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format")) return } + idStr := pathParts[4] + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil { + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID")) + return + } + fmt.Println("idStr:", idStr) + req.Id = id mysqlCfg := cfg.MySQL dsn := fmt.Sprintf( "%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local", diff --git a/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/getsocialservicegovernmentprogramhandler.go b/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/getsocialservicegovernmentprogramhandler.go index 19a53e11..da312427 100644 --- a/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/getsocialservicegovernmentprogramhandler.go +++ b/server/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram/getsocialservicegovernmentprogramhandler.go @@ -6,6 +6,8 @@ package socialServiceGovernmentProgram import ( "fmt" "net/http" + "strconv" + "strings" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram" @@ -18,10 +20,19 @@ import ( func GetSocialServiceGovernmentProgramHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.GetSocialServiceGovernmentProgramReq - if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + pathParts := strings.Split(r.URL.Path, "/") + if len(pathParts) < 4 { // 确保路径格式正确 + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format")) return } + idStr := pathParts[4] + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil { + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID")) + return + } + fmt.Println("idStr:", idStr) + req.Id = id mysqlCfg := cfg.MySQL dsn := fmt.Sprintf( diff --git a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/createsocialservicegovernmentprogramlogic.go b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/createsocialservicegovernmentprogramlogic.go index 0852f0c0..31f94940 100644 --- a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/createsocialservicegovernmentprogramlogic.go +++ b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/createsocialservicegovernmentprogramlogic.go @@ -5,10 +5,12 @@ package socialServiceGovernmentProgram import ( "context" + "database/sql" + "fmt" + "time" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/model" - "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/svc" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/types" "github.com/zeromicro/go-zero/core/logx" @@ -31,7 +33,66 @@ func NewCreateSocialServiceGovernmentProgramLogic(ctx context.Context, cfg *conf } func (l *CreateSocialServiceGovernmentProgramLogic) CreateSocialServiceGovernmentProgram(req *types.CreateSocialServiceGovernmentProgramReq) (resp *types.CreateSocialServiceGovernmentProgramResp, err error) { - // todo: add your logic here and delete this line + // 1. 兜底验证必填参数(避免validate失效场景) + if req.Title == "" { + return &types.CreateSocialServiceGovernmentProgramResp{ + Code: 400, // 参数错误码 + Msg: "标题不能为空", + }, nil + } - return + // 2. 构造数据库实体(严格对应表字段) + dbData := &model.SocialServiceGovernmentprogram{ + Title: req.Title, + Subtitle: req.Subtitle, + CoverUrl: req.CoverUrl, + Intro: req.Intro, + Content: stringToNullString(req.Content), + ImageEditors: req.ImageEditors, + TextEditors: req.TextEditors, + ChiefEditor: req.ChiefEditor, + Proofreaders: req.Proofreaders, + Reviewers: req.Reviewers, + // 按要求格式设置当前时间(yyyy-MM-dd HH:mm:ss) + PublishTime: time.Now(), + IsDelete: 0, // 默认未删除(0=未删除,1=已删除,适配软删除) + } + + // 3. 调用model插入数据 + result, err := l.model.Insert(context.Background(), dbData) + if err != nil { + fmt.Printf("插入社会服务政府项目失败:%v\n", err) + return &types.CreateSocialServiceGovernmentProgramResp{ + Code: 500, // 服务器/数据库错误码 + Msg: "项目创建失败,请稍后重试", + }, nil + } + + // 4. 获取新增记录的主键ID + newId, err := result.LastInsertId() + if err != nil { + fmt.Printf("获取新增项目ID失败:%v\n", err) + return &types.CreateSocialServiceGovernmentProgramResp{ + Code: 500, + Msg: "项目创建成功,但获取ID失败", + }, nil + } + + // 5. 构造成功响应 + resp = &types.CreateSocialServiceGovernmentProgramResp{ + Code: 0, // 0表示成功 + Msg: "项目创建成功", + Data: types.CreateSocialServiceGovernmentProgramData{ + Id: newId, // 返回新增记录ID,供前端后续使用 + }, + } + + return resp, nil +} + +func stringToNullString(s string) sql.NullString { + if s == "" { + return sql.NullString{String: "", Valid: false} // 空字符串 -> 数据库 NULL + } + return sql.NullString{String: s, Valid: true} // 非空字符串 -> 数据库存储该值 } diff --git a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramlogic.go b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramlogic.go index 785fa098..5dbaa975 100644 --- a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramlogic.go +++ b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/deletesocialservicegovernmentprogramlogic.go @@ -5,6 +5,7 @@ package socialServiceGovernmentProgram import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/model" @@ -30,7 +31,30 @@ func NewDeleteSocialServiceGovernmentProgramLogic(ctx context.Context, cfg *conf } func (l *DeleteSocialServiceGovernmentProgramLogic) DeleteSocialServiceGovernmentProgram(req *types.DeleteSocialServiceGovernmentProgramReq) (resp *types.DeleteSocialServiceGovernmentProgramResp, err error) { - // todo: add your logic here and delete this line + // 1. 兜底验证必填参数(避免validate失效,确保ID合法) + if req.Id <= 0 { + return &types.DeleteSocialServiceGovernmentProgramResp{ + Code: 400, // 参数错误码 + Msg: "项目ID不合法,必须大于0", + }, nil + } - return + // 2. 调用model执行删除操作(软删除/物理删除按model实现逻辑) + err = l.model.Delete(context.Background(), req.Id) + if err != nil { + // 打印错误日志便于排查 + fmt.Printf("删除社会服务政府项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.DeleteSocialServiceGovernmentProgramResp{ + Code: 500, // 服务器/数据库错误码 + Msg: "项目删除失败,请稍后重试", + }, nil + } + + // 3. 构造成功响应 + resp = &types.DeleteSocialServiceGovernmentProgramResp{ + Code: 0, // 0表示成功 + Msg: "项目删除成功", + } + + return resp, nil } diff --git a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/getsocialservicegovernmentprogramlogic.go b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/getsocialservicegovernmentprogramlogic.go index 4dcc68b4..60992003 100644 --- a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/getsocialservicegovernmentprogramlogic.go +++ b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/getsocialservicegovernmentprogramlogic.go @@ -5,6 +5,8 @@ package socialServiceGovernmentProgram import ( "context" + "database/sql" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/model" @@ -31,7 +33,68 @@ func NewGetSocialServiceGovernmentProgramLogic(ctx context.Context, cfg *config. } func (l *GetSocialServiceGovernmentProgramLogic) GetSocialServiceGovernmentProgram(req *types.GetSocialServiceGovernmentProgramReq) (resp *types.GetSocialServiceGovernmentProgramResp, err error) { - // todo: add your logic here and delete this line + // 1. 兜底验证参数合法性 + if req.Id <= 0 { + return &types.GetSocialServiceGovernmentProgramResp{ + Code: 400, + Msg: "项目ID不合法,必须大于0", + }, nil + } - return + // 2. 调用model查询详情(已添加软删除过滤) + program, err := l.model.FindOne(context.Background(), req.Id) + if err != nil { + if err == model.ErrNotFound { + return &types.GetSocialServiceGovernmentProgramResp{ + Code: 404, + Msg: "未找到该社会服务政府项目", + }, nil + } + fmt.Printf("查询社会服务政府项目详情失败,ID:%d,错误:%v\n", req.Id, err) + return &types.GetSocialServiceGovernmentProgramResp{ + Code: 500, + Msg: "查询项目详情失败,请稍后重试", + }, nil + } + + // 3. 软删除二次校验(双重保障) + if program.IsDelete == 1 { + return &types.GetSocialServiceGovernmentProgramResp{ + Code: 404, + Msg: "未找到该社会服务政府项目(已删除)", + }, nil + } + + // 核心修复:手动映射model层结构体到types层(解决类型不匹配) + data := types.SocialServiceGovernmentProgram{ + Id: program.Id, + Title: program.Title, + Subtitle: program.Subtitle, + CoverUrl: program.CoverUrl, + Intro: program.Intro, + Content: getNullStringValue(program.Content), + ImageEditors: program.ImageEditors, + TextEditors: program.TextEditors, + ChiefEditor: program.ChiefEditor, + Proofreaders: program.Proofreaders, + Reviewers: program.Reviewers, + PublishTime: program.PublishTime.Format("2006-01-02 15:04:05"), + UpdateTime: program.UpdateTime.Format("2006-01-02 15:04:05"), + } + + // 4. 构造成功响应 + resp = &types.GetSocialServiceGovernmentProgramResp{ + Code: 0, + Msg: "查询成功", + Data: data, // 传入映射后的types层结构体 + } + + return resp, nil +} + +func getNullStringValue(nullStr sql.NullString) string { + if nullStr.Valid { + return nullStr.String + } + return "" } diff --git a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/listsocialservicegovernmentprogramlogic.go b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/listsocialservicegovernmentprogramlogic.go index 3da7bc61..d4951b09 100644 --- a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/listsocialservicegovernmentprogramlogic.go +++ b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/listsocialservicegovernmentprogramlogic.go @@ -5,6 +5,7 @@ package socialServiceGovernmentProgram import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/model" @@ -30,7 +31,73 @@ func NewListSocialServiceGovernmentProgramLogic(ctx context.Context, cfg *config } func (l *ListSocialServiceGovernmentProgramLogic) ListSocialServiceGovernmentProgram(req *types.ListSocialServiceGovernmentProgramReq) (resp *types.ListSocialServiceGovernmentProgramResp, err error) { - // todo: add your logic here and delete this line + // 1. 分页参数校验(与请求参数validate规则保持一致) + if req.Page < 1 { + req.Page = 1 // 默认第一页 + } + if req.PageSize < 1 || req.PageSize > 100 { + req.PageSize = 10 // 默认10条/页,最大100条 + } - return + // 2. 计算分页偏移量(offset = (page-1) * pageSize) + offset := (req.Page - 1) * req.PageSize + + // 3. 调用model层查询:先查总数,再查列表数据 + // 3.1 查询符合条件的总条数(过滤已删除记录) + total, err := l.model.Count(context.Background()) + if err != nil { + fmt.Printf("查询社会服务政府项目总数失败:%v\n", err) + return &types.ListSocialServiceGovernmentProgramResp{ + Code: 500, + Msg: "获取列表总数失败,请稍后重试", + }, nil + } + + // 3.2 查询当前页数据(带分页+软删除过滤) + list, err := l.model.ListByPage( + context.Background(), + offset, + req.PageSize, + ) + if err != nil { + fmt.Printf("查询社会服务政府项目列表失败,offset:%d,pageSize:%d,错误:%v\n", offset, req.PageSize, err) + return &types.ListSocialServiceGovernmentProgramResp{ + Code: 500, + Msg: "获取项目列表失败,请稍后重试", + }, nil + } + + // 4. 批量转换model层数据到types层(处理类型差异) + typesList := make([]types.SocialServiceGovernmentProgram, 0, len(list)) + for _, item := range list { + // 单个项目数据转换(复用之前的字段映射逻辑) + typesItem := types.SocialServiceGovernmentProgram{ + Id: item.Id, + Title: item.Title, + Subtitle: item.Subtitle, + CoverUrl: item.CoverUrl, + Intro: item.Intro, + Content: getNullStringValue(item.Content), // 处理sql.NullString→string + ImageEditors: item.ImageEditors, + TextEditors: item.TextEditors, + ChiefEditor: item.ChiefEditor, + Proofreaders: item.Proofreaders, + Reviewers: item.Reviewers, + PublishTime: item.PublishTime.Format("2006-01-02 15:04:05"), // time.Time→string + UpdateTime: item.UpdateTime.Format("2006-01-02 15:04:05"), + } + typesList = append(typesList, typesItem) + } + + // 5. 构造分页响应 + resp = &types.ListSocialServiceGovernmentProgramResp{ + Code: 0, + Msg: "查询成功", + Data: types.ListSocialServiceGovernmentProgramData{ + Total: total, // 总条数 + List: typesList, // 转换后的当前页数据 + }, + } + + return resp, nil } diff --git a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/updatesocialservicegovernmentprogramlogic.go b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/updatesocialservicegovernmentprogramlogic.go index b4e5578c..101a8c70 100644 --- a/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/updatesocialservicegovernmentprogramlogic.go +++ b/server/internal/social_service_governmentprogram/internal/logic/socialServiceGovernmentProgram/updatesocialservicegovernmentprogramlogic.go @@ -5,6 +5,9 @@ package socialServiceGovernmentProgram import ( "context" + "database/sql" + "fmt" + "time" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/internal/model" @@ -30,7 +33,84 @@ func NewUpdateSocialServiceGovernmentProgramLogic(ctx context.Context, cfg *conf } func (l *UpdateSocialServiceGovernmentProgramLogic) UpdateSocialServiceGovernmentProgram(req *types.UpdateSocialServiceGovernmentProgramReq) (resp *types.UpdateSocialServiceGovernmentProgramResp, err error) { - // todo: add your logic here and delete this line + // 1. 验证ID合法性(路径参数) + if req.Id <= 0 { + return &types.UpdateSocialServiceGovernmentProgramResp{ + Code: 400, + Msg: "项目ID不合法,必须大于0", + }, nil + } - return + // 2. 查询原记录(检查是否存在且未被删除) + oldProgram, err := l.model.FindOne(context.Background(), req.Id) + if err != nil { + if err == model.ErrNotFound { + return &types.UpdateSocialServiceGovernmentProgramResp{ + Code: 404, + Msg: "未找到该社会服务政府项目(或已被删除)", + }, nil + } + fmt.Printf("查询待更新项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.UpdateSocialServiceGovernmentProgramResp{ + Code: 500, + Msg: "查询项目信息失败,请稍后重试", + }, nil + } + + // 3. 构造更新数据(复用原记录字段,仅覆盖req中提供的非空值) + updateData := &model.SocialServiceGovernmentprogram{ + Id: req.Id, // 必须携带ID用于WHERE条件 + // 基础字段:优先使用req中的值,未提供则保留原记录值 + Title: getUpdateValue(req.Title, oldProgram.Title), + Subtitle: getUpdateValue(req.Subtitle, oldProgram.Subtitle), + CoverUrl: getUpdateValue(req.CoverUrl, oldProgram.CoverUrl), + Intro: getUpdateValue(req.Intro, oldProgram.Intro), + // 特殊类型:string → sql.NullString(处理Content字段) + Content: getNullStringFromUpdate(req.Content, oldProgram.Content), + ImageEditors: getUpdateValue(req.ImageEditors, oldProgram.ImageEditors), + TextEditors: getUpdateValue(req.TextEditors, oldProgram.TextEditors), + ChiefEditor: getUpdateValue(req.ChiefEditor, oldProgram.ChiefEditor), + Proofreaders: getUpdateValue(req.Proofreaders, oldProgram.Proofreaders), + Reviewers: getUpdateValue(req.Reviewers, oldProgram.Reviewers), + // 时间字段:保留原发布时间,更新最后修改时间为当前时间 + PublishTime: oldProgram.PublishTime, // 发布时间不随更新改变(除非有特殊需求) + UpdateTime: time.Now(), // 强制更新为当前时间 + IsDelete: oldProgram.IsDelete, // 保留原删除状态(不允许通过更新接口修改删除状态) + } + + // 4. 调用model执行更新 + err = l.model.Update(context.Background(), updateData) + if err != nil { + fmt.Printf("更新社会服务政府项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.UpdateSocialServiceGovernmentProgramResp{ + Code: 500, + Msg: "项目更新失败,请稍后重试", + }, nil + } + + // 5. 构造成功响应 + resp = &types.UpdateSocialServiceGovernmentProgramResp{ + Code: 0, + Msg: "项目更新成功", + } + + return resp, nil +} +func getUpdateValue(newVal, oldVal string) string { + if newVal != "" { + return newVal + } + return oldVal +} + +// getNullStringFromUpdate:处理Content字段的更新(string → sql.NullString) +// 若请求中提供了新内容,则包装为有效NullString;否则保留原记录的NullString +func getNullStringFromUpdate(newContent string, oldNull sql.NullString) sql.NullString { + if newContent != "" { + return sql.NullString{ + String: newContent, + Valid: true, + } + } + return oldNull } diff --git a/server/internal/social_service_governmentprogram/internal/model/socialservicegovernmentprogrammodel_gen.go b/server/internal/social_service_governmentprogram/internal/model/socialservicegovernmentprogrammodel_gen.go index 0bdc02db..2cb906a4 100644 --- a/server/internal/social_service_governmentprogram/internal/model/socialservicegovernmentprogrammodel_gen.go +++ b/server/internal/social_service_governmentprogram/internal/model/socialservicegovernmentprogrammodel_gen.go @@ -29,6 +29,8 @@ type ( FindOne(ctx context.Context, id int64) (*SocialServiceGovernmentprogram, error) Update(ctx context.Context, data *SocialServiceGovernmentprogram) error Delete(ctx context.Context, id int64) error + Count(ctx context.Context) (int64, error) + ListByPage(ctx context.Context, offset, limit int) ([]*SocialServiceGovernmentprogram, error) } defaultSocialServiceGovernmentprogramModel struct { @@ -62,13 +64,14 @@ func newSocialServiceGovernmentprogramModel(conn sqlx.SqlConn) *defaultSocialSer } func (m *defaultSocialServiceGovernmentprogramModel) Delete(ctx context.Context, id int64) error { - query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + // 软删除:更新is_delete字段为1(1=已删除),保留数据记录 + query := fmt.Sprintf("UPDATE %s SET `is_delete` = 1, `update_time` = NOW() WHERE `id` = ? AND `is_delete` = 0", m.table) _, err := m.conn.ExecCtx(ctx, query, id) return err } func (m *defaultSocialServiceGovernmentprogramModel) FindOne(ctx context.Context, id int64) (*SocialServiceGovernmentprogram, error) { - query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", socialServiceGovernmentprogramRows, m.table) + query := fmt.Sprintf("select %s from %s where `id` = ? and `is_delete` = 0 limit 1", socialServiceGovernmentprogramRows, m.table) var resp SocialServiceGovernmentprogram err := m.conn.QueryRowCtx(ctx, &resp, query, id) switch err { @@ -93,6 +96,28 @@ func (m *defaultSocialServiceGovernmentprogramModel) Update(ctx context.Context, return err } +func (m *defaultSocialServiceGovernmentprogramModel) Count(ctx context.Context) (int64, error) { + query := fmt.Sprintf("select count(*) from %s where `is_delete` = 0", m.table) + var total int64 + err := m.conn.QueryRowCtx(ctx, &total, query) + return total, err +} + +// 2. 分页查询列表数据(带偏移量+限制条数+软删除过滤) +func (m *defaultSocialServiceGovernmentprogramModel) ListByPage(ctx context.Context, offset, limit int) ([]*SocialServiceGovernmentprogram, error) { + query := fmt.Sprintf( + "select %s from %s where `is_delete` = 0 order by `id` desc limit ?, ?", + socialServiceGovernmentprogramRows, // 包内全局变量直接引用,无前缀 + m.table, + ) + var list []*SocialServiceGovernmentprogram // 包内结构体直接引用,无model.前缀 + err := m.conn.QueryRowsCtx(ctx, &list, query, offset, limit) + if err != nil { + return nil, err + } + return list, nil +} + func (m *defaultSocialServiceGovernmentprogramModel) tableName() string { return m.table } diff --git a/server/internal/social_service_governmentprogram/internal/types/types.go b/server/internal/social_service_governmentprogram/internal/types/types.go index 0ada31c3..3bbfb573 100644 --- a/server/internal/social_service_governmentprogram/internal/types/types.go +++ b/server/internal/social_service_governmentprogram/internal/types/types.go @@ -56,8 +56,8 @@ type ListSocialServiceGovernmentProgramData struct { } type ListSocialServiceGovernmentProgramReq struct { - Page int `json:"page" form:"page" validate:"min=1"` // 页码(默认1) - PageSize int `json:"page_size" form:"page_size" validate:"min=1,max=100"` // 每页条数(默认10,最大100) + Page int `json:"page" validate:"min=1"` // 页码(默认1) + PageSize int `json:"page_size" validate:"min=1,max=100"` // 每页条数(默认10,最大100) } type ListSocialServiceGovernmentProgramResp struct { @@ -83,17 +83,17 @@ type SocialServiceGovernmentProgram struct { } type UpdateSocialServiceGovernmentProgramReq struct { - Id int64 `json:"-" path:"id" validate:"min=1"` // 社会服务政府项目ID(路径参数,必填) - Title string `json:"title,omitempty"` // 标题 - Subtitle string `json:"subtitle,omitempty"` // 副标题 - CoverUrl string `json:"cover_url,omitempty"` // 封面图片URL - Intro string `json:"intro,omitempty"` // 简介(纯文字) - Content string `json:"content,omitempty"` // 内容(Markdown格式) - ImageEditors string `json:"image_editors,omitempty"` // 图片编辑者名单(逗号分隔) - TextEditors string `json:"text_editors,omitempty"` // 文字编辑者名单(逗号分隔) - ChiefEditor string `json:"chief_editor,omitempty"` // 总编辑 - Proofreaders string `json:"proofreaders,omitempty"` // 校对者名单(逗号分隔) - Reviewers string `json:"reviewers,omitempty"` // 审核者名单(逗号分隔) + Id int64 `json:"id" validate:"min=1"` // 社会服务政府项目ID(路径参数,必填) + Title string `json:"title,omitempty"` // 标题 + Subtitle string `json:"subtitle,omitempty"` // 副标题 + CoverUrl string `json:"cover_url,omitempty"` // 封面图片URL + Intro string `json:"intro,omitempty"` // 简介(纯文字) + Content string `json:"content,omitempty"` // 内容(Markdown格式) + ImageEditors string `json:"image_editors,omitempty"` // 图片编辑者名单(逗号分隔) + TextEditors string `json:"text_editors,omitempty"` // 文字编辑者名单(逗号分隔) + ChiefEditor string `json:"chief_editor,omitempty"` // 总编辑 + Proofreaders string `json:"proofreaders,omitempty"` // 校对者名单(逗号分隔) + Reviewers string `json:"reviewers,omitempty"` // 审核者名单(逗号分隔) } type UpdateSocialServiceGovernmentProgramResp struct { diff --git a/server/internal/social_service_internship/handler/socialServiceInternship/deletesocialserviceinternshiphandler.go b/server/internal/social_service_internship/handler/socialServiceInternship/deletesocialserviceinternshiphandler.go index 105fcf21..b5ebaad0 100644 --- a/server/internal/social_service_internship/handler/socialServiceInternship/deletesocialserviceinternshiphandler.go +++ b/server/internal/social_service_internship/handler/socialServiceInternship/deletesocialserviceinternshiphandler.go @@ -6,6 +6,8 @@ package socialServiceInternship import ( "fmt" "net/http" + "strconv" + "strings" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/logic/socialServiceInternship" @@ -18,10 +20,19 @@ import ( func DeleteSocialServiceInternshipHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.DeleteSocialServiceInternshipReq - if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + pathParts := strings.Split(r.URL.Path, "/") + if len(pathParts) < 4 { // 确保路径格式正确 + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format")) return } + idStr := pathParts[4] + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil { + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID")) + return + } + fmt.Println("idStr:", idStr) + req.Id = id mysqlCfg := cfg.MySQL dsn := fmt.Sprintf( diff --git a/server/internal/social_service_internship/handler/socialServiceInternship/getsocialserviceinternshiphandler.go b/server/internal/social_service_internship/handler/socialServiceInternship/getsocialserviceinternshiphandler.go index 94139324..3f0ed3d7 100644 --- a/server/internal/social_service_internship/handler/socialServiceInternship/getsocialserviceinternshiphandler.go +++ b/server/internal/social_service_internship/handler/socialServiceInternship/getsocialserviceinternshiphandler.go @@ -6,6 +6,8 @@ package socialServiceInternship import ( "fmt" "net/http" + "strconv" + "strings" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/logic/socialServiceInternship" @@ -18,10 +20,19 @@ import ( func GetSocialServiceInternshipHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.GetSocialServiceInternshipReq - if err := httpx.Parse(r, &req); err != nil { - httpx.ErrorCtx(r.Context(), w, err) + pathParts := strings.Split(r.URL.Path, "/") + if len(pathParts) < 4 { // 确保路径格式正确 + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid path format")) return } + idStr := pathParts[4] + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil { + httpx.ErrorCtx(r.Context(), w, fmt.Errorf("invalid meeting ID")) + return + } + fmt.Println("idStr:", idStr) + req.Id = id mysqlCfg := cfg.MySQL dsn := fmt.Sprintf( diff --git a/server/internal/social_service_internship/internal/logic/socialServiceInternship/createsocialserviceinternshiplogic.go b/server/internal/social_service_internship/internal/logic/socialServiceInternship/createsocialserviceinternshiplogic.go index f233b36a..f7cd6c87 100644 --- a/server/internal/social_service_internship/internal/logic/socialServiceInternship/createsocialserviceinternshiplogic.go +++ b/server/internal/social_service_internship/internal/logic/socialServiceInternship/createsocialserviceinternshiplogic.go @@ -5,6 +5,9 @@ package socialServiceInternship import ( "context" + "database/sql" + "fmt" + "time" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/model" @@ -30,7 +33,68 @@ func NewCreateSocialServiceInternshipLogic(ctx context.Context, cfg *config.Conf } func (l *CreateSocialServiceInternshipLogic) CreateSocialServiceInternship(req *types.CreateSocialServiceInternshipReq) (resp *types.CreateSocialServiceInternshipResp, err error) { - // todo: add your logic here and delete this line + // 1. 兜底验证必填参数(补充validate标签的校验漏洞) + if req.Title == "" { + return &types.CreateSocialServiceInternshipResp{ + Code: 400, // 参数错误码 + Msg: "标题不能为空", + }, nil + } - return + // 2. 构造数据库实体(严格对应表字段与Insert参数顺序) + dbData := &model.SocialServiceInternship{ + Title: req.Title, + Subtitle: req.Subtitle, + CoverUrl: req.CoverUrl, + Intro: req.Intro, + // 关键:string → sql.NullString(适配model层字段类型) + Content: getNullString(req.Content), + ImageEditors: req.ImageEditors, + TextEditors: req.TextEditors, + ChiefEditor: req.ChiefEditor, + Proofreaders: req.Proofreaders, + Reviewers: req.Reviewers, + // 按要求格式设置发布时间(yyyy-MM-dd HH:mm:ss) + PublishTime: time.Now(), + IsDelete: 0, // 默认未删除(适配软删除逻辑) + } + + // 3. 调用model插入数据 + result, err := l.model.Insert(context.Background(), dbData) + if err != nil { + fmt.Printf("插入社会服务实习项目失败:%v\n", err) + return &types.CreateSocialServiceInternshipResp{ + Code: 500, // 服务器/数据库错误码 + Msg: "实习项目创建失败,请稍后重试", + }, nil + } + + // 4. 获取新增记录的主键ID + newId, err := result.LastInsertId() + if err != nil { + fmt.Printf("获取新增实习项目ID失败:%v\n", err) + return &types.CreateSocialServiceInternshipResp{ + Code: 500, + Msg: "实习项目创建成功,但获取ID失败", + }, nil + } + + // 5. 构造成功响应 + resp = &types.CreateSocialServiceInternshipResp{ + Code: 0, // 0表示成功 + Msg: "实习项目创建成功", + Data: types.CreateSocialServiceInternshipData{ + Id: newId, // 返回新增ID供前端后续使用 + }, + } + + return resp, nil +} + +// 辅助函数:string → sql.NullString(适配model层Content字段类型) +func getNullString(val string) sql.NullString { + return sql.NullString{ + String: val, + Valid: val != "", // 非空字符串标记为有效,空字符串标记为无效(数据库存NULL) + } } diff --git a/server/internal/social_service_internship/internal/logic/socialServiceInternship/deletesocialserviceinternshiplogic.go b/server/internal/social_service_internship/internal/logic/socialServiceInternship/deletesocialserviceinternshiplogic.go index f903d3de..28e32c95 100644 --- a/server/internal/social_service_internship/internal/logic/socialServiceInternship/deletesocialserviceinternshiplogic.go +++ b/server/internal/social_service_internship/internal/logic/socialServiceInternship/deletesocialserviceinternshiplogic.go @@ -5,6 +5,7 @@ package socialServiceInternship import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/model" @@ -30,7 +31,45 @@ func NewDeleteSocialServiceInternshipLogic(ctx context.Context, cfg *config.Conf } func (l *DeleteSocialServiceInternshipLogic) DeleteSocialServiceInternship(req *types.DeleteSocialServiceInternshipReq) (resp *types.DeleteSocialServiceInternshipResp, err error) { - // todo: add your logic here and delete this line + // 1. 兜底验证ID合法性(补充validate标签校验漏洞) + if req.Id <= 0 { + return &types.DeleteSocialServiceInternshipResp{ + Code: 400, + Msg: "实习项目ID不合法,必须大于0", + }, nil + } - return + // 2. 先查询记录是否存在且未被删除(避免删除不存在/已删除的记录) + _, err = l.model.FindOne(context.Background(), req.Id) + if err != nil { + if err == model.ErrNotFound { + return &types.DeleteSocialServiceInternshipResp{ + Code: 404, + Msg: "未找到该社会服务实习项目(或已被删除)", + }, nil + } + fmt.Printf("查询待删除实习项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.DeleteSocialServiceInternshipResp{ + Code: 500, + Msg: "查询项目信息失败,请稍后重试", + }, nil + } + + // 3. 调用Model层执行软删除(已修改为更新is_delete=1) + err = l.model.Delete(context.Background(), req.Id) + if err != nil { + fmt.Printf("软删除社会服务实习项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.DeleteSocialServiceInternshipResp{ + Code: 500, + Msg: "项目删除失败,请稍后重试", + }, nil + } + + // 4. 构造成功响应 + resp = &types.DeleteSocialServiceInternshipResp{ + Code: 0, + Msg: "实习项目删除成功", + } + + return resp, nil } diff --git a/server/internal/social_service_internship/internal/logic/socialServiceInternship/getsocialserviceinternshiplogic.go b/server/internal/social_service_internship/internal/logic/socialServiceInternship/getsocialserviceinternshiplogic.go index d875660f..9cbdb7c1 100644 --- a/server/internal/social_service_internship/internal/logic/socialServiceInternship/getsocialserviceinternshiplogic.go +++ b/server/internal/social_service_internship/internal/logic/socialServiceInternship/getsocialserviceinternshiplogic.go @@ -5,6 +5,8 @@ package socialServiceInternship import ( "context" + "database/sql" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/model" @@ -30,7 +32,71 @@ func NewGetSocialServiceInternshipLogic(ctx context.Context, cfg *config.Config, } func (l *GetSocialServiceInternshipLogic) GetSocialServiceInternship(req *types.GetSocialServiceInternshipReq) (resp *types.GetSocialServiceInternshipResp, err error) { - // todo: add your logic here and delete this line + // 1. 兜底验证参数合法性 + if req.Id <= 0 { + return &types.GetSocialServiceInternshipResp{ + Code: 400, + Msg: "实习项目ID不合法,必须大于0", + }, nil + } - return + // 2. 调用Model查询详情(已添加软删除过滤) + internship, err := l.model.FindOne(context.Background(), req.Id) + if err != nil { + // 区分"未找到"和"数据库错误" + if err == model.ErrNotFound { + return &types.GetSocialServiceInternshipResp{ + Code: 404, + Msg: "未找到该社会服务实习项目", + }, nil + } + fmt.Printf("查询社会服务实习项目详情失败,ID:%d,错误:%v\n", req.Id, err) + return &types.GetSocialServiceInternshipResp{ + Code: 500, + Msg: "查询项目详情失败,请稍后重试", + }, nil + } + + // 3. 软删除二次校验(双重保障,避免漏过滤) + if internship.IsDelete == 1 { + return &types.GetSocialServiceInternshipResp{ + Code: 404, + Msg: "未找到该社会服务实习项目(已删除)", + }, nil + } + + // 4. 手动映射Model→Types(处理类型转换) + data := types.SocialServiceInternship{ + Id: internship.Id, + Title: internship.Title, + Subtitle: internship.Subtitle, + CoverUrl: internship.CoverUrl, + Intro: internship.Intro, + // 关键:sql.NullString → string(处理Content字段) + Content: getNullStringValue(internship.Content), + ImageEditors: internship.ImageEditors, + TextEditors: internship.TextEditors, + ChiefEditor: internship.ChiefEditor, + Proofreaders: internship.Proofreaders, + Reviewers: internship.Reviewers, + // 关键:time.Time → string(按要求格式) + PublishTime: internship.PublishTime.Format("2006-01-02 15:04:05"), + UpdateTime: internship.UpdateTime.Format("2006-01-02 15:04:05"), + } + + // 5. 构造成功响应 + resp = &types.GetSocialServiceInternshipResp{ + Code: 0, + Msg: "查询成功", + Data: data, + } + + return resp, nil +} + +func getNullStringValue(nullStr sql.NullString) string { + if nullStr.Valid { + return nullStr.String + } + return "" } diff --git a/server/internal/social_service_internship/internal/logic/socialServiceInternship/listsocialserviceinternshiplogic.go b/server/internal/social_service_internship/internal/logic/socialServiceInternship/listsocialserviceinternshiplogic.go index 5fb69596..3f5bb150 100644 --- a/server/internal/social_service_internship/internal/logic/socialServiceInternship/listsocialserviceinternshiplogic.go +++ b/server/internal/social_service_internship/internal/logic/socialServiceInternship/listsocialserviceinternshiplogic.go @@ -5,6 +5,7 @@ package socialServiceInternship import ( "context" + "fmt" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/model" @@ -30,7 +31,78 @@ func NewListSocialServiceInternshipLogic(ctx context.Context, cfg *config.Config } func (l *ListSocialServiceInternshipLogic) ListSocialServiceInternship(req *types.ListSocialServiceInternshipReq) (resp *types.ListSocialServiceInternshipResp, err error) { - // todo: add your logic here and delete this line + // 1. 分页参数校验与兜底(兼容前端未传/传参非法场景) + if req.Page < 1 { + req.Page = 1 // 默认第一页 + } + if req.PageSize < 1 || req.PageSize > 100 { + req.PageSize = 10 // 默认10条/页,最大限制100条 + } - return + // 2. 计算分页偏移量(offset = (page-1) * pageSize) + offset := (req.Page - 1) * req.PageSize + + // 3. 调用Model层查询:先查总数,再查分页数据 + // 3.1 查询未删除的总条数 + total, err := l.model.Count(context.Background()) + if err != nil { + fmt.Printf("查询社会服务实习项目总数失败:%v\n", err) + return &types.ListSocialServiceInternshipResp{ + Code: 500, + Msg: "获取列表总数失败,请稍后重试", + }, nil + } + + // 3.2 查询当前页数据(带软删除过滤+分页+排序) + list, err := l.model.ListByPage( + context.Background(), + offset, + req.PageSize, + ) + if err != nil { + fmt.Printf("查询实习项目列表失败,offset:%d,pageSize:%d,错误:%v\n", offset, req.PageSize, err) + return &types.ListSocialServiceInternshipResp{ + Code: 500, + Msg: "获取项目列表失败,请稍后重试", + }, nil + } + + // 4. 批量转换Model→Types(处理类型差异,批量映射) + typesList := make([]types.SocialServiceInternship, 0, len(list)) // 预分配容量提升性能 + for _, item := range list { + typesItem := types.SocialServiceInternship{ + Id: item.Id, + Title: item.Title, + Subtitle: item.Subtitle, + CoverUrl: item.CoverUrl, + Intro: item.Intro, + // sql.NullString → string(复用辅助函数) + Content: getNullStringValue(item.Content), + ImageEditors: item.ImageEditors, + TextEditors: item.TextEditors, + ChiefEditor: item.ChiefEditor, + Proofreaders: item.Proofreaders, + Reviewers: item.Reviewers, + // time.Time → string(按要求格式:yyyy-MM-dd HH:mm:ss) + PublishTime: item.PublishTime.Format("2006-01-02 15:04:05"), + UpdateTime: item.UpdateTime.Format("2006-01-02 15:04:05"), + } + typesList = append(typesList, typesItem) + } + + // 5. 构造分页响应 + resp = &types.ListSocialServiceInternshipResp{ + Code: 0, + Msg: "查询成功", + Data: types.ListSocialServiceInternshipData{ + Total: total, // 总条数(用于前端计算总页数) + List: typesList, // 当前页转换后的数据列表 + }, + } + + return resp, nil } + +// ------------------------------ +// 依赖的辅助函数(复用自Get接口,无需重复定义) +// ------------------------------ diff --git a/server/internal/social_service_internship/internal/logic/socialServiceInternship/updatesocialserviceinternshiplogic.go b/server/internal/social_service_internship/internal/logic/socialServiceInternship/updatesocialserviceinternshiplogic.go index cbc85fc1..c73f32fa 100644 --- a/server/internal/social_service_internship/internal/logic/socialServiceInternship/updatesocialserviceinternshiplogic.go +++ b/server/internal/social_service_internship/internal/logic/socialServiceInternship/updatesocialserviceinternshiplogic.go @@ -5,6 +5,9 @@ package socialServiceInternship import ( "context" + "database/sql" + "fmt" + "time" "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/internal/model" @@ -30,7 +33,91 @@ func NewUpdateSocialServiceInternshipLogic(ctx context.Context, cfg *config.Conf } func (l *UpdateSocialServiceInternshipLogic) UpdateSocialServiceInternship(req *types.UpdateSocialServiceInternshipReq) (resp *types.UpdateSocialServiceInternshipResp, err error) { - // todo: add your logic here and delete this line + // 1. 验证ID合法性(路径参数必填且有效) + if req.Id <= 0 { + return &types.UpdateSocialServiceInternshipResp{ + Code: 400, + Msg: "实习项目ID不合法,必须大于0", + }, nil + } - return + // 2. 查询原记录(确认存在且未被软删除) + oldInternship, err := l.model.FindOne(context.Background(), req.Id) + if err != nil { + if err == model.ErrNotFound { + return &types.UpdateSocialServiceInternshipResp{ + Code: 404, + Msg: "未找到该社会服务实习项目(或已被删除)", + }, nil + } + fmt.Printf("查询待更新实习项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.UpdateSocialServiceInternshipResp{ + Code: 500, + Msg: "查询项目信息失败,请稍后重试", + }, nil + } + + // 3. 构造更新数据(增量更新:仅覆盖请求中提供的非空值,其余保留原记录) + updateData := &model.SocialServiceInternship{ + Id: req.Id, // 主键ID,用于SQL WHERE条件 + // 基础字段:有新值则更新,无则保留原值 + Title: getUpdateValue(req.Title, oldInternship.Title), + Subtitle: getUpdateValue(req.Subtitle, oldInternship.Subtitle), + CoverUrl: getUpdateValue(req.CoverUrl, oldInternship.CoverUrl), + Intro: getUpdateValue(req.Intro, oldInternship.Intro), + // 特殊字段:string → sql.NullString(适配Content字段类型) + Content: getNullStringFromUpdate(req.Content, oldInternship.Content), + ImageEditors: getUpdateValue(req.ImageEditors, oldInternship.ImageEditors), + TextEditors: getUpdateValue(req.TextEditors, oldInternship.TextEditors), + ChiefEditor: getUpdateValue(req.ChiefEditor, oldInternship.ChiefEditor), + Proofreaders: getUpdateValue(req.Proofreaders, oldInternship.Proofreaders), + Reviewers: getUpdateValue(req.Reviewers, oldInternship.Reviewers), + // 时间字段:发布时间保留原值,更新时间强制设为当前时间 + PublishTime: oldInternship.PublishTime, // 发布时间不随更新改变 + UpdateTime: time.Now(), // 最后修改时间自动更新 + IsDelete: oldInternship.IsDelete, // 保留删除状态(不允许通过更新接口修改) + } + + // 4. 调用Model层执行更新 + err = l.model.Update(context.Background(), updateData) + if err != nil { + fmt.Printf("更新社会服务实习项目失败,ID:%d,错误:%v\n", req.Id, err) + return &types.UpdateSocialServiceInternshipResp{ + Code: 500, + Msg: "项目更新失败,请稍后重试", + }, nil + } + + // 5. 构造成功响应 + resp = &types.UpdateSocialServiceInternshipResp{ + Code: 0, + Msg: "实习项目更新成功", + } + + return resp, nil +} + +// ------------------------------ +// 辅助函数(复用自政府项目模块,无需重复开发) +// ------------------------------ + +// getUpdateValue:处理普通字符串字段的增量更新 +func getUpdateValue(newVal, oldVal string) string { + if newVal != "" { + return newVal // 有新值则使用新值 + } + return oldVal // 无新值则保留原值 +} + +// getNullStringFromUpdate:处理Content字段的增量更新(string → sql.NullString) +func getNullStringFromUpdate(newContent string, oldNull sql.NullString) sql.NullString { + if newContent != "" { + // 新值非空:包装为有效sql.NullString + return sql.NullString{ + String: newContent, + Valid: true, + } + } + // 新值为空:保留原记录的sql.NullString状态(可能是NULL或有效字符串) + return oldNull } diff --git a/server/internal/social_service_internship/internal/model/socialserviceinternshipmodel_gen.go b/server/internal/social_service_internship/internal/model/socialserviceinternshipmodel_gen.go index 2adad822..a731165e 100644 --- a/server/internal/social_service_internship/internal/model/socialserviceinternshipmodel_gen.go +++ b/server/internal/social_service_internship/internal/model/socialserviceinternshipmodel_gen.go @@ -29,6 +29,8 @@ type ( FindOne(ctx context.Context, id int64) (*SocialServiceInternship, error) Update(ctx context.Context, data *SocialServiceInternship) error Delete(ctx context.Context, id int64) error + Count(ctx context.Context) (int64, error) + ListByPage(ctx context.Context, offset, limit int) ([]*SocialServiceInternship, error) } defaultSocialServiceInternshipModel struct { @@ -62,13 +64,17 @@ func newSocialServiceInternshipModel(conn sqlx.SqlConn) *defaultSocialServiceInt } func (m *defaultSocialServiceInternshipModel) Delete(ctx context.Context, id int64) error { - query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + // 软删除逻辑:更新is_delete=1,保留数据;同时更新最后修改时间 + query := fmt.Sprintf( + "UPDATE %s SET `is_delete` = 1, `update_time` = NOW() WHERE `id` = ? AND `is_delete` = 0", + m.table, + ) _, err := m.conn.ExecCtx(ctx, query, id) return err } func (m *defaultSocialServiceInternshipModel) FindOne(ctx context.Context, id int64) (*SocialServiceInternship, error) { - query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", socialServiceInternshipRows, m.table) + query := fmt.Sprintf("select %s from %s where `id` = ? and `is_delete` = 0 limit 1", socialServiceInternshipRows, m.table) var resp SocialServiceInternship err := m.conn.QueryRowCtx(ctx, &resp, query, id) switch err { @@ -93,6 +99,29 @@ func (m *defaultSocialServiceInternshipModel) Update(ctx context.Context, data * return err } +func (m *defaultSocialServiceInternshipModel) Count(ctx context.Context) (int64, error) { + query := fmt.Sprintf("select count(*) from %s where `is_delete` = 0", m.table) + var total int64 + err := m.conn.QueryRowCtx(ctx, &total, query) + return total, err +} + +// ListByPage:分页查询未删除的记录(按ID倒序,最新在前) +func (m *defaultSocialServiceInternshipModel) ListByPage(ctx context.Context, offset, limit int) ([]*SocialServiceInternship, error) { + query := fmt.Sprintf( + "select %s from %s where `is_delete` = 0 order by `id` desc limit ?, ?", + socialServiceInternshipRows, // 包内全局变量,直接引用(无前缀) + m.table, + ) + // 修复点:切片类型去掉 model. 前缀(当前在model包内,直接使用结构体) + var list []*SocialServiceInternship + err := m.conn.QueryRowsCtx(ctx, &list, query, offset, limit) + if err != nil { + return nil, err + } + return list, nil +} + func (m *defaultSocialServiceInternshipModel) tableName() string { return m.table } diff --git a/server/internal/social_service_internship/internal/types/types.go b/server/internal/social_service_internship/internal/types/types.go index 0298bce1..4447847c 100644 --- a/server/internal/social_service_internship/internal/types/types.go +++ b/server/internal/social_service_internship/internal/types/types.go @@ -56,8 +56,8 @@ type ListSocialServiceInternshipData struct { } type ListSocialServiceInternshipReq struct { - Page int `json:"page" form:"page" validate:"min=1"` // 页码(默认1) - PageSize int `json:"page_size" form:"page_size" validate:"min=1,max=100"` // 每页条数(默认10,最大100) + Page int `json:"page" validate:"min=1"` // 页码(默认1) + PageSize int `json:"page_size" validate:"min=1,max=100"` // 每页条数(默认10,最大100) } type ListSocialServiceInternshipResp struct { @@ -83,17 +83,17 @@ type SocialServiceInternship struct { } type UpdateSocialServiceInternshipReq struct { - Id int64 `json:"-" path:"id" validate:"min=1"` // 社会服务实习ID(路径参数,必填) - Title string `json:"title,omitempty"` // 标题 - Subtitle string `json:"subtitle,omitempty"` // 副标题 - CoverUrl string `json:"cover_url,omitempty"` // 封面图片URL - Intro string `json:"intro,omitempty"` // 简介(纯文字) - Content string `json:"content,omitempty"` // 内容(Markdown格式) - ImageEditors string `json:"image_editors,omitempty"` // 图片编辑者名单(逗号分隔) - TextEditors string `json:"text_editors,omitempty"` // 文字编辑者名单(逗号分隔) - ChiefEditor string `json:"chief_editor,omitempty"` // 总编辑 - Proofreaders string `json:"proofreaders,omitempty"` // 校对者名单(逗号分隔) - Reviewers string `json:"reviewers,omitempty"` // 审核者名单(逗号分隔) + Id int64 `json:"id" validate:"min=1"` // 社会服务实习ID(路径参数,必填) + Title string `json:"title,omitempty"` // 标题 + Subtitle string `json:"subtitle,omitempty"` // 副标题 + CoverUrl string `json:"cover_url,omitempty"` // 封面图片URL + Intro string `json:"intro,omitempty"` // 简介(纯文字) + Content string `json:"content,omitempty"` // 内容(Markdown格式) + ImageEditors string `json:"image_editors,omitempty"` // 图片编辑者名单(逗号分隔) + TextEditors string `json:"text_editors,omitempty"` // 文字编辑者名单(逗号分隔) + ChiefEditor string `json:"chief_editor,omitempty"` // 总编辑 + Proofreaders string `json:"proofreaders,omitempty"` // 校对者名单(逗号分隔) + Reviewers string `json:"reviewers,omitempty"` // 审核者名单(逗号分隔) } type UpdateSocialServiceInternshipResp struct { diff --git a/server/router/router.go b/server/router/router.go index 790dc3c6..f575f8b6 100644 --- a/server/router/router.go +++ b/server/router/router.go @@ -9,6 +9,9 @@ import ( "github.com/JACKYMYPERSON/hldrCenter/internal/meetingspeaker/handler/meeting_speaker" "github.com/JACKYMYPERSON/hldrCenter/internal/pageimgs/handler/pageImage" ping "github.com/JACKYMYPERSON/hldrCenter/internal/ping/handler/ping" + "github.com/JACKYMYPERSON/hldrCenter/internal/social_service/handler/socialService" + "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_governmentprogram/handler/socialServiceGovernmentProgram" + "github.com/JACKYMYPERSON/hldrCenter/internal/social_service_internship/handler/socialServiceInternship" uploadimg "github.com/JACKYMYPERSON/hldrCenter/internal/upload/handler/upload" "github.com/JACKYMYPERSON/hldrCenter/middleware" "github.com/gin-gonic/gin" @@ -103,6 +106,51 @@ func SetupRouter(cfg *config.Config) *gin.Engine { // 4. 软删除嘉宾(DELETE /api/speakers/:id) speakers.DELETE("/:id", gin.WrapH(meeting_speaker.DeleteSpeakerHandler(cfg))) } + + // ------------ 社会服务基础模块 ------------ + socialServiceapi := api.Group("/social-service") + { + // 创建社会服务(POST /api/social-service) + socialServiceapi.POST("", gin.WrapH(socialService.CreateSocialServiceHandler(cfg))) + // 获取社会服务列表(GET /api/social-service/list) + socialServiceapi.POST("/list", gin.WrapH(socialService.ListSocialServiceHandler(cfg))) + // 获取社会服务详情(GET /api/social-service/:id) + socialServiceapi.GET("/:id", gin.WrapH(socialService.GetSocialServiceHandler(cfg))) + // 更新社会服务(PUT /api/social-service) + socialServiceapi.PUT("", gin.WrapH(socialService.UpdateSocialServiceHandler(cfg))) + // 删除社会服务(DELETE /api/social-service/:id) + socialServiceapi.DELETE("/:id", gin.WrapH(socialService.DeleteSocialServiceHandler(cfg))) + } + + // ------------ 社会服务实习模块 ------------ + socialServiceInternshipapi := api.Group("/social-service/internship") + { + // 创建社会服务实习(POST /api/social-service/internship) + socialServiceInternshipapi.POST("", gin.WrapH(socialServiceInternship.CreateSocialServiceInternshipHandler(cfg))) + // 获取社会服务实习列表(GET /api/social-service/internship/list) + socialServiceInternshipapi.POST("/list", gin.WrapH(socialServiceInternship.ListSocialServiceInternshipHandler(cfg))) + // 获取社会服务实习详情(GET /api/social-service/internship/:id) + socialServiceInternshipapi.GET("/:id", gin.WrapH(socialServiceInternship.GetSocialServiceInternshipHandler(cfg))) + // 更新社会服务实习(PUT /api/social-service/internship) + socialServiceInternshipapi.PUT("", gin.WrapH(socialServiceInternship.UpdateSocialServiceInternshipHandler(cfg))) + // 删除社会服务实习(DELETE /api/social-service/internship/:id) + socialServiceInternshipapi.DELETE("/:id", gin.WrapH(socialServiceInternship.DeleteSocialServiceInternshipHandler(cfg))) + } + + // ------------ 社会服务政府项目模块 ------------ + socialServiceGovProgramapi := api.Group("/social-service/government-program") + { + // 创建社会服务政府项目(POST /api/social-service/government-program) + socialServiceGovProgramapi.POST("", gin.WrapH(socialServiceGovernmentProgram.CreateSocialServiceGovernmentProgramHandler(cfg))) + // 获取社会服务政府项目列表(GET /api/social-service/government-program/list) + socialServiceGovProgramapi.POST("/list", gin.WrapH(socialServiceGovernmentProgram.ListSocialServiceGovernmentProgramHandler(cfg))) + // 获取社会服务政府项目详情(GET /api/social-service/government-program/:id) + socialServiceGovProgramapi.GET("/:id", gin.WrapH(socialServiceGovernmentProgram.GetSocialServiceGovernmentProgramHandler(cfg))) + // 更新社会服务政府项目(PUT /api/social-service/government-program) + socialServiceGovProgramapi.PUT("", gin.WrapH(socialServiceGovernmentProgram.UpdateSocialServiceGovernmentProgramHandler(cfg))) + // 删除社会服务政府项目(DELETE /api/social-service/government-program/:id) + socialServiceGovProgramapi.DELETE("/:id", gin.WrapH(socialServiceGovernmentProgram.DeleteSocialServiceGovernmentProgramHandler(cfg))) + } } return r