Skip to content

Commit 73fe98b

Browse files
authored
feat: 更新提案接口 (#61)
* feat: 更新提案接口
1 parent 40ee270 commit 73fe98b

File tree

8 files changed

+328
-35
lines changed

8 files changed

+328
-35
lines changed

api/handler/proposal.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,33 @@ func ApproveProposal(c *gin.Context) {
9595
// TODO: not implemented
9696
}
9797

98-
// UpdateProposal 修改提案
99-
// @router /api/proposal/{proposalId}/update [POST]
98+
// UpdateProposal 更新提案接口
99+
// @Summary 更新提案内容
100+
// @Description 根据提案ID修改提案的标题和内容
101+
// @Tags proposal
102+
// @Accept json
103+
// @Produce json
104+
// @Param proposalId path string true "提案唯一ID"
105+
// @Param body body dto.UpdateProposalReq true "更新参数(标题、内容)"
106+
// @Success 200 {object} dto.UpdateProposalResp "更新成功响应"
107+
// @Router /api/proposal/{proposalId}/update [post]
100108
func UpdateProposal(c *gin.Context) {
101-
// TODO: not implemented
109+
var req dto.UpdateProposalReq
110+
var resp *dto.UpdateProposalResp
111+
var err error
112+
113+
req.ProposalID = c.Param(consts.CtxProposalID)
114+
115+
if err = c.ShouldBindJSON(&req); err != nil {
116+
PostProcess(c, &req, nil, err)
117+
return
118+
}
119+
120+
c.Set(consts.CtxUserID, token.GetUserID(c))
121+
122+
resp, err = provider.Get().ProposalService.UpdateProposal(c, &req)
123+
124+
PostProcess(c, &req, resp, err)
102125
}
103126

104127
// DeleteProposal 删除提案

application/dto/proposal.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,17 @@ type GetProposalResp struct {
7373
*Resp
7474
Proposal *ProposalVO `json:"proposal"`
7575
}
76+
77+
// UpdateProposalReq 更新提案请求参数
78+
type UpdateProposalReq struct {
79+
ProposalID string `json:"-"`
80+
Title string `json:"title" binding:"required"`
81+
Content string `json:"content" binding:"required"`
82+
Course *CourseVO `json:"course" binding:"required"`
83+
}
84+
85+
// UpdateProposalResp 更新提案响应参数
86+
type UpdateProposalResp struct {
87+
*Resp `json:",inline"`
88+
ProposalID string `json:"proposalId"`
89+
}

application/service/proposal.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type IProposalService interface {
3939
CreateProposal(ctx context.Context, req *dto.CreateProposalReq) (*dto.CreateProposalResp, error)
4040
ListProposals(ctx context.Context, req *dto.ListProposalReq) (*dto.ListProposalResp, error)
4141
GetProposal(ctx context.Context, req *dto.GetProposalReq) (resp *dto.GetProposalResp, err error)
42+
UpdateProposal(ctx context.Context, req *dto.UpdateProposalReq) (*dto.UpdateProposalResp, error)
4243
}
4344

4445
type ProposalService struct {
@@ -216,3 +217,45 @@ func (s *ProposalService) GetProposal(ctx context.Context, req *dto.GetProposalR
216217
Proposal: vo,
217218
}, nil
218219
}
220+
221+
// UpdateProposal 更新提案
222+
func (s *ProposalService) UpdateProposal(ctx context.Context, req *dto.UpdateProposalReq) (*dto.UpdateProposalResp, error) {
223+
//鉴权
224+
userId, ok := ctx.Value(consts.CtxUserID).(string)
225+
if !ok || userId == "" {
226+
return nil, errorx.New(errno.ErrUserNotLogin)
227+
}
228+
//查询提案
229+
proposal, err := s.ProposalRepo.FindByID(ctx, req.ProposalID)
230+
if err != nil {
231+
logs.CtxErrorf(ctx, "[ProposalRepo] [FindByID] error: %v, proposalId: %s", err, req.ProposalID)
232+
return nil, errorx.WrapByCode(err, errno.ErrProposalFindFailed, errorx.KV("proposalId", req.ProposalID))
233+
}
234+
if proposal == nil {
235+
logs.CtxWarnf(ctx, "[ProposalRepo] [FindByID] proposal not found, proposalId: %s", req.ProposalID)
236+
return nil, errorx.New(errno.ErrProposalNotFound, errorx.KV("key", consts.ReqProposalID), errorx.KV("value", req.ProposalID))
237+
}
238+
239+
//更新提案字段
240+
proposal.Title = req.Title
241+
proposal.Content = req.Content
242+
courseModel, err := s.CourseAssembler.ToCourseDB(ctx, req.Course)
243+
if err != nil {
244+
return nil, errorx.WrapByCode(err, errno.ErrCourseCvtFailed,
245+
errorx.KV("src", "course vo"), errorx.KV("dst", "course model"),
246+
)
247+
}
248+
proposal.Course = courseModel
249+
proposal.UpdatedAt = time.Now()
250+
251+
// 执行更新
252+
if err = s.ProposalRepo.UpdateProposal(ctx, proposal); err != nil {
253+
logs.CtxErrorf(ctx, "[ProposalRepo] [UpdateProposal] error: %v, proposalId: %s", err, req.ProposalID)
254+
return nil, errorx.WrapByCode(err, errno.ErrProposalUpdateFailed, errorx.KV("proposalId", req.ProposalID))
255+
}
256+
257+
return &dto.UpdateProposalResp{
258+
Resp: dto.Success(),
259+
ProposalID: proposal.ID,
260+
}, nil
261+
}

docs/docs.go

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
// Copyright 2025 Boyuan-IT-Club
2-
//
3-
// Licensed under the Apache License, Version 2.0 (the "License");
4-
// you may not use this file except in compliance with the License.
5-
// You may obtain a copy of the License at
6-
//
7-
// http://www.apache.org/licenses/LICENSE-2.0
8-
//
9-
// Unless required by applicable law or agreed to in writing, software
10-
// distributed under the License is distributed on an "AS IS" BASIS,
11-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
// See the License for the specific language governing permissions and
13-
// limitations under the License.
14-
151
// Package docs Code generated by swaggo/swag. DO NOT EDIT
162
package docs
173

@@ -443,7 +429,55 @@ const docTemplate = `{
443429
},
444430
"/api/proposal/{proposalId}/update": {
445431
"post": {
446-
"responses": {}
432+
"description": "根据提案ID修改提案的标题和内容",
433+
"consumes": [
434+
"application/json"
435+
],
436+
"produces": [
437+
"application/json"
438+
],
439+
"tags": [
440+
"proposal"
441+
],
442+
"summary": "更新提案内容",
443+
"parameters": [
444+
{
445+
"type": "string",
446+
"description": "提案唯一ID",
447+
"name": "proposalId",
448+
"in": "path",
449+
"required": true
450+
},
451+
{
452+
"description": "更新参数(标题、内容)",
453+
"name": "body",
454+
"in": "body",
455+
"required": true,
456+
"schema": {
457+
"$ref": "#/definitions/dto.UpdateProposalReq"
458+
}
459+
}
460+
],
461+
"responses": {
462+
"200": {
463+
"description": "更新成功响应",
464+
"schema": {
465+
"$ref": "#/definitions/dto.UpdateProposalResp"
466+
}
467+
},
468+
"400": {
469+
"description": "参数错误响应",
470+
"schema": {
471+
"$ref": "#/definitions/dto.UpdateProposalResp"
472+
}
473+
},
474+
"500": {
475+
"description": "服务器内部错误响应",
476+
"schema": {
477+
"$ref": "#/definitions/dto.UpdateProposalResp"
478+
}
479+
}
480+
}
447481
}
448482
},
449483
"/api/search": {
@@ -1224,6 +1258,38 @@ const docTemplate = `{
12241258
"type": "string"
12251259
}
12261260
}
1261+
},
1262+
"dto.UpdateProposalReq": {
1263+
"type": "object",
1264+
"required": [
1265+
"content",
1266+
"title"
1267+
],
1268+
"properties": {
1269+
"content": {
1270+
"type": "string"
1271+
},
1272+
"title": {
1273+
"type": "string"
1274+
}
1275+
}
1276+
},
1277+
"dto.UpdateProposalResp": {
1278+
"type": "object",
1279+
"properties": {
1280+
"code": {
1281+
"type": "integer"
1282+
},
1283+
"message": {
1284+
"type": "string"
1285+
},
1286+
"msg": {
1287+
"type": "string"
1288+
},
1289+
"proposalId": {
1290+
"type": "string"
1291+
}
1292+
}
12271293
}
12281294
}
12291295
}`

docs/swagger.json

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,55 @@
422422
},
423423
"/api/proposal/{proposalId}/update": {
424424
"post": {
425-
"responses": {}
425+
"description": "根据提案ID修改提案的标题和内容",
426+
"consumes": [
427+
"application/json"
428+
],
429+
"produces": [
430+
"application/json"
431+
],
432+
"tags": [
433+
"proposal"
434+
],
435+
"summary": "更新提案内容",
436+
"parameters": [
437+
{
438+
"type": "string",
439+
"description": "提案唯一ID",
440+
"name": "proposalId",
441+
"in": "path",
442+
"required": true
443+
},
444+
{
445+
"description": "更新参数(标题、内容)",
446+
"name": "body",
447+
"in": "body",
448+
"required": true,
449+
"schema": {
450+
"$ref": "#/definitions/dto.UpdateProposalReq"
451+
}
452+
}
453+
],
454+
"responses": {
455+
"200": {
456+
"description": "更新成功响应",
457+
"schema": {
458+
"$ref": "#/definitions/dto.UpdateProposalResp"
459+
}
460+
},
461+
"400": {
462+
"description": "参数错误响应",
463+
"schema": {
464+
"$ref": "#/definitions/dto.UpdateProposalResp"
465+
}
466+
},
467+
"500": {
468+
"description": "服务器内部错误响应",
469+
"schema": {
470+
"$ref": "#/definitions/dto.UpdateProposalResp"
471+
}
472+
}
473+
}
426474
}
427475
},
428476
"/api/search": {
@@ -1203,6 +1251,38 @@
12031251
"type": "string"
12041252
}
12051253
}
1254+
},
1255+
"dto.UpdateProposalReq": {
1256+
"type": "object",
1257+
"required": [
1258+
"content",
1259+
"title"
1260+
],
1261+
"properties": {
1262+
"content": {
1263+
"type": "string"
1264+
},
1265+
"title": {
1266+
"type": "string"
1267+
}
1268+
}
1269+
},
1270+
"dto.UpdateProposalResp": {
1271+
"type": "object",
1272+
"properties": {
1273+
"code": {
1274+
"type": "integer"
1275+
},
1276+
"message": {
1277+
"type": "string"
1278+
},
1279+
"msg": {
1280+
"type": "string"
1281+
},
1282+
"proposalId": {
1283+
"type": "string"
1284+
}
1285+
}
12061286
}
12071287
}
12081288
}

0 commit comments

Comments
 (0)