@@ -16,27 +16,34 @@ package service
1616
1717import (
1818 "context"
19+ "time"
1920
2021 "github.com/Boyuan-IT-Club/Meowpick-Backend/application/assembler"
2122 "github.com/Boyuan-IT-Club/Meowpick-Backend/application/dto"
2223 "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/cache"
24+ "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/model"
2325 "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/repo"
26+ "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/util/mapping"
2427 "github.com/Boyuan-IT-Club/Meowpick-Backend/types/consts"
2528 "github.com/Boyuan-IT-Club/Meowpick-Backend/types/errno"
2629
2730 "github.com/Boyuan-IT-Club/go-kit/errorx"
2831 "github.com/Boyuan-IT-Club/go-kit/logs"
2932 "github.com/google/wire"
33+ "go.mongodb.org/mongo-driver/bson/primitive"
3034)
3135
3236var _ IProposalService = (* ProposalService )(nil )
3337
3438type IProposalService interface {
39+ CreateProposal (ctx context.Context , req * dto.CreateProposalReq ) (* dto.CreateProposalResp , error )
3540 ToggleProposal (ctx context.Context , req * dto.ToggleProposalReq ) (resp * dto.ToggleProposalResp , err error )
3641 ListProposals (ctx context.Context , req * dto.ListProposalReq ) (* dto.ListProposalResp , error )
3742}
3843
3944type ProposalService struct {
45+ CourseRepo * repo.CourseRepo
46+ CourseAssembler * assembler.CourseAssembler
4047 ProposalRepo * repo.ProposalRepo
4148 ProposalCache * cache.ProposalCache
4249 ProposalAssembler * assembler.ProposalAssembler
@@ -47,6 +54,96 @@ var ProposalServiceSet = wire.NewSet(
4754 wire .Bind (new (IProposalService ), new (* ProposalService )),
4855)
4956
57+ // CreateProposal 添加一个新的课程提案
58+ func (s * ProposalService ) CreateProposal (ctx context.Context , req * dto.CreateProposalReq ) (* dto.CreateProposalResp , error ) {
59+ // 鉴权
60+ userId , ok := ctx .Value (consts .CtxUserID ).(string )
61+ if ! ok || userId == "" {
62+ return nil , errorx .New (errno .ErrUserNotLogin )
63+ }
64+
65+ // 转换为 courseModel
66+ courseDB , err := s .CourseAssembler .ToCourseDB (ctx , req .Course )
67+ if err != nil {
68+ return nil , errorx .WrapByCode (err , errno .ErrCourseCvtFailed ,
69+ errorx .KV ("src" , "database course" ), errorx .KV ("dst" , "course vo" ),
70+ )
71+ }
72+
73+ // 检查是否已经存在相同的提案(前端传回的和我已有的ProposalCourse)
74+ existingProposal , err := s .ProposalRepo .IsCourseInExistingProposals (ctx , courseDB )
75+ if err != nil {
76+ return nil , errorx .WrapByCode (err , errno .ErrProposalCourseFindInProposalsFailed ,
77+ errorx .KV ("key" , consts .ReqCourse ),
78+ errorx .KV ("value" , req .Course .Name ),
79+ )
80+ }
81+
82+ // 检查是否已经存在相同的课程(前端传回的的和我已有的course)
83+ existingCourse , err := s .CourseRepo .IsCourseInExistingCourses (ctx , courseDB )
84+ if err != nil {
85+ return nil , errorx .WrapByCode (err , errno .ErrProposalCourseFindInCoursesFailed ,
86+ errorx .KV ("key" , consts .ReqCourse ),
87+ errorx .KV ("value" , req .Course .Name ),
88+ )
89+ }
90+
91+ if existingProposal == true {
92+ return nil , errorx .New (errno .ErrProposalCourseFoundInProposals ,
93+ errorx .KV ("key" , consts .ReqCourse ),
94+ errorx .KV ("value" , req .Course .Name ),
95+ )
96+ }
97+ if existingCourse == true {
98+ return nil , errorx .New (errno .ErrProposalCourseFoundInCourses ,
99+ errorx .KV ("key" , consts .ReqCourse ),
100+ errorx .KV ("value" , req .Course .Name ),
101+ )
102+ }
103+ campuses := []int32 {}
104+ for _ , campus := range req .Course .Campuses {
105+ campuses = append (campuses , mapping .Data .GetCampusIDByName (campus ))
106+ }
107+
108+ // 构造课程信息
109+ course := model.Course {
110+ Name : req .Course .Name ,
111+ Code : req .Course .Code ,
112+ TeacherIDs : make ([]string , 0 ),
113+ Department : mapping .Data .GetDepartmentIDByName (req .Course .Department ),
114+ Category : mapping .Data .GetCategoryIDByName (req .Course .Category ),
115+ Campuses : campuses ,
116+ CreatedAt : time .Now (),
117+ UpdatedAt : time .Now (),
118+ }
119+
120+ // 创建提案对象
121+ status := mapping .Data .GetProposalStatusIDByName (req .Status )
122+ proposal := & model.Proposal {
123+ ID : primitive .NewObjectID ().Hex (),
124+ UserID : userId ,
125+ Title : req .Title ,
126+ Content : req .Content ,
127+ Deleted : false ,
128+ Course : & course ,
129+ Status : status ,
130+ CreatedAt : time .Now (),
131+ UpdatedAt : time .Now (),
132+ }
133+
134+ // 保存提案到数据库
135+ if err = s .ProposalRepo .Insert (ctx , proposal ); err != nil {
136+ return nil , errorx .WrapByCode (err , errno .ErrProposalCreateFailed ,
137+ errorx .KV (consts .ReqTitle , req .Title ),
138+ errorx .KV (consts .CtxUserID , userId ))
139+ }
140+
141+ return & dto.CreateProposalResp {
142+ Resp : dto .Success (),
143+ ProposalID : proposal .ID ,
144+ }, nil
145+ }
146+
50147// ToggleProposal 切换投票状态
51148func (s * ProposalService ) ToggleProposal (ctx context.Context , req * dto.ToggleProposalReq ) (resp * dto.ToggleProposalResp , err error ) {
52149
0 commit comments