From 5b4075966760b0e211b76a214ba7c45a7db6c40d Mon Sep 17 00:00:00 2001 From: Horizon_srt Date: Mon, 21 Feb 2022 23:27:06 +0800 Subject: [PATCH 01/21] database --- database.db | Bin 0 -> 176128 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 database.db diff --git a/database.db b/database.db new file mode 100644 index 0000000000000000000000000000000000000000..6868c8cb6454625e7f187831469e5cfa3cab2b9c GIT binary patch literal 176128 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 literal 0 HcmV?d00001 From f112fb2df2453da1c23fc2c27480608dd95e9e65 Mon Sep 17 00:00:00 2001 From: Horizon_srt Date: Sat, 26 Feb 2022 20:59:57 +0800 Subject: [PATCH 02/21] database --- database.db | Bin 176128 -> 176128 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/database.db b/database.db index 6868c8cb6454625e7f187831469e5cfa3cab2b9c..8552fcb2cad085f3dc54a92ac95d09bac8a82c57 100644 GIT binary patch delta 1077 zcmb`Gu}>3G9LL|?mD)D6kA|TdG#-J(fpEO{?ykK%1`I_gkkUe-B*p;ewX`Sn4%!0) z3lIk<6HQ&5a4?QW?chQnaq%y37G}c0KuCy#5004DU^K?zEtl{6e!suZ{odw&U~@n4 zyp7p=aWl^BeVBXGb3M?!1K>OO07gQeL$je^@Jnzx7;4_Bh0*I~HXW$G?^8CSJVBZ) zYA7mT5y>$ubsRPyE3e3>^E?MgnU@kPg3()djM$C7SZLdDU`&OM`O z3-c?Mfwh=K5Fy=&bQ77!qJ||+R0R}^N{UL{h)JIpY%rsDQl5nA@P<=f?27Yxfx7XI z&ClCqBhN3dn2z8EoJVS+e6_8l66Lb_z%|;ui@Mg8G_68|%g=IcjqU1e(%uU`v^>#d ztYIREBEkrZmwcN38z0OQQ6mbSO(0lR)L7Jw$aq{n$$#V1V5=z6%i?kF0#EX<@Q@q7 zaY?h3PH**9--3?~?E*Lx+NEptF|@IDiw%HCq+_col>&OsELnQ4WLlVrcj*xfyVOba zPK-LO>0vd!I%1?p3q8a4mj`?La|?s{HG=v}g^_hVGm)9jW+x0IJ7rHAjuk7}gflrd pV2ra@jY#NX$}!c2@QZ-HJS5Q7RTU9GIop1Ew#|Gx+h)BjKLEO>i5#?*}oOY}LI_+uFO*YU?}77PgBX9{4Nyusdj@=W_|Hb(w9 z2L3ppa0vh8IR9lp{znG>kDCP-Jm;VMFMg%82eUY*p^>qPDMaEA1OK1xf(=Zc`1zQb88~^ts;4sWPX$`k&99ls z$j;!)>F>``RazculH%kMS?X@=SdkuLkyhZ8=USYe78Yur;*nuA`M$rXx~Y+orMZ!| yfrXWUfsuick* Date: Sat, 27 Aug 2022 11:19:16 +0800 Subject: [PATCH 03/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution.go | 18 ++++++++++++++++ app/request/solution.go | 14 ++++++++++++ app/response/resource/solution.go | 15 +++++++++++++ app/response/solution.go | 34 ++++++++++++++++++++++++++++++ app/routes.go | 6 ++++++ database.db | Bin 176128 -> 180224 bytes database/models/solution.go | 17 +++++++++++++++ 7 files changed, 104 insertions(+) create mode 100644 app/controller/solution.go create mode 100644 app/request/solution.go create mode 100644 app/response/resource/solution.go create mode 100644 app/response/solution.go create mode 100644 database/models/solution.go diff --git a/app/controller/solution.go b/app/controller/solution.go new file mode 100644 index 00000000..c50a2f26 --- /dev/null +++ b/app/controller/solution.go @@ -0,0 +1,18 @@ +package controller + +import ( + "github.com/labstack/echo/v4" +) + +// TODO +func GetSolution() { +} + +// TODO +func GetSolutions() { +} + +// TODO +func CreateSolution(c echo.Context) { + +} diff --git a/app/request/solution.go b/app/request/solution.go new file mode 100644 index 00000000..3543124b --- /dev/null +++ b/app/request/solution.go @@ -0,0 +1,14 @@ +package request + +type CreateSolutionRequest struct { + Name string `json:"name" form:"name" query:"name" validate:"required,max=255"` + Description string `json:"description" form:"description" query:"description" validate:"required"` + // attachment_file(optional) + Public *bool `json:"public" form:"public" query:"public" validate:"required"` +} + +type GetSolutionRequest struct { +} + +type GetSolutionsRequest struct { +} diff --git a/app/response/resource/solution.go b/app/response/resource/solution.go new file mode 100644 index 00000000..f1783edc --- /dev/null +++ b/app/response/resource/solution.go @@ -0,0 +1,15 @@ +package resource + +import "github.com/EduOJ/backend/database/models" + +type Solution struct { + ID uint `json:"id"` + Name string `sql:"index" json:"name"` + Description string `json:"description"` +} + +func GetSolution(problem *models.Problem) *Problem { + p := Problem{} + p.convert(problem) + return &p +} diff --git a/app/response/solution.go b/app/response/solution.go new file mode 100644 index 00000000..f2a46aa4 --- /dev/null +++ b/app/response/solution.go @@ -0,0 +1,34 @@ +package response + +import ( + "github.com/EduOJ/backend/app/response/resource" +) + +type GetSolutionResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.Problem `json:"problem"` + } `json:"data"` +} + +type GetSolutionsResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + Problems []resource.ProblemSummary `json:"problems"` + Total int `json:"total"` + Count int `json:"count"` + Offset int `json:"offset"` + Prev *string `json:"prev"` + Next *string `json:"next"` + } `json:"data"` +} + +type CreateSolutionResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.ProblemForAdmin `json:"problem"` + } `json:"data"` +} diff --git a/app/routes.go b/app/routes.go index 65d6ecd5..a02e869e 100644 --- a/app/routes.go +++ b/app/routes.go @@ -167,6 +167,12 @@ func Register(e *echo.Echo) { submission.GET("/submission/:submission_id/run/:id/compiler_output", controller.GetRunCompilerOutput, middleware.Logged).Name = "submission.getRunCompilerOutput" submission.GET("/submission/:submission_id/run/:id/comparer_output", controller.GetRunComparerOutput, middleware.Logged).Name = "submission.getRunComparerOutput" + // solution APIs + // api.POST("/admin/solution", controller.CreateSolution, + // middleware.Logged, middleware.EmailVerified, + // middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution"}), + // ).Name = "solution.createSolution" + // log API api.GET("/admin/logs", controller.AdminGetLogs, middleware.Logged, middleware.EmailVerified, diff --git a/database.db b/database.db index 8552fcb2cad085f3dc54a92ac95d09bac8a82c57..05c2c143c5b28b55c7286919d6b71719134cf3c5 100644 GIT binary patch delta 3987 zcmcInZA=^I9lz(!FWB7O19|fZNic6s0Ox$~FKz>*g?1}VfIyNaQf43a0WLNMY%;=< z0zu6_Y^tbEDT~^UYM-_bo0@tWo772_wnb_-EnlWd(XuJgv}#(EtxXgq+cIg-ozKJ= z*oSJfxWniBJgttOG4gzn*cDlb$9VI`% zI=hX;;}zz8vJv>qSjApbpc;YKJV`Zx3iI#2UFH(iSnu%!+5%uMIi4_Pl8Kq;4 zMvb(dOxa((_Q=nvJ@}B@e3NVj9((9@@|iqEKLSKOdCv4!J?H%s`7`ngc`n~y6((K# z>hW&#YG@DM5H#=YX*kwYhxhA=L}A+KSz{_WoQ&(aWM({?%ZwT5t`DV*)_wSya+HyX z#xtquv;}my+1NbX`w;J}Cr@G2Ect+X2l}We{d?*Vxk6r}+v#1@P5P_U19}m@LAB72 z;dAsa>38U>3Z3X_w6%3=s4J>ay-lP2U+zXuLLV3N{p3NmZ?S(lh!fK4Hs)AHpTCXwn_Kw!447ngDMk6YhG^;H9cjz9?q+Z>QD`oQQZpIx2v40jTFTQD=@6ANUH2G(08t<%Bn$L zh_GUWlNni*RZVl&9^A1R)%9=zY2&EhwS7I+^*~;cS%*O1wlb;~l8uO5gl8F9Mq2S) z!Fs*Aj4BEf4LLo+Ner)8>N}1atlE@nDO~0?fpg~Vf@M^<0`}46R1s2$AiV^Q5d>A@ zibmR>kGkSU=WiatfIuabu1hdoe z(cow%oAZw(bEDHk){Ag=V!HR`@Q@xy9U&1m&Kl#n@RTvqk<8|dDP{ouc%r0pbXzTo z8J-@Ga}i;kG1J^>6zKVqls6uuf51kjtEnyU)77{)M19Wvy7m~ zqNoT?Fqa@uXi6$FkU?q8ua!~1&HV`mpR88TgG0;pAqj3@}4APf0_uK24+ z7aYOh+wdFkYj6ZDeiF{nE)w%00jv)II6)KZo^c8fWmyXUnz?66^;Gkj&0rA zvzCG`cn^b*;C*-xK0$u?18j5=7;srP!n)xELD{Zy!CM&o6m3mzSq|&_H5AK$Tl&uh zKgHl@@GcsSycqi(Y%LpE=F|=N-CN^-1YDhdg1&^oi_k@1%2#*J&~xVrh;0v0z6uxK zNO34Vc%Dc7jPh3@gNeUKZYKTuvG+aQbF`-Wx(QIZo7ftKA_-N6=DB4S6nU@98 zX>*$c6oD(2_VaW2|7>{)wNFNq6;>0S9#^(}0ibXKr#Z#>JeVt6o5RrH}rp|IsSD1SB_TT^+s*VlMx{}YeLZ-?XP*ReMs{JW#T#f|FsyqsSfq0L!YTB)!^=`|U{z zhJ<4FiKqC0&R8X`Sa6?kp&It9<@@h~yG*R5<-&e%K&t@@l6^k24X{r^(TS-HvMU|U z8o7d5t>~P#^DCPpV!_^{!B_zoI}o$Zbn z{T{fu+P(s=-S!i341+h|dvFZZr!#PlCEOUO>m{bq;c+-QZY0(RZ?R7)s=ztX&Eob5 ze5(<~Y*TreFKk)Dz>WFpdN&)e%i5+n86>J=v5)_F33pX_09?V~3gUSgo{j<^<_iZZ jjvT=@^uK}00i~yex3xDYbYQeGDDJ1Xe4qcvinr=N%s%~9 delta 1619 zcmbW1T})eL7{||ZPRmC*r*A=L`CN-YHY~L7Ij5)XX&^8@Hef){fOcasLTQolQ9g?k zOdLo|ype#%r4ZuWmC@*oqnY)Bz@isRT(V>r-uMyWnk-Stf=g!fZHrKhi-{Lca^Ca& z-{<_^=YO7eZZ2zXTep;-Lv2wMWg+nr2_V5QR|qtT}v+N$XhBCPx{SREVnr|*RaSQp; zDk?=gXdQjaKHzS1&!c@(Wq?(?E6iY0XDdphzg6TgxjJ@(LZ73Tkx~D(zDLh-_qYj8 z&u$R$O_o-4>K8SY1x}}c1)&lPm4d@8V7DZ?vBS!XSaPa&s+tS!hiS>oi*DZT7G*1T zI_xf4Q1h$Z1=7C@?6Tle$Eq!*&nOVj+b!7T##l*Q< zYt^l)nv{~fSrFZV%PmS)ftOvf(~%T*YScxCP=3UAOz3hs4hq&YX%tvak*-%4mK>2j zL#@zp(4rL3gphZ*C8w3gP8SwM_2U}Jc3hD-3YM&P!6`~EAxX%QUyIgnQs@=^CNX4P ze{H^q)=@@d$-LI%q5Q$Y(5OEc8XV;Xv6h52FcvBm{G~iD9lh8rE3dT#l=B0&=F1aj zZFRxnv;8vyt_uyc%=$Y!IxqTs9f5$)JJuDraCLB|&o?x9+$D_THu5gPF4&z(plkoB zm^T3dEJy+pB)il!HaR#umOz}E45uIlT5X=0*&&;J$rG4qZmys9hP{*1{ZmTYRVf&3 zZ<=W6@=beR@9w@d<_flScZ;?rW&DUS(N@g6MQnB0Wf9AAlJOAnSpr?Wt7wNJ)A4IG zTlo%I5K{svEu{5KNoIU~z?(LRNq#s^Z_MbBv%3TTF*GUIMj28u%Olf=8IZ=?-8o{Vs4I6Qu? zKH#kLww()4H#j<*X0EhfnesJ-yV@H97wE(DCT1^bnn0#Oa{jX+NdXy7Y$fv|yTsTN z52Twv!eID2zQmw4+|k0HH8G6>f7oI$4jMx??WNEN`bPgFxgZi3TZJupNb zT!%{a6ZkB8o(@3ls|9GyP&Mp3|Ns8e%(rUNW7&(a2aprdE;#5=dGo zkG*;wdNq;nSHYkgnhp;1Pxg%ZL$U2u(1M28`+L+w8=-D~_;k9ltPB?N!v4OI{((t< zuz#wjC)^(zPkpx3cQl^qYBYD9scUUC_ok*Ib1Ptp++Bg}$mI{9IkLG1r-+BN$C#G~ z3vy)e1}KrO6~al<3(P!}M>cN2TXgs72)hQkWN+CT+>KR#2=}(5nwwA2vXT|cTB4tz G#Og1b)}mVg diff --git a/database/models/solution.go b/database/models/solution.go new file mode 100644 index 00000000..d7335001 --- /dev/null +++ b/database/models/solution.go @@ -0,0 +1,17 @@ +package models + +import ( + "time" + + "gorm.io/gorm" +) + +type Solution struct { + ID uint `gorm:"primaryKey" json:"id"` + Name string `sql:"index" json:"name" gorm:"size:255;default:'';not null"` + Description string `json:"description"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} From 1b62b9c4f19c63d737db394dbc168f16e5d6cd06 Mon Sep 17 00:00:00 2001 From: Invariant64 <1319438556@qq.com> Date: Mon, 5 Sep 2022 18:42:11 +0800 Subject: [PATCH 04/21] backend file --- .minio.sys/buckets/.bloomcycle.bin | Bin 0 -> 8 bytes .../buckets/.usage-cache.bin/fs.json | 1 + .../buckets/app/.usage-cache.bin/fs.json | 1 + .../buckets/base/.usage-cache.bin/fs.json | 1 + .../buckets/database/.usage-cache.bin/fs.json | 1 + .../buckets/docs/.usage-cache.bin/fs.json | 1 + .../buckets/event/.usage-cache.bin/fs.json | 1 + .../buckets/images/.usage-cache.bin/fs.json | 1 + .../buckets/problems/.usage-cache.bin/fs.json | 1 + .../buckets/scripts/.usage-cache.bin/fs.json | 1 + .../submissions/.usage-cache.bin/fs.json | 1 + .../buckets/template/.usage-cache.bin/fs.json | 1 + .minio.sys/buckets/.tracker.bin | Bin 0 -> 2037433 bytes .minio.sys/buckets/.usage-cache.bin | Bin 0 -> 865 bytes .minio.sys/buckets/.usage.json | 1 + .minio.sys/buckets/app/.usage-cache.bin | Bin 0 -> 294 bytes .minio.sys/buckets/base/.usage-cache.bin | Bin 0 -> 337 bytes .minio.sys/buckets/database/.usage-cache.bin | Bin 0 -> 185 bytes .minio.sys/buckets/docs/.usage-cache.bin | Bin 0 -> 138 bytes .minio.sys/buckets/event/.usage-cache.bin | Bin 0 -> 266 bytes .minio.sys/buckets/images/.metadata.bin | Bin 0 -> 299 bytes .minio.sys/buckets/images/.usage-cache.bin | Bin 0 -> 131 bytes .minio.sys/buckets/problems/.metadata.bin | Bin 0 -> 301 bytes .minio.sys/buckets/problems/.usage-cache.bin | Bin 0 -> 135 bytes .minio.sys/buckets/scripts/.metadata.bin | Bin 0 -> 300 bytes .minio.sys/buckets/scripts/.usage-cache.bin | Bin 0 -> 133 bytes .minio.sys/buckets/submissions/.metadata.bin | Bin 0 -> 304 bytes .../buckets/submissions/.usage-cache.bin | Bin 0 -> 141 bytes .minio.sys/buckets/template/.usage-cache.bin | Bin 0 -> 144 bytes .minio.sys/config/config.json | 1 + .minio.sys/config/iam/format.json | 1 + .minio.sys/format.json | 1 + app/controller/solution.go | 170 +++++++++++++++++- 33 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 .minio.sys/buckets/.bloomcycle.bin create mode 100644 .minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/app/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/base/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/database/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/docs/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/event/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/images/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/problems/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/scripts/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/submissions/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.minio.sys/buckets/template/.usage-cache.bin/fs.json create mode 100644 .minio.sys/buckets/.tracker.bin create mode 100644 .minio.sys/buckets/.usage-cache.bin create mode 100644 .minio.sys/buckets/.usage.json create mode 100644 .minio.sys/buckets/app/.usage-cache.bin create mode 100644 .minio.sys/buckets/base/.usage-cache.bin create mode 100644 .minio.sys/buckets/database/.usage-cache.bin create mode 100644 .minio.sys/buckets/docs/.usage-cache.bin create mode 100644 .minio.sys/buckets/event/.usage-cache.bin create mode 100644 .minio.sys/buckets/images/.metadata.bin create mode 100644 .minio.sys/buckets/images/.usage-cache.bin create mode 100644 .minio.sys/buckets/problems/.metadata.bin create mode 100644 .minio.sys/buckets/problems/.usage-cache.bin create mode 100644 .minio.sys/buckets/scripts/.metadata.bin create mode 100644 .minio.sys/buckets/scripts/.usage-cache.bin create mode 100644 .minio.sys/buckets/submissions/.metadata.bin create mode 100644 .minio.sys/buckets/submissions/.usage-cache.bin create mode 100644 .minio.sys/buckets/template/.usage-cache.bin create mode 100644 .minio.sys/config/config.json create mode 100644 .minio.sys/config/iam/format.json create mode 100644 .minio.sys/format.json diff --git a/.minio.sys/buckets/.bloomcycle.bin b/.minio.sys/buckets/.bloomcycle.bin new file mode 100644 index 0000000000000000000000000000000000000000..0117a8bc8a7d8febc8c7f9f6ee857af9eb1b59ba GIT binary patch literal 8 LcmaFJ!T<&U2P^>Q literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin/fs.json new file mode 100644 index 00000000..82931635 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"24875af2ad02c0be3096aa4475889d38"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/app/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/app/.usage-cache.bin/fs.json new file mode 100644 index 00000000..251bf2b6 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/app/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"a43ee200a9b5b13ca89d536328b55eb0"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/base/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/base/.usage-cache.bin/fs.json new file mode 100644 index 00000000..25390b8a --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/base/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"b0f726419ecd7eeb85e584ba57d77b7f"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/database/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/database/.usage-cache.bin/fs.json new file mode 100644 index 00000000..5fdcf7e6 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/database/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"e7546e8e99df0980c20811145ef54c51"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/docs/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/docs/.usage-cache.bin/fs.json new file mode 100644 index 00000000..51ce1fd9 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/docs/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"5111bcbd33222bfbdd82354c36cc0337"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/event/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/event/.usage-cache.bin/fs.json new file mode 100644 index 00000000..e63977e1 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/event/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"4c19a1f21a85db0bc7b89e0fcfe39191"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/images/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/images/.usage-cache.bin/fs.json new file mode 100644 index 00000000..e2bf8f31 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/images/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"eddb3a38ec980fb5bf0afedd7bd482c5"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/problems/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/problems/.usage-cache.bin/fs.json new file mode 100644 index 00000000..951c3dfa --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/problems/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"38c1017dea279b7022faa23459828676"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/scripts/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/scripts/.usage-cache.bin/fs.json new file mode 100644 index 00000000..3bd7da09 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/scripts/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"53e9679469590a412cf8ef076841e1dc"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/submissions/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/submissions/.usage-cache.bin/fs.json new file mode 100644 index 00000000..29afe112 --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/submissions/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"d74225a715028548a67b160bbcc00244"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.minio.sys/buckets/template/.usage-cache.bin/fs.json b/.minio.sys/buckets/.minio.sys/buckets/template/.usage-cache.bin/fs.json new file mode 100644 index 00000000..84cb5aea --- /dev/null +++ b/.minio.sys/buckets/.minio.sys/buckets/template/.usage-cache.bin/fs.json @@ -0,0 +1 @@ +{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"etag":"c52a3c6609fb5daa573eb326389aaae1"}} \ No newline at end of file diff --git a/.minio.sys/buckets/.tracker.bin b/.minio.sys/buckets/.tracker.bin new file mode 100644 index 0000000000000000000000000000000000000000..5b592afb4f9967ed9f149caa1521833a4e7226cd GIT binary patch literal 2037433 zcmeI*O>*SCvKUaw;Rttl(9uH=Iqp?pFWv~2(o6FHzx})vyH#~Vs#l^Yk^q%6g%XJX0RjXF5I86BFV5|5Zvy27(p$)-eBenU zrb+5lCIJEj2oNAZfB*pk1PBlyK!89rfhAf(&-s`f{%qnE0`CIp{XhK|0RjXF5FkK+ z009C7>IgVBuj48z0RjXF5FkKcQh_MXLcC7uuWSMY2oR_#@T+EUu?Y|$K%lCC&+w|e zf)gMRQoyy5kZqCFE&)gJE-o7rAV7cs0RjXF5FkJxyugp}8A^}<0RjY?2&5*X7=!=; z0wW5f=c1y_+kVb$^A#run?yDsK!5-N0t5&UAV7cs0RjZh3%CSv-cSSr1ZERRvlXmf z0tAi-pT0%YiGX$`K!5-N0t7}E z`1H?*f<>o-v4kQ(;IP1QcuzYLAV7csf!zXT4(ukg1A)81Rd?ewfB=D61!`Xvn$=a^ z1PBlyK;ROAjeo_;@BK@ali)0Br z3Z%zHO9TiIAkbJKHy+P$Hv!W{9SH=!E#S7nx2bGMfB*pk1PGiF@KDMbJ^MxwSRy1L z2Lc587H|gMcmHJHr-1iepM6`+IPZp5FkKcO~BNaH5soHAV7cs z0Rk5Z`19l<_>P8McILYCSv`l~PG6f7AV7dXYyo#WV)sXO1gZ#l<5yt~71UWvsCJY{ zMoUX5iqVC@&Wki%)Fep)1PBmlDX_F0%vb~n5U3-N>x30`Mga%Yj9phV0Rqiv0t7+`eJ6ZzwcGuUVUHgyI9#1AV7cs0RjXF5FkK+ z009C72oNAZprSyo7+Yup1PBlyK!5-N0t5&UAP`mH1;DfZ;z05ST>3 zwUJ30J#?9l;-TBCI06I+5FkK+009C7CKUKFVa-Y=K!5;&PXy8@uX%|80RjZRBaogq ziZXBeIkU}IoFHrx*?<560t5&UAV7cs0RjXF5I8U362y5!5eN{NO(4xyuzCp)I3kdb z>|`Hb_~{rRK!89z0pCIK@=|2xNs8B784W4mEjwge6-9smfp7x8=47=cX?2YiUkcdYl*;Lfyjrw4iO+gfB*pk z1jZLIyLJ2?tB?Qz0t5&UAV6S1fjnSMN+Ljj009D*2!#DY+NM}J(%!g+(N!&yCGaSa9v3YU zAV7dXV}aawJj2}tOc!+|5csx$+XmmJvLOKi1PBlya7MsGDQEQT8$n=+kc1ov5a?UL z8F=6QlYO58-gkZWZ8ht>y2c6u1jZ709jhGG5FkK+0D(0DQ(M+#yiR}s0RjXFTqNMn zlZ)Ux8g|*4>&|EO9D+N2ZBBpy0RpiF-0g_nAK4M8BH)c*g*8-AXDy-HQ6d>FEuknz z7Xmvk(sWUiBnc28K%k|-(sD3k5gy^zUWAie!u?n{2`6-aw`uss0+1PBlyK!5-N0t5&U zAV7csfg%D+ktkJzm>gb}SMcryQuh@ofB*pk1PBlyK!5;&@B&WF!?#F+1PBlyK!5;& zo&=&i3-Q_$np_DGAV8oKfnS~EDNOpT0%YiGX$`K!5-N0t7}E`1H?*f<>o-v4kQ(;IP1QcuzYL zAV7csf!zXT4(ukg1A)81Rd?ewfB=D61!`Xvn$=a^1PBlyK;ROAjeo_;@BK@ali)0Br3Z%zHO9TiIAkbJKHy+P$Hv!W{ z9SH=!E#S7nx2bGMfB*pk1PGiF@KDMbJ^MxwSRy1L2Lc587H|gMcmHJHr-1iepM6`+ zIPZp5FkKcO~BNaH5soHAV7cs0Rk5Z`19l<_>P8McILYCSv`l~ zPG6f7AV7dXYyo#WV)sXO1gZ#l<5yt~71UWvsCJY{MoUX5iqVC@&Wki%)Fep)1PBml zDX_F0%vb~n5U3-N>x30`Mga%Yj9phV0Rqiv0t7+` z~UDYC40*?aeanTY10t5&&7RZgqGu%zUbWukFfo}`AZSZX>8xkNu zfB*pkX9PTyaz@X-5d@Y9Nyvc!fxZQtf%n}%+4m{neb;B-RxvC2^m z0RjXF5Lgp1wPj7l>jVf8AV7e?MFRdjxd^_aVV9k`?tE6yA-L1m<^%{3AP`%?-HzD( zksX050^aylSVIMM))J~6C6dw75{hDUA+YlzO&2vuk^lh$1X>C#EeA6e0RjZ-2;@3p zMV(Q=!8Bvn)l7iEwF1ST5_Uu9+J+jPKpg>>!Rxq+N`L@?5CSlHMdvam-{YK z_5=tJAV7cs0RjXF5FkK+009C72oR_!kSoR(ng9U;1PBlyK!5-N0t5&|75F&qC~A)K zB0zvZM1d4BsiATrJXAXsLx2E*sRi=X)z4mhnjJv>1PBlyKp>8QZ;Xo53z^&n(%aAF zzU0SVfwXrA+Y=x_fB*pk1PBlyK!5-N0t5&UC?c>FiBdI)$>CLb1@B%Ubzgx32oNAZ zfB*pk1PBlaFW}TXe2XMVfB*pk1PBo5Ng&Fz5U)L<$&~;B0t7k{_|-|C(j-8D0D)%# zpW)9YULinWbOF~!M(^+p^*M@X=&~9K5FkK+009C72oRV_;KxkGs+9l%0tD6t()ucE z2oNAZ;7ft@yf(_b?dQxkUvYx4Nn`^81PBlyK!5-N0t5&UAVA=}fJ+eP4MiY8U^am? zTfyojK;Vc#KC+X2eBq~KfB*pk@dSJa#mh^PnI|b;Z)G&3fVb?BZB-Nj0tCVd_?nZ| zmZa4+R(vUtzg%l2fkFbgP#j?hyb0tu4q<*Vhe@PbZ009C72oM-w!0guXd#pkN1PBlyK!5;&0R{4aH7SVz0RjXFTp|$m3vu%$90nyo zfIt@lrZ9EUCP@+?K!5;&g92C0VOS34JJ4?72*RGR57cy}5I7<5>030N2xwOV1PBly zKwxx%Pyc)jXZUG;?bN65M1PBlyK!8A}0;$uyyGncG8b(*O zNS45(KzdxXM1TMR0*wW7v)|HOt&U1PI&&%*}Nq z5FkK+009C78VW28$1)TF0tEUN_@5uII{p0f`(DlM)%WGTilWFKGn z=@=kDfIvI}-$C*6Qe@^yiq~5i4JqI)J7ilGMSuW-a00&OWVIz}b&VBY3gj=>T1lXg zKrR$V7y@qsIgUe^U(8_=sn(mNcw}es#YqJuK!5-N0t9Lam}y)~R$KxE2oNAZfIusO zrPV;jAwYn@mO$FtzqB0zuu0Roo@g#AL?de$O(z1{l>h+(1PBlqUEtF{9|{(o3dRzO z0D;2-%i%rkNPqwV0t9vom^rYU%nk(Z0$1IQ(*OblW)-M?RcKaMbrT>!fB=C@1UCK^ zE5G+I>54%K5SUxQNAKMIS3Lm&1PBly(5XP`H1Dp`-nfR*RV|Vw@F`A{i|$p(sWd0y{6# zbWxKe2@oJaprydlaxh~NAV8pwK&}&3)ENaFOfz;}%>)QsD^UC?VK;QHZK%-+)DdtQ zypF4=1PBlaA&^64AqfHm2oNAZpqW7Ni$TpYHxK~=Hvw~V9SH;o5FkK+0D*=AOT)1Y zMSuW-z6Jir$E!|1|NOpJb9?oDx$h!nPk;ac0t5&UAV7cs0RjXF5FkK+0D+1ExngXg z2@oJafB*pk1PBlyK!8A0fsfOUqUIGkjY&jz5QJ7OMdJXNPBm%Jplp)2oNAZfB*pk1PBlyK!5;& zA_7a1C{=@)9A1@I@a_dt_Z29B009C72oNAZfB=E;0#41tw@88n2oNAZfB=D>1fo0( z@!AubTnP{$K%f(WU!CMBO#%c65O@~w8UAeI6#@iC7jSK4^bXHZpQCt&E~}9M0RjXF z5FkK+0D+kVe#}&?S_u#!Kww=Ut*^3%009C7z7$B$YopBDe$H(36(oeuQ^$5Nm^ZF#g_v4%e7V#C?t>z#SwN009C72oNC9N?>U?X4VfxEy}cjGjG0D)NrYF`za)m7aD2oNAZ;1Yq2f5po0{Y$!HPyz(z7VyzK zcmGvSfB*pk1PF90kUGt~tF$++VRTiCWC=V9q{l@|1PBly&{!Zh9?x($0nDk=d21VRYp5Lrlq z009C72oPu{Q2b(0v&;=dfWS?_++0Tj0RjXF5FkLHp}^8`EJG0>K%j4d|Nil+)6YM@ z@73I1eP8aoNZAu0K!5-N0t5&UAV7cs0RjXF5FkLHqCl<~TWA6V2oNAZfB*pk1PBly z5LMvgw4%ASQ=b4-n|Or)fzbtA8yUUBGt}oOo}tTXBtU=w0RjXF5FkKcCV?L_6{}VP z1PBmV7f9=?tRX;v0D&(B((~FV^R}Ne+kC|d!X}Xo2oNAZfB*pk1PBlyK!5;&^8zkG zoHrDK0D;*A(rg8*mjHny0{O^J_VI z1PBlaC*W&NR$G!**I4nTK>l*Al>`b2ca@eAw#{0RjXF5FkKcd;zmt$M3NU2@oJafB*pk1O^ny1J_FfyaMj&7 z4In^ZR)N}Ag=TeCHvs|!2oShLVB=r0@_YZ1t{9X6fw={I^v>OX)e|5@NFs^5+Fc;009DL z1U!^-M$f(x1eOR%$bkTXz6G3t_uW6)_bK3g*Js~Wv(Bq)tRO&OEP>at%25pg0t5&U zSQ9X{WlhHG1PBlyK!CtS0{%R?2)?6Xmz}xpd{)mPxYO6>1PBly5L>|Aj@bQ?9f2wW z-uP8mLj`r#5~>{~lF`xz&ac0=ddh8mqf9RZiY>$r+afB=CI0y#t$k|02U009C7nh6xY7}P9t z0}&u_6EHW|kwAa|0RjXF5NIf{G#txN1PBo5Tj0Nayz2Dx&+mIRw^!en`z})U1PBly zK!5-N0t5&UAV7cs0RjXF5U41SE5;U@009C72oNAZfB*pk1PDYG_&Dt-YL4iTTR67+zfB=E11@hF@&t80*9YFmA2oNAZAdY}ncM}^+t1~`PizG;Z009C72oUH=Aj-24uRWp3l>h+(1UeD;)k&VxBtU=wfoB1q;m;;s zAwXbs0oO)G@9+%uIf`fKvKk2xAV7cs0RjXF5SU5e$4tell>h+(1l9%8`YLM(5FkL{ zOM&#fHp;y1=gc-=ae}Z(WCH>O2oNAZfB*pk1PBlyK;XQ9OAzM`MIb<6Hi0x-!RjSI z;D|szvXgy$;iqGO009E=1bhd@%S(}&Cn;WUWi+IKx9pH@RTKdN1i}gUnv>O*q}4T6 zd?}E>Tx%tPLISx^9AOB&3FJ5qVSX`(Nu*kDmg13}#TO?PkN^P!1PBnQC19p;Em?61 z5FkK+009E61eR6<8HWG?0$T!UYXj>E5FkK+0D(t=$T#DQJZbS*t|bD01tK5zIz)f~ z0RjXF5Ex&;?AGyntU>|=2oNAZfB=C31@eG3DTx390t5(LA`tcqaq}e{1|>j%KorXjcLR2oNAZV03{` z|9mJ|bSfB2C;|iy3oM8Cv?Bom1PBn=Enw!rZZbO%xC>l$H%N_*oPMpv~+mcXMx zdR(+bfB*pkjRkV!@eFqpFkRGKZEu5Ex6~b*yq!Lx2DQ0tD6sOl?_{@j3wl1PBly zaFKvNPcDM*XxL?Et~;OAa|rJAwK)L-1PH_yaJM6Ne`H6XihwtM71mHeowbB&M~P&# zw1lDuBG86#<1o{^EuOF{E{rvO$Ud`>*_vOBelsy3g1PBlyK!5-N0t5&UAV7cs z0RjXn3gn8hg(g6N009C72oNAZfB*pkQ3XCuJBpg4ya*5=5K$mSOlqi{2oKdx#SkDs zU}}Lpb@j6spJoS8KLG*+2oQ)P;2Wdj^g58EW~S1XmTY$fB=C`1b%grr!)x=AVA<*z-RcgiB|{^7+t`%k@S0t5&UAV7cs0RjYO68JGwv1%nifB=DYfwaEL8Uh3e5cpCcJ+F;2Z~Hm3%~zZt zY!cak009C72oNAZfB*pk1PBl~FW?fyc|#Eh5SUFM%~r5_2@p6UkdN$SA7A+C7$87^ zKs*88LGkiZWadeV*IOA4Dc~(TWLp(QfB=DT0>0*CwIykFjTK)C;pAjDFjXkeEJqmCj#1)009C72oM-u;L|@J3KpFT#uADEfx`mJ z;XUn0fB*pk1a=FUIk20|4g~H3SKW=%00IPN6{vkxXjWHs6Cgl<0D(&cHvSbWzxOZc zia`kwm|MU{@7(=YJplp)2oNC9sX*#9@2=9`xQ5YHEs`bhD3Bf(EfF9%6+g3IYVi5_lb}9MupYK!5;&H33sw)?~a+fB*pk1PELt;Lnqb;5!<2*_rFk zXZ0L{JAG|VfB*pku?5`ih}|FA5vU^IjbDW|R8VIvq1sU*87(cLC`K0oJ1^37QIjMI z5FkLHrNGj1Fk=xQK%kC5t`k<&83i0nGj?6g1PEL!Q2Z%jH*~ITsL=`35pWs2j;p8y z2oMM%kV9l42?7KN5FkLHnLzQ2LCrEZ5CH-=0dsR52?PibAV7csfrbK0!?6rSfB=EM z1^&y&t4=@v{JvLnd-Z*}?;>SSfB*pk1PBlyK!5-N0t5&UAV7csfr#o#ZJ^0t5&Ucoy&({%qnE0t7}EaBXDt4$n}Zqj-ictC0W!0t5&UAV7cs zftdt;%v7ve2@oJaU|k@sud;>!0RjZR6iCl&qs-fW&TR7)CkUHFHXuNN009C72oNAZ zfB*pk1kMY%1aaO_1OfzR6G*catX={HjtJx zDIVEbd~s3%2@oJafB=D70%jW5k`U}-gwaR?9~uqBYTHn5%m0RjXF z5O@@bd^5htlNOKVS|adQAo5|aLj(vAAV7csf$;^*ZXLhJDkMOF009C72oM-hAP-oR zk_ZqWK!Cs{0%5-pH($bGPyz%9bRl30Qx|QLBmn{h2oN|ZaMc`!>2w& zO;-wm69S*UMbn9Zb|pZ7009C7Mi=<>&xe9Vr-HGBB0%7#mevfOS)oE0tDt3@XG+oprNdg225NIi|v>eP>1PBnQ zBarKa6?H}d2h)sQS2FLcI2bCRYLk2oUH*;8!PkN|OKq z0tB7~e1<=pc!dCg(FI%^8NI_Z)aNLkq04F{K!5-N0t5&UAV6Ryfgdv!t5yO82oP8o zNb9StAwYltfiDHp^V%r$wx2WGe8maECXo#Y5FkK+009C72oNAZfB=E>0xm(EHxz*Y zf!PGoYz3>A0D&U{`N&T8@r9p`0RjXF#1rrx6fZADW}c*Yy_M0B0^YJiwpCFC2oMM- z;A>7+Tas4SSn;Jm{&KCA1PTe{LUDv4@FtMsIE4Ad943)!y;+J!b{1cpR6qg*2oNAZ zpq7A{#3Zzc+?keq# zYZzVCB3S~D0_kzl5&;4P2s9SRjmI3A zFgMqcK!5-N0t5&UXeh8W9LrDy2oUI7;6Hu5>h$x^?|U`3SKpWWE>iXc2oNAZfB*pk z1PBlyK!5-N0t5&Us3?#t#ul0Y0RjXF5FkK+009C72t*b5IPEBEj`AWvfIvin6fvox zaw0rbI~7BK0D-9m^3>JOUVNGzK>Y*=5FkJxj(~5Biqi|3+y&Cx&*i@4$6kT7cL&=O zAV7cs0RjXF5FkK+009C72oNYDuoQ_>HHgXKRe1&PULbW}fdU8+AV7cs0RjXF5C|{e z)I5BPBuIb&0RjXF5a>xD%Ciu!J)y~!009C7IuZEQNuJUqK!5;&X91t#&n8|WKwxwM z*G5L~@C@}iif8Du8VL{}K!5-N0t5&Um`UKrOvS2|009C7)&Loznh(JEF zlYM;Qr(=Ks0Rr&^dRp0N+qbfpkDA@J#2G@S@&R{{hG5FkKcbb(L*d?;9S zDi}*B0t5~VEQj~BBLM;g2oTsUVCKMXGCL5s3tV+KP6G%Km{p+mRiRm3)lGl^0RjXr z5!m=wto+`;q$>s`KwxeGAH8$;U-bkC5FkK+K&Jw!)4aP%d*d2LSG7o%z@tEVT(m@h z009Dx1#;u@40jVSUDT04;M)Rj8+@C}h6D%@AV7e?837NaoYAvy1c4<&5^^9wpl<787)#)Fta4OCfB*pk1l9yhZCR7?IspO%2oNA}k$^u> zE`sl9*kxy~JD=5a2=4T?IROF$2*eg}w)=)v6wS;O%iDb02grXQ- z2<*H_(?v~^BtU=wftCVG%fXCAfB=Cy0=Z6DQD+ozFwNL?H4`9ktw8aogx%1&wxLER zP)ERJ@H(!d5+Fbzgg_3Fg(L_NAV7csfo1~5F9tQs+&}~f+yu&F$6q<-UuQJplp)2oNAZfB*pk1PBlyK!5-N0t6}w z8a%LMC^C^!9VPFZr=oAno13_5=tJAV7cs0RjXF5FkK+ z009C7iU=%4qEroHa(Gofesz+kGzkzOK;T)xXZW*;R|pUoUBI=G(K|dteU9Q8x~xV5 z1PBlyK!5-N0t99f_%TzlY9&B`0D*OZw7$w30t5&U_);J}uZ=Qq`#H1CSDYYh64`(N z0RjXF5FkK+009C72oN|g;1a}nLlFoNm`xzfRr5I7=`kL+Y0U-;=5AV7dXJOST9 z@$yn+=1GdzTNw>0;4M33TNOos0D*7>EK~iI9XG2oUI7z!`Yo{gZv40^WCh_H8xm zyt>8;0tChqcpa-8)es;+fB=Ct0aIJnWV}v*009C72wWuK&y$PbI~sP`nd{DH^&Emb zeQi#F009EA1>Eh3-5=Qzs3PEvUxhVPP-iWn+EF4IEiIuaMi&A*FVb{TlOzccAV8p{ zz|wLsV-X-gppHPU6IRq21sqH>c3sT`2wW>r{3&5Kbgpfv(FxQMa2dRgtEdDB5C|cV zLu4Td0t5&UAV8p*K=F$~%`!I-0RlGxb8{UD1PBlyK!5;&h5}2&u?$6k0D-;*{=>(s zPCx(rzE^X5^?kYTB4tm2009C72oNAZfB*pk1PBlyK!5;&iUPS}Y@rDdAV7cs0RjXF z5FkK+KvaQ`(~hF%C@%s82t*V}5tAA!C&ELuQ!xYx5SUsZPhI`&#i!W;)K7o_0RjZ# z2>8aRIK7a`T_C;vT<%ML>=j6Rcd$JH0t5&UAV7cs0RjXF5FkK+0D&R`OOYs5gP0s% zl~?fY1yc7FD1ZO~0t5&UAV7csf$#!O&BM1yf&>TZ1WW-2%AJUAV7cs0RjXF5FkK+009C7 z&I`B%ao$h_0t99gNV65JUIGM;2;?I>*~b@tItB<3AP`T$cTl{%6q$LF;`LTWLkf7y z4%t>k5g2oNB!C6Kl@u$}+`0t5&Ucoc|y zGrq`^7LVmxBJfur@?oz-1PBlyK!5;&@deCo9lysaBtU=w0RjXF5ExJ(4_K3u2oNAZ zfWRdJVZRVJU&3Kf0t5(jAz%tq7j2Rx0RjXF5I87s)f|T9V7>$G7LFk78T&v@R| z0-wG`(}{p~B|v}x0RjX@7x?tghk`|?g0X}mK;W>za(GWW5+Fc;0D;{CW)AEovjc&< zz*TqSG=KnsSp{le6`Ivm-2?~_AVA;}fsKE~%J2P4x?)fQ1m+g-(K~nlRZoBb0RjXF zbSjWK&AY3#H?CoHRf}W^JPM@8MN0$-5FpT4AU7V*a5n+dMI8wQzAfOk!MCYwNPqwV z0t5)05%5sT89n<(5LhB4AqN5k`WA2o-gp0G-=~20U7vkh%{s5Hv4Q}Bu>@YnDn~U0 z2oNAZU`@c(mNgl#6Cgl<009CQ3HbBmBKVGmU3TWW^I1KI;7(tg6Cgll1NP++X0t5&UXeLnn zVo3Y z6Cgl<009C72oNAZfB*pk1PBlyK%k;Pt{7Wr0t5&UAV7cs0RjXF5Fij$;N!HTs5#1u z009CK1yaPMhRTWXQ0-I<0RjZ37RXaqKYQ_Mb^!GgAV7csfj9!bF)B_kWO5fsZ$Fp& zk{^2o(%v0xPk;ac0t5&UAV7cs0RjXF5FkLHh`>@LO4T4HhganlynBJveFX|2K!5-N z0t5&UAV46zfK&7EEs`Js0t5&UAV8oefhf;Hy!M19R{{hG5a>kUS0{N&lK=q%1fB(a zhCiElg#dxk1zZ~$y~8uq=O~_`%W5P*fB*pk1PBlyKwu_;A2SuJRssYF5Lg#T>#M9G zK!5;&F9p)`+9>n3pEKKh#R$WHe0g`bWA0t5)e6Yw1rFE2%Ao}_ramC=v_-m*isRZ#>85C|vWYfe^M zl2+GP@ufiia;=pF3JK&wafBi8CXnMeg!#oBCXs5rS&Bz?7GIoHKmr5^5FkLHmVlYY zwPeL5K!5-N0t5)O5?ERdWE=tn2y6+YtqrUvK!5-N0t6lfBHxTJ@}$LMxt0k06^MM; z>kt6~1PBlyKwx|Uvs=gSu?h(gAV7cs0RjXD6vzYCq$C0a2oNA}i9pyd#Lbs*7?c13 z0$m80!qi2ZBuRh(0RjXL3S2dZVL6!ZK)Zz_2z$mpP}7w{;Do@ZZ_#ujpj`2c8#0RjXFG#1E>$1~hbz;sbZ0)cM}xNY!lDjO0YK!5-N0%rs~lyXMTz7YhL z2ua9+0D-;*oPqbb=DH9 z9VL>{(h`bdbRn?wB25=HNs<5o0t8wLEG-8!76AeT>ImdIVMU!$z`-YL>7`DK!5-N0tA`~6u%hMEOP@9AaD~fH`kFs zfB*pk1PBmlD6ljf%TNRe5a?Ur-+jF5^z+Z}do{OL-2fr?I>!F@*+ThKtzEQF{z<)B0N+( z6+?gkfvE-Z)YZ>ke3~6V{R9XQAV46FfNzY7(+ip01=8Ek<-X*{UV*fC2ip@MK!5-N z0t5&UAV7cs0RjXF5GW$B6p2zbh{@qqc?IuYAa!4X0tgTwK!5-N0t5&U2ruB&Jba5J zNPqwV0t5&U=t&^TvkhfB=DK0iWT|CSD;xU~~c3Mn>=O z4D~sRXXvsT2@oJafB*pk1PBnAN#Ms!#j2G60RjZp1=9K|YX}e^K;TP(^t?98yzS@A zHeYdqut{VC0t5&UAV7cs0RjXF5FkL{ynss(=M6<5Kwvh3G+V*yB|zYaKt8gQeSG1k zV}Jkw0`UZV2gS=vk(nncUTal>j@AbK!5;&M}f#U3v z@q4U70t5&UAV7csfdK{bfHf(J009C72wWl%_6u?IB^(ANK!89O0;Vu^(I!a}AV7cs zfrA29&0$y$<~z`C;RwQ>u@BUAr4TqF@abDLod{@G0t5&UAV6SrflvQ@C|GnV7)vMu z1P%)s_p^#lkIAV7dXrvj*yJXY=0Yy0YxrbY3U)LbrLV_c|-* zf51WTA(B*tTa*xjFTnJLJm^AubVjC2nD8b^SaIH z5-@N{A6tV0yLFB6x{T9}fH`NJdtG=LV_+)L{5DVC?YmL`!oGyb2&Y1-B zG1?YD-uzUedlAe%_>HyX;zj`GZN7WWx1q}Z9Yb^iVw>xN}9++s3fz_ z%4dN%Ne?ce(l1TXflHvMs5OAdr3AM}#S+eO30|_uw|KCf@EUct zD-w9D^HUcoe*@(mz5xYiWuU(8H&Czo8z@YxhU(cUcKim)Z`DBQ;Wwc0_8TZ)R0c{> z)j+XQ4Jd0X17%77CPpEfh*+uyN(A@@N|}EH1#D$N8Bz@tbt(g8_sT%AQ5jIq{|%H- zDg#BGGEnsS4Jc451LcY`P;SyUP}=#4PAXd3Z=j%G87QzS14??ofznUK6Cs{({-ec| rR#9c34hBk1snkqUT>A}_O8y3lY%q$)HspVVJnoc7{OtEufnrB;=?IoQ literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/.usage.json b/.minio.sys/buckets/.usage.json new file mode 100644 index 00000000..a486b555 --- /dev/null +++ b/.minio.sys/buckets/.usage.json @@ -0,0 +1 @@ +{"lastUpdate":"2022-08-27T21:11:14.1118762+08:00","objectsCount":151,"objectsTotalSize":61095515,"objectsReplicationInfo":null,"bucketsCount":10,"bucketsUsageInfo":{"app":{"size":60755226,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":77,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":56,"BETWEEN_10_MB_AND_64_MB":1,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":20},"objectReplicaTotalSize":0,"objectsReplicationInfo":{}},"base":{"size":129938,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":38,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":28,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":10},"objectReplicaTotalSize":0,"objectsReplicationInfo":{}},"database":{"size":104362,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":25,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":14,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":11},"objectReplicaTotalSize":0,"objectsReplicationInfo":{}},"docs":{"size":93002,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":3,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":3,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":0},"objectReplicaTotalSize":0,"objectsReplicationInfo":{}},"event":{"size":2852,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":7,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":1,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":6},"objectReplicaTotalSize":0,"objectsReplicationInfo":{}},"images":{"size":0,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":0,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":0,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":0},"objectReplicaTotalSize":0,"objectsReplicationInfo":null},"problems":{"size":0,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":0,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":0,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":0},"objectReplicaTotalSize":0,"objectsReplicationInfo":null},"scripts":{"size":0,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":0,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":0,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":0},"objectReplicaTotalSize":0,"objectsReplicationInfo":null},"submissions":{"size":0,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":0,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":0,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":0},"objectReplicaTotalSize":0,"objectsReplicationInfo":null},"template":{"size":10135,"objectsPendingReplicationTotalSize":0,"objectsFailedReplicationTotalSize":0,"objectsReplicatedTotalSize":0,"objectsPendingReplicationCount":0,"objectsFailedReplicationCount":0,"objectsCount":1,"objectsSizesHistogram":{"BETWEEN_1024_B_AND_1_MB":1,"BETWEEN_10_MB_AND_64_MB":0,"BETWEEN_128_MB_AND_512_MB":0,"BETWEEN_1_MB_AND_10_MB":0,"BETWEEN_64_MB_AND_128_MB":0,"GREATER_THAN_512_MB":0,"LESS_THAN_1024_B":0},"objectReplicaTotalSize":0,"objectsReplicationInfo":{}}},"bucketsSizes":null} \ No newline at end of file diff --git a/.minio.sys/buckets/app/.usage-cache.bin b/.minio.sys/buckets/app/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..a5e893ae5f511ec07ddb6d5eb30d7d79b79d0811 GIT binary patch literal 294 zcmV+>0oncsD77#BL;#QgwFm$rP&+hGjR3$2HI9l?_NOFr5chAf`$B2Jfiuk?dH&Y@ zC$FLQ`HHH_PGDN)JZDXVJ(##4`~Ds)SQ@x+pYJr^TJzWy&800=fQ9>fhxyi+$KE8c zR4aBpOZ%A`b^C1OiZ1)siV$`9SO-{}@P408AEx7aeJ_pAqKQ?dW|>8xbN~Flhu2 s0Jh?sl|a`F0KUx=a1#n7%mQeyT{$N&^zwfwQLOE@%S&p9tN;K2 literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/base/.usage-cache.bin b/.minio.sys/buckets/base/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..6f3001c4d5f1e0dbc85cfbd6130a6b1aaa494ed9 GIT binary patch literal 337 zcmV-X0j~ZBD77#BL;wN-4GI9l(Lgy+Q4|2ce;WEjHqf(T{GV({-lpvcFi>uo2-slP zZ!c~;S-g)}C%&pI5rE*k!?+tLQw(%e(RNBbC>XNVgV528E3b92IvP7nibP&J^4S_4 zyD1Y&GI{OEXDeV`X3A@H+6wgTqUyD)&-SRg?X6AvFj2m0x{Q>QneyU4Y(!&+L^H0; zp@IG3Ka86cfWBQsd2PyPR|wcmT}H~e_zx?gVCaH|Fs}9P?ph1_c9Hek)@K(u=(hKU z2KI+F4u;{>HW&Y4rVnf2t9+a?S(J|*HgO^XqyfMJ1Azny+}$NG2x0m#n+yGeC=D10 zz!F+iXooE%{=+z?cor^WN@Ne5Cl~;L!&jXF2n`=@T4!KI1g?Y5YOL{FNuZ$sxDZHI j6;GC-3;`Ao(g9IW2aqv6xkeenfMnI#;}S{=B9x05F7TDd literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/database/.usage-cache.bin b/.minio.sys/buckets/database/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..f28cb54e4e467cd4faf9b887eb9aa6b8dc2350dd GIT binary patch literal 185 zcmZSA*sA}Rg&~%ep@g$(iDzC~e#;WS#N5;sDTyVCNr}a&EB#U{N}MZ`b5hT;JXqzE zSX>fX0F+BT&cn(81j$_D9}N~*yjdNbomt?KnwXQBmwsreb7FEvYE%27g!6 zQgezI6<1wiV7REbD8HC(QCTtD;^L~}=}asjGZ+>X6*n#{X;_$i2&84gu}+{OVW1*m gPOgQ?huIh!3^Pt>`w^ytMq5C4PyysY_DwlZ#jSrB;+US0?AAo@IHk$|te7B(xwU zu_X044=V!@By)*>G_}jrSRI_5S>TbHn3I{8erTz4Vsb`mBUpd?qU4MTi;Al*F)(I( mEy^!uUQ|}hytufkcsc_!$N+{#Ma7K^OBxm?ADUTJQwac^QZ_dL literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/event/.usage-cache.bin b/.minio.sys/buckets/event/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..984313e7f08ba74245cee76c15544d9bcd4f3a13 GIT binary patch literal 266 zcmZSA*sA~6g`u9|Dm%j#o~9+9d1?7AOZ*aZQQMajs0xNj=N*V3ki| zaY<-FN@7XsaUNC%AV}sC|7b3+erI)Xc4mP`YGO`iUizV>&WXtxsjVx)2I%MHr?)Rk z&X};MxauOa!lL|QrbT7NOpA-Fil;Myj9_3`R8-u!u%uyO^5Hh1!YS*DQqwbwOHzx9 zO7k`pmnP+A78hsc=K;+D8o>ZGfB|R#1K0qDg~^A2su*9dV{rjWFajkQ85lP(UQIqM z#K6>@cwIuo38*T CA!!}} literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/images/.metadata.bin b/.minio.sys/buckets/images/.metadata.bin new file mode 100644 index 0000000000000000000000000000000000000000..520efeec2c694969eaee40c18e557e798dc3d99a GIT binary patch literal 299 zcmZQ%U}Wf9;+L44x-2s{F+H_-xpPr!Vo7SsaUNC%AV}u;y~t3;X3A=x{N!xcyu_rO z)RaRT0`hY*lPjI`^U^ZYy@LJyjxcQX%P+}H%S=uz$;{7#NJRMh9AVhxlbM#9T$!Ac ziX^z%KPf9Uxddb+vS?UpQ87?=W?nk7sB2zwQDp&|u^U1X)6-EEt`98DFG+;xgt%!- lP-+3to#;;5?o^tbomvu-Sd^YxQjDx&Hx?P+)RIJqaR6NvbaMaz literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/images/.usage-cache.bin b/.minio.sys/buckets/images/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..e42e130b71288f9e988f41a9daa0418dbd63fa0b GIT binary patch literal 131 zcmZSA*sA}Rg<&N#L(>w^ytMq5C4Pyysmn5R6Vp?RSNf$^lsH!==cJxxd9cbSvA86( zASJOR^*9eJ0}v#0iGQ^CD!X8HaCT;aM`~hDW?uTCrOt`T8L5p>6WSIfXG~aBT*a^` bznEcBSuw-n;;Q25Ak9FqF!|62z3s;VP7^ce literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/problems/.metadata.bin b/.minio.sys/buckets/problems/.metadata.bin new file mode 100644 index 0000000000000000000000000000000000000000..4f496f16b9fb5bd560ed495333ffe68dc5f7de53 GIT binary patch literal 301 zcmZQ%U}Wf9;+L44x}u;cKPe|Qw|Kd8QEFmIYRYjQRt6wQ=J>tHaOb6j)js*j*{*qs zKs70cHU#A7WF}WS=jWwmrh5hZ`yFA}>X%=VnUvwu=nYH|t4NMzBl)S_ab?##S&WKq|=wB4yRIXkr^B(W$xwWJtX!)`1xzNsaN5aR%M>ULrP literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/problems/.usage-cache.bin b/.minio.sys/buckets/problems/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..ff508d94820649bbf0b763fef79b1ab2e19e74d7 GIT binary patch literal 135 zcmZSA*sA}Rh2bPKL(>w^ytMq5C4PyysVfSK@{@8>bBkB{rB;+US0?AAo@IHk$|te7 zB(xwUu_X044=V!@By)*>w7T4MWOZ?YGO%h%5ff61|Uf0_`S%mIq$=2pZw%(*Sy4} zoYa&<8v^okGLtKv^YhX&)4hWI{f;nf^~*2GOv_A8EXmBzgGfa9`W#`{w^ytMq5C4PyysmqI#i!uvJidXujR+KnbCg-G{WqGj5C$YFB zv>+w1B=tBCD+3TDbBTXq6nwE|b#QiOfk$d$PG(;Ep{34=$r-7QFeBO)C1*@nR9wZd cD8HCtQCTs=;^L~}=^))eurT@18M~v|0LPd#fdBvi literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/submissions/.metadata.bin b/.minio.sys/buckets/submissions/.metadata.bin new file mode 100644 index 0000000000000000000000000000000000000000..1ae8be989b29cff3693356bbf87f3f24695814a3 GIT binary patch literal 304 zcmZQ%U}Wf9;+L44y1KYDDL1pYI5R)5c)4>?YGO%h%5ff61|Uf0_`S&R2YbS5pZw%( z*Sy4}oYa&<8v^okGLtKv^YhX&)4hWI{f;nf^~*2GOv_A8ECCtzQmLx)q0|0_$cQgP1 literal 0 HcmV?d00001 diff --git a/.minio.sys/buckets/submissions/.usage-cache.bin b/.minio.sys/buckets/submissions/.usage-cache.bin new file mode 100644 index 0000000000000000000000000000000000000000..8f7c0525a564c335937c5123bdc832af74bfa9ef GIT binary patch literal 141 zcmZSA*sA}Rh2bYNL(>w^ytMq5C4PyysjG`ilX5eQi!<}{idXujR+KnbCg-G{WqGj5 zC$YFBv>+w1B=tBCD+3TDbBTXqdM946IygJCz#}y=Co?bo&{F5bG``$r%$C6<1wU npS~!+m~l~AG2`Oms^aMkj36Tz78MmYE-YzSn0%;U1OHC| Date: Mon, 5 Sep 2022 21:46:27 +0800 Subject: [PATCH 05/21] backend file --- app/controller/solution.go | 11 ----------- base/utils/query_helper.go | 14 ++++++++++++++ database/models/solution.go | 8 ++++++++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/app/controller/solution.go b/app/controller/solution.go index dbbc6782..3c00bfe9 100644 --- a/app/controller/solution.go +++ b/app/controller/solution.go @@ -25,17 +25,6 @@ func GetSolution(c echo.Context) error { } else if err != nil { panic(err) } - if user.Can("read_solution_secrets", solution) || user.Can("read_solution_secrets") { - return c.JSON(http.StatusOK, response.GetSolutionResponseForAdmin{ - Message: "SUCCESS", - Error: nil, - Data: struct { - *resource.SolutionForAdmin `json:"problem"` - }{ - resource.GetSolutonForAdmin(solution), - }, - }) - } return c.JSON(http.StatusOK, response.GetSolutionResponse{ Message: "SUCCESS", Error: nil, diff --git a/base/utils/query_helper.go b/base/utils/query_helper.go index 2cd9c34f..b22f4064 100644 --- a/base/utils/query_helper.go +++ b/base/utils/query_helper.go @@ -137,6 +137,20 @@ func FindProblem(id string, user *models.User) (*models.Problem, error) { return &problem, nil } +func FindSolution(id string, user *models.User) (*models.Solution, error) { + solution := models.Solution{} + query := base.DB + err := query.Preload("Tags").Where("id = ?", id).First(&solution).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, err + } else { + return nil, errors.Wrap(err, "could not query solution") + } + } + return &solution, nil +} + // This function checks if the user has permission to get problems which are not public. // nil user pointer is regarded as admin(skip the permission judgement). func FindTestCase(problemId string, testCaseIdStr string, user *models.User) (*models.TestCase, *models.Problem, error) { diff --git a/database/models/solution.go b/database/models/solution.go index d7335001..7c657339 100644 --- a/database/models/solution.go +++ b/database/models/solution.go @@ -15,3 +15,11 @@ type Solution struct { UpdatedAt time.Time `json:"-"` DeletedAt gorm.DeletedAt `json:"deleted_at"` } + +func (s Solution) GetID() uint { + return s.ID +} + +func (s Solution) TypeName() string { + return "solution" +} From 9a8b986c6c3859d26691a8cf5bbef700c3454e2d Mon Sep 17 00:00:00 2001 From: Invariant64 <1319438556@qq.com> Date: Mon, 5 Sep 2022 21:54:24 +0800 Subject: [PATCH 06/21] backend file --- app/controller/solution.go | 40 +------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/app/controller/solution.go b/app/controller/solution.go index 3c00bfe9..68f1be88 100644 --- a/app/controller/solution.go +++ b/app/controller/solution.go @@ -45,12 +45,6 @@ func GetSolutions(c echo.Context) error { query := base.DB.Model(&models.Solution{}).Order("id ASC").Omit("Description") // Force order by id asc. - user := c.Get("user").(models.User) - isAdmin := user.Can("manage_solution") - if !isAdmin { - query = query.Where("public = ?", true) - } - if req.Search != "" { id, _ := strconv.ParseUint(req.Search, 10, 64) query = query.Where("id = ? or name like ?", id, "%"+req.Search+"%") @@ -82,27 +76,6 @@ func GetSolutions(c echo.Context) error { panic(err) } - if isAdmin { - return c.JSON(http.StatusOK, response.GetSolutionsResponseForAdmin{ - Message: "SUCCESS", - Error: nil, - Data: struct { - Solutions []resource.SolutionSummaryForAdmin `json:"solutions"` - Total int `json:"total"` - Count int `json:"count"` - Offset int `json:"offset"` - Prev *string `json:"prev"` - Next *string `json:"next"` - }{ - Solutions: resource.GetSolutionSummaryForAdminSlice(solutions, passed), - Total: total, - Count: len(solutions), - Offset: req.Offset, - Prev: prevUrl, - Next: nextUrl, - }, - }) - } return c.JSON(http.StatusOK, response.GetSolutionsResponse{ Message: "SUCCESS", Error: nil, @@ -114,7 +87,7 @@ func GetSolutions(c echo.Context) error { Prev *string `json:"prev"` Next *string `json:"next"` }{ - Solutions: resource.GetSolutionSummarySlice(solutions, passed), + Solutions: resource.GetSolutionSummarySlice(solutions), Total: total, Count: len(solutions), Offset: req.Offset, @@ -136,17 +109,6 @@ func CreateSolution(c echo.Context) error { if !ok { return err } - var public, privacy bool - if req.Public == nil { - public = false - } else { - public = *req.Public - } - if req.Privacy == nil { - privacy = false - } else { - privacy = *req.Privacy - } solution := models.Solution{ Name: req.Name, From 9b2e4275e748ac882e4e1e9c31056b72900c197d Mon Sep 17 00:00:00 2001 From: Noah <98544022+Invariant64@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:58:12 +0800 Subject: [PATCH 07/21] Update solution.go --- app/response/solution.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/response/solution.go b/app/response/solution.go index f2a46aa4..4d24dd22 100644 --- a/app/response/solution.go +++ b/app/response/solution.go @@ -16,7 +16,7 @@ type GetSolutionsResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - Problems []resource.ProblemSummary `json:"problems"` + Problems []resource.ProblemSummary `json:"problems"` // 这里是否需要把problem都改成solution? --Noah Total int `json:"total"` Count int `json:"count"` Offset int `json:"offset"` From b74abb1f6bcb0d8aa5b2778bf8c6bc91ca4105bd Mon Sep 17 00:00:00 2001 From: Invariant64 <1319438556@qq.com> Date: Tue, 6 Sep 2022 17:40:23 +0800 Subject: [PATCH 08/21] backend file --- app/request/solution.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/request/solution.go b/app/request/solution.go index 3543124b..3ec135e1 100644 --- a/app/request/solution.go +++ b/app/request/solution.go @@ -11,4 +11,11 @@ type GetSolutionRequest struct { } type GetSolutionsRequest struct { + Search string `json:"search" form:"search" query:"search"` + UserID uint `json:"user_id" form:"user_id" query:"user_id" validate:"min=0,required_with=Tried Passed"` + + Limit int `json:"limit" form:"limit" query:"limit" validate:"max=100,min=0"` + Offset int `json:"offset" form:"offset" query:"offset" validate:"min=0"` + + Tags string `json:"tags" form:"tags" query:"tags"` } From 10c79e74be3900128f8f7e5044800f2e37b302d4 Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Wed, 19 Oct 2022 19:14:09 +0800 Subject: [PATCH 09/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E9=A2=98=E8=A7=A3?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution.go | 92 +++-------------------- app/request/solution.go | 29 ++++--- app/request/solution_comment.go | 15 ++++ app/response/resource/solution.go | 23 ++++-- app/response/resource/solution_comment.go | 27 +++++++ app/response/solution.go | 15 ++-- app/response/solution_comment.go | 27 +++++++ app/routes.go | 14 +++- base/utils/query_helper.go | 13 ++-- database/migrate.go | 35 ++++++++- database/models/solution.go | 12 ++- database/models/solution_comment.go | 32 ++++++++ 12 files changed, 213 insertions(+), 121 deletions(-) create mode 100644 app/request/solution_comment.go create mode 100644 app/response/resource/solution_comment.go create mode 100644 app/response/solution_comment.go create mode 100644 database/models/solution_comment.go diff --git a/app/controller/solution.go b/app/controller/solution.go index 68f1be88..cdfd63af 100644 --- a/app/controller/solution.go +++ b/app/controller/solution.go @@ -1,8 +1,8 @@ package controller import ( - "errors" - "fmt" + "net/http" + "github.com/EduOJ/backend/app/request" "github.com/EduOJ/backend/app/response" "github.com/EduOJ/backend/app/response/resource" @@ -10,16 +10,12 @@ import ( "github.com/EduOJ/backend/base/utils" "github.com/EduOJ/backend/database/models" "github.com/labstack/echo/v4" + "github.com/pkg/errors" "gorm.io/gorm" - "net/http" - "strconv" - "strings" ) -// TODO func GetSolution(c echo.Context) error { - user := c.Get("user").(models.User) - solution, err := utils.FindSolution(c.Param("id"), &user) + solution, err := utils.FindSolution(c.Param("id")) if errors.Is(err, gorm.ErrRecordNotFound) { return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) } else if err != nil { @@ -36,74 +32,7 @@ func GetSolution(c echo.Context) error { }) } -// TODO -func GetSolutions(c echo.Context) error { - req := request.GetSolutionsRequest{} - if err, ok := utils.BindAndValidate(&req, c); !ok { - return err - } - - query := base.DB.Model(&models.Solution{}).Order("id ASC").Omit("Description") // Force order by id asc. - - if req.Search != "" { - id, _ := strconv.ParseUint(req.Search, 10, 64) - query = query.Where("id = ? or name like ?", id, "%"+req.Search+"%") - } - - where := (*gorm.DB)(nil) - - if req.Tags != "" { - tags := strings.Split(req.Tags, ",") - query = query.Where("id in (?)", - base.DB.Table("tags"). - Where("name in (?)", tags). - Group("solution_id"). - Having("count(*) = ?", len(tags)). - Select("solution_id"), - ) - } - - if where != nil { - query = query.Where(where) - } - - var solutions []*models.Solution - total, prevUrl, nextUrl, err := utils.Paginator(query.WithContext(c.Request().Context()).Preload("Tags"), req.Limit, req.Offset, c.Request().URL, &solutions) - if err != nil { - if herr, ok := err.(utils.HttpError); ok { - return herr.Response(c) - } - panic(err) - } - - return c.JSON(http.StatusOK, response.GetSolutionsResponse{ - Message: "SUCCESS", - Error: nil, - Data: struct { - Solutions []resource.SolutionSummary `json:"solutions"` - Total int `json:"total"` - Count int `json:"count"` - Offset int `json:"offset"` - Prev *string `json:"prev"` - Next *string `json:"next"` - }{ - Solutions: resource.GetSolutionSummarySlice(solutions), - Total: total, - Count: len(solutions), - Offset: req.Offset, - Prev: prevUrl, - Next: nextUrl, - }, - }) -} - -// TODO func CreateSolution(c echo.Context) error { - file, err := c.FormFile("attachment_file") - if err != nil && err != http.ErrMissingFile && err.Error() != "request Content-Type isn't multipart/form-data" { - panic(errors.Wrap(err, "could not read file")) - } - req := request.CreateSolutionRequest{} err, ok := utils.BindAndValidate(&req, c) if !ok { @@ -111,22 +40,21 @@ func CreateSolution(c echo.Context) error { } solution := models.Solution{ + ProblemID: req.ProblemID, Name: req.Name, + Author: req.Author, Description: req.Description, + Likes: req.Likes, } utils.PanicIfDBError(base.DB.Create(&solution), "could not create solution") - user := c.Get("user").(models.User) - user.GrantRole("solution_creator", solution) - - if file != nil { - utils.MustPutObject(file, c.Request().Context(), "solutions", fmt.Sprintf("%d/attachment", solution.ID)) - } return c.JSON(http.StatusCreated, response.CreateSolutionResponse{ Message: "SUCCESS", Error: nil, Data: struct { - *resource.SolutionForAdmin(&solution) + *resource.Solution `json:"solution"` + }{ + resource.GetSolution(&solution), }, }) diff --git a/app/request/solution.go b/app/request/solution.go index 3ec135e1..ce893a7b 100644 --- a/app/request/solution.go +++ b/app/request/solution.go @@ -1,21 +1,32 @@ package request type CreateSolutionRequest struct { + ProblemID uint `json:"problem_id" from:"problem_id" query:"problem_id" validate:"required"` Name string `json:"name" form:"name" query:"name" validate:"required,max=255"` + Author string `json:"author" form:"suthor" query:"author" validate:"required"` Description string `json:"description" form:"description" query:"description" validate:"required"` - // attachment_file(optional) - Public *bool `json:"public" form:"public" query:"public" validate:"required"` + // Public *bool `json:"public" form:"public" query:"public" validate:"required"` + Likes uint `json:"likes" from:"likes" querry:"likes" validate:"required"` } type GetSolutionRequest struct { } -type GetSolutionsRequest struct { - Search string `json:"search" form:"search" query:"search"` - UserID uint `json:"user_id" form:"user_id" query:"user_id" validate:"min=0,required_with=Tried Passed"` +type UpdateSolutionRequest struct { + ProblemID uint `json:"problem_id" from:"problem_id" query:"problem_id" validate:"required"` + Name string `json:"name" form:"name" query:"name" validate:"required,max=255"` + Author string `json:"author" form:"suthor" query:"author" validate:"required"` + Description string `json:"description" form:"description" query:"description" validate:"required"` + // Public *bool `json:"public" form:"public" query:"public" validate:"required"` + Likes uint `json:"likes" from:"likes" querry:"likes" validate:"required"` +} - Limit int `json:"limit" form:"limit" query:"limit" validate:"max=100,min=0"` - Offset int `json:"offset" form:"offset" query:"offset" validate:"min=0"` +// type GetSolutionsRequest struct { +// Search string `json:"search" form:"search" query:"search"` +// UserID uint `json:"user_id" form:"user_id" query:"user_id" validate:"min=0,required_with=Tried Passed"` - Tags string `json:"tags" form:"tags" query:"tags"` -} +// Limit int `json:"limit" form:"limit" query:"limit" validate:"max=100,min=0"` +// Offset int `json:"offset" form:"offset" query:"offset" validate:"min=0"` + +// Tags string `json:"tags" form:"tags" query:"tags"` +// } diff --git a/app/request/solution_comment.go b/app/request/solution_comment.go new file mode 100644 index 00000000..10afa144 --- /dev/null +++ b/app/request/solution_comment.go @@ -0,0 +1,15 @@ +package request + +type CreateSolutionCommentRequest struct { + SolutionID uint `json:"solution_id" from:"solution_id" query:"solution_id" validate:"required"` + FatherNode uint `json:"father_node" from:"father_node" query:"father_node" validate:"father_node"` + Description string `json:"description" from:"description" query:"description" validate:"description"` + Speaker string `json:"speaker" from:"speaker" query:"speaker" validate:"speaker"` +} + +type UpdateSolutionCommentRequest struct { + SolutionID uint `json:"solution_id" from:"solution_id" query:"solution_id" validate:"required"` + FatherNode uint `json:"father_node" from:"father_node" query:"father_node" validate:"father_node"` + Description string `json:"description" from:"description" query:"description" validate:"description"` + Speaker string `json:"speaker" from:"speaker" query:"speaker" validate:"speaker"` +} diff --git a/app/response/resource/solution.go b/app/response/resource/solution.go index f1783edc..40d6af0c 100644 --- a/app/response/resource/solution.go +++ b/app/response/resource/solution.go @@ -3,13 +3,26 @@ package resource import "github.com/EduOJ/backend/database/models" type Solution struct { - ID uint `json:"id"` + ID uint `json:"id"` + + ProblemID uint `json:"problem_id"` Name string `sql:"index" json:"name"` + Author string `json:"author"` Description string `json:"description"` + Likes uint `json:"likes"` +} + +func (s *Solution) convert(solution *models.Solution) { + s.ID = solution.ID + + s.ProblemID = solution.ProblemID + s.Name = solution.Name + s.Description = solution.Description + s.Likes = solution.Likes } -func GetSolution(problem *models.Problem) *Problem { - p := Problem{} - p.convert(problem) - return &p +func GetSolution(solution *models.Solution) *Solution { + s := Solution{} + s.convert(solution) + return &s } diff --git a/app/response/resource/solution_comment.go b/app/response/resource/solution_comment.go new file mode 100644 index 00000000..f9b679ef --- /dev/null +++ b/app/response/resource/solution_comment.go @@ -0,0 +1,27 @@ +package resource + +import "github.com/EduOJ/backend/database/models" + +type SolutionComment struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` +} + +func (sc *SolutionComment) convert(solutionComment *models.SolutionComment) { + sc.ID = solutionComment.ID + + sc.SolutionID = solutionComment.SolutionID + sc.FatherNode = solutionComment.FatherNode + sc.Description = solutionComment.Description + sc.Speaker = solutionComment.Speaker +} + +func GetSolutionComment(solutionComment *models.SolutionComment) *SolutionComment { + sc := SolutionComment{} + sc.convert(solutionComment) + return &sc +} diff --git a/app/response/solution.go b/app/response/solution.go index 4d24dd22..e103ffd2 100644 --- a/app/response/solution.go +++ b/app/response/solution.go @@ -8,27 +8,22 @@ type GetSolutionResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.Problem `json:"problem"` + *resource.Solution `json:"solution"` } `json:"data"` } -type GetSolutionsResponse struct { +type CreateSolutionResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - Problems []resource.ProblemSummary `json:"problems"` // 这里是否需要把problem都改成solution? --Noah - Total int `json:"total"` - Count int `json:"count"` - Offset int `json:"offset"` - Prev *string `json:"prev"` - Next *string `json:"next"` + *resource.Solution `json:"solution"` } `json:"data"` } -type CreateSolutionResponse struct { +type UpdateSolutionResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.ProblemForAdmin `json:"problem"` + *resource.Solution `json:"solution"` } `json:"data"` } diff --git a/app/response/solution_comment.go b/app/response/solution_comment.go new file mode 100644 index 00000000..fef79ff5 --- /dev/null +++ b/app/response/solution_comment.go @@ -0,0 +1,27 @@ +package response + +import "github.com/EduOJ/backend/app/response/resource" + +type GetSolutionCommentResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.SolutionComment `json:"solution"` + } `json:"data"` +} + +type CreateSolutionCommentResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.SolutionComment `json:"solution"` + } `json:"data"` +} + +type UpdateSolutionCommentResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.SolutionComment `json:"solutiong_comment"` + } `json:"data"` +} diff --git a/app/routes.go b/app/routes.go index a02e869e..1a8db446 100644 --- a/app/routes.go +++ b/app/routes.go @@ -168,10 +168,16 @@ func Register(e *echo.Echo) { submission.GET("/submission/:submission_id/run/:id/comparer_output", controller.GetRunComparerOutput, middleware.Logged).Name = "submission.getRunComparerOutput" // solution APIs - // api.POST("/admin/solution", controller.CreateSolution, - // middleware.Logged, middleware.EmailVerified, - // middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution"}), - // ).Name = "solution.createSolution" + solution := api.Group("", + middleware.ValidateParams(map[string]string{ + "id": "NOT_FOUND", + }), + middleware.Logged, middleware.EmailVerified) + api.POST("/solution", controller.CreateSolution, + middleware.Logged, middleware.EmailVerified, + middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution"}), + ).Name = "solution.createSolution" + solution.GET("/solution/:id", controller.GetSolution).Name = "solution.getSolution" // log API api.GET("/admin/logs", controller.AdminGetLogs, diff --git a/base/utils/query_helper.go b/base/utils/query_helper.go index b22f4064..95df35d1 100644 --- a/base/utils/query_helper.go +++ b/base/utils/query_helper.go @@ -2,15 +2,16 @@ package utils import ( "fmt" - "github.com/EduOJ/backend/base" - "github.com/EduOJ/backend/database/models" - "github.com/pkg/errors" - "gorm.io/gorm" "net/http" "net/url" "reflect" "strconv" "strings" + + "github.com/EduOJ/backend/base" + "github.com/EduOJ/backend/database/models" + "github.com/pkg/errors" + "gorm.io/gorm" ) func Paginator(query *gorm.DB, limit, offset int, requestURL *url.URL, output interface{}) (total int, prevUrl, nextUrl *string, err error) { @@ -137,10 +138,10 @@ func FindProblem(id string, user *models.User) (*models.Problem, error) { return &problem, nil } -func FindSolution(id string, user *models.User) (*models.Solution, error) { +func FindSolution(id string) (*models.Solution, error) { solution := models.Solution{} query := base.DB - err := query.Preload("Tags").Where("id = ?", id).First(&solution).Error + err := query.Where("id = ?", id).First(&solution).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, err diff --git a/database/migrate.go b/database/migrate.go index 45a24bf1..9af51295 100644 --- a/database/migrate.go +++ b/database/migrate.go @@ -2,13 +2,14 @@ package database import ( "fmt" + "time" + "github.com/EduOJ/backend/base" "github.com/go-gormigrate/gormigrate/v2" "github.com/pkg/errors" "github.com/spf13/viper" "gorm.io/datatypes" "gorm.io/gorm" - "time" ) func GetMigration() *gormigrate.Gormigrate { @@ -337,6 +338,38 @@ func GetMigration() *gormigrate.Gormigrate { return }, }, + // add solutions + { + ID: "add_solutions", + Migrate: func(tx *gorm.DB) (err error) { + + type Solution struct { + ID uint `gorm:"primaryKey" json:"id"` + + ProblemID uint `json:"problem_id"` + Name string `sql:"index" json:"name"` + Author string `sql:"index" json:"auther"` + Description string `json:"description"` + Likes uint `json:"likes"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` + } + err = tx.AutoMigrate(&Solution{}) + if err != nil { + return + } + return + }, + Rollback: func(tx *gorm.DB) (err error) { + err = tx.Migrator().DropTable("solutions") + if err != nil { + return + } + return + }, + }, { // add default problem role ID: "add_default_problem_role", diff --git a/database/models/solution.go b/database/models/solution.go index 7c657339..4343d78e 100644 --- a/database/models/solution.go +++ b/database/models/solution.go @@ -7,9 +7,13 @@ import ( ) type Solution struct { - ID uint `gorm:"primaryKey" json:"id"` - Name string `sql:"index" json:"name" gorm:"size:255;default:'';not null"` + ID uint `gorm:"primaryKey" json:"id"` + + ProblemID uint `json:"problem_id"` + Name string `sql:"index" json:"name"` + Author string `sql:"index" json:"auther"` Description string `json:"description"` + Likes uint `json:"likes"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"-"` @@ -20,6 +24,6 @@ func (s Solution) GetID() uint { return s.ID } -func (s Solution) TypeName() string { - return "solution" +func (s Solution) GetProblemID() uint { + return s.ProblemID } diff --git a/database/models/solution_comment.go b/database/models/solution_comment.go new file mode 100644 index 00000000..b127d7f7 --- /dev/null +++ b/database/models/solution_comment.go @@ -0,0 +1,32 @@ +package models + +import ( + "time" + + "gorm.io/gorm" +) + +type SolutionComment struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +func (sc SolutionComment) GetID() uint { + return sc.ID +} + +func (sc SolutionComment) GetSolutionID() uint { + return sc.SolutionID +} + +func (sc SolutionComment) GetFatherNode() uint { + return sc.FatherNode +} From 3067ee9d3af26277c6a05876f6c0468961c1a0ba Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Thu, 20 Oct 2022 23:27:08 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=B1=BB=E5=9E=8B=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution.go | 2 +- app/request/solution.go | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/app/controller/solution.go b/app/controller/solution.go index cdfd63af..09de9fcb 100644 --- a/app/controller/solution.go +++ b/app/controller/solution.go @@ -44,7 +44,7 @@ func CreateSolution(c echo.Context) error { Name: req.Name, Author: req.Author, Description: req.Description, - Likes: req.Likes, + Likes: 0, } utils.PanicIfDBError(base.DB.Create(&solution), "could not create solution") diff --git a/app/request/solution.go b/app/request/solution.go index ce893a7b..f28d7468 100644 --- a/app/request/solution.go +++ b/app/request/solution.go @@ -1,24 +1,21 @@ package request type CreateSolutionRequest struct { - ProblemID uint `json:"problem_id" from:"problem_id" query:"problem_id" validate:"required"` + ProblemID uint `json:"problemID" form:"problemID" query:"problemID" validate:"required"` Name string `json:"name" form:"name" query:"name" validate:"required,max=255"` - Author string `json:"author" form:"suthor" query:"author" validate:"required"` + Author string `json:"author" form:"author" query:"author" validate:"required"` Description string `json:"description" form:"description" query:"description" validate:"required"` - // Public *bool `json:"public" form:"public" query:"public" validate:"required"` - Likes uint `json:"likes" from:"likes" querry:"likes" validate:"required"` } type GetSolutionRequest struct { } type UpdateSolutionRequest struct { - ProblemID uint `json:"problem_id" from:"problem_id" query:"problem_id" validate:"required"` + ProblemID uint `json:"problemID" form:"problemID" query:"problemID" validate:"required"` Name string `json:"name" form:"name" query:"name" validate:"required,max=255"` - Author string `json:"author" form:"suthor" query:"author" validate:"required"` + Author string `json:"author" form:"author" query:"author" validate:"required"` Description string `json:"description" form:"description" query:"description" validate:"required"` - // Public *bool `json:"public" form:"public" query:"public" validate:"required"` - Likes uint `json:"likes" from:"likes" querry:"likes" validate:"required"` + Likes uint `json:"likes" form:"likes" query:"likes" validate:"required"` } // type GetSolutionsRequest struct { From 51ce75d59f92ce5fbacc570c121f57703c8d0578 Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Fri, 21 Oct 2022 20:06:22 +0800 Subject: [PATCH 11/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E9=A2=98=E8=A7=A3?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution.go | 31 ++++++++++++++++++++----------- app/request/solution.go | 3 ++- app/response/resource/solution.go | 12 +++++++++++- app/response/solution.go | 12 ++---------- app/routes.go | 2 +- database/models/solution.go | 6 +++--- 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/app/controller/solution.go b/app/controller/solution.go index 09de9fcb..fb926875 100644 --- a/app/controller/solution.go +++ b/app/controller/solution.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "strconv" "github.com/EduOJ/backend/app/request" "github.com/EduOJ/backend/app/response" @@ -10,24 +11,33 @@ import ( "github.com/EduOJ/backend/base/utils" "github.com/EduOJ/backend/database/models" "github.com/labstack/echo/v4" - "github.com/pkg/errors" - "gorm.io/gorm" ) -func GetSolution(c echo.Context) error { - solution, err := utils.FindSolution(c.Param("id")) - if errors.Is(err, gorm.ErrRecordNotFound) { - return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) - } else if err != nil { +func GetSolutions(c echo.Context) error { + req := request.GetSolutionsRequest{} + if err, ok := utils.BindAndValidate(&req, c); !ok { + return err + } + + problemID, _ := strconv.ParseUint(req.ProblemID, 10, 64) + query := base.DB.Model(&models.Solution{}).Order("problem_id ASC").Where("problem_id = ?", problemID) + var solutions []*models.Solution + + err := query.Find(&solutions).Error + if err != nil { + if herr, ok := err.(utils.HttpError); ok { + return herr.Response(c) + } panic(err) } - return c.JSON(http.StatusOK, response.GetSolutionResponse{ + + return c.JSON(http.StatusOK, response.GetSolutionsResponse{ Message: "SUCCESS", Error: nil, Data: struct { - *resource.Solution `json:"solution"` + Solutions []resource.Solution `json:"solutions"` }{ - resource.GetSolution(solution), + Solutions: resource.GetSolutions(solutions), }, }) } @@ -57,5 +67,4 @@ func CreateSolution(c echo.Context) error { resource.GetSolution(&solution), }, }) - } diff --git a/app/request/solution.go b/app/request/solution.go index f28d7468..af58102e 100644 --- a/app/request/solution.go +++ b/app/request/solution.go @@ -7,7 +7,8 @@ type CreateSolutionRequest struct { Description string `json:"description" form:"description" query:"description" validate:"required"` } -type GetSolutionRequest struct { +type GetSolutionsRequest struct { + ProblemID string `json:"problemID" form:"problemID" query:"problemID" validate:"required"` } type UpdateSolutionRequest struct { diff --git a/app/response/resource/solution.go b/app/response/resource/solution.go index 40d6af0c..ec629a6d 100644 --- a/app/response/resource/solution.go +++ b/app/response/resource/solution.go @@ -1,6 +1,8 @@ package resource -import "github.com/EduOJ/backend/database/models" +import ( + "github.com/EduOJ/backend/database/models" +) type Solution struct { ID uint `json:"id"` @@ -26,3 +28,11 @@ func GetSolution(solution *models.Solution) *Solution { s.convert(solution) return &s } + +func GetSolutions(solutions []*models.Solution) (profiles []Solution) { + profiles = make([]Solution, len(solutions)) + for i, solution := range solutions { + profiles[i].convert(solution) + } + return +} diff --git a/app/response/solution.go b/app/response/solution.go index e103ffd2..d1641edf 100644 --- a/app/response/solution.go +++ b/app/response/solution.go @@ -4,14 +4,6 @@ import ( "github.com/EduOJ/backend/app/response/resource" ) -type GetSolutionResponse struct { - Message string `json:"message"` - Error interface{} `json:"error"` - Data struct { - *resource.Solution `json:"solution"` - } `json:"data"` -} - type CreateSolutionResponse struct { Message string `json:"message"` Error interface{} `json:"error"` @@ -20,10 +12,10 @@ type CreateSolutionResponse struct { } `json:"data"` } -type UpdateSolutionResponse struct { +type GetSolutionsResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.Solution `json:"solution"` + Solutions []resource.Solution `json:"solutions"` } `json:"data"` } diff --git a/app/routes.go b/app/routes.go index 1a8db446..ac3648c0 100644 --- a/app/routes.go +++ b/app/routes.go @@ -177,7 +177,7 @@ func Register(e *echo.Echo) { middleware.Logged, middleware.EmailVerified, middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution"}), ).Name = "solution.createSolution" - solution.GET("/solution/:id", controller.GetSolution).Name = "solution.getSolution" + solution.GET("/solutions", controller.GetSolutions).Name = "solution.getSolutions" // log API api.GET("/admin/logs", controller.AdminGetLogs, diff --git a/database/models/solution.go b/database/models/solution.go index 4343d78e..f10d2bad 100644 --- a/database/models/solution.go +++ b/database/models/solution.go @@ -9,9 +9,9 @@ import ( type Solution struct { ID uint `gorm:"primaryKey" json:"id"` - ProblemID uint `json:"problem_id"` - Name string `sql:"index" json:"name"` - Author string `sql:"index" json:"auther"` + ProblemID uint `sql:"index" json:"problem_id"` + Name string `json:"name"` + Author string `json:"auther"` Description string `json:"description"` Likes uint `json:"likes"` From 5a0691dd6e383ac0dfc5cdd71f748d48ff8eebc1 Mon Sep 17 00:00:00 2001 From: Invariant64 <1319438556@qq.com> Date: Mon, 24 Oct 2022 16:17:31 +0800 Subject: [PATCH 12/21] =?UTF-8?q?=E9=A2=98=E8=A7=A3=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E7=9A=84=E5=88=9B=E5=BB=BA=E4=B8=8E=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution_comment.go | 60 ++++++++++++++++++ app/controller/solution_comment_tree.go | 36 +++++++++++ app/response/resource/solution_comment.go | 8 +++ .../resource/solution_comment_node.go | 34 ++++++++++ .../resource/solution_comment_tree.go | 20 ++++++ app/response/solution_comment.go | 14 +++- app/response/solution_comment_tree.go | 11 ++++ base/utils/query_helper.go | 14 ++++ database.db | Bin 180224 -> 188416 bytes database/models/solution_comment_node.go | 22 +++++++ database/models/solution_comment_tree.go | 15 +++++ 11 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 app/controller/solution_comment.go create mode 100644 app/controller/solution_comment_tree.go create mode 100644 app/response/resource/solution_comment_node.go create mode 100644 app/response/resource/solution_comment_tree.go create mode 100644 app/response/solution_comment_tree.go create mode 100644 database/models/solution_comment_node.go create mode 100644 database/models/solution_comment_tree.go diff --git a/app/controller/solution_comment.go b/app/controller/solution_comment.go new file mode 100644 index 00000000..ee902685 --- /dev/null +++ b/app/controller/solution_comment.go @@ -0,0 +1,60 @@ +package controller + +import ( + "net/http" + + "github.com/EduOJ/backend/app/request" + "github.com/EduOJ/backend/app/response" + "github.com/EduOJ/backend/app/response/resource" + "github.com/EduOJ/backend/base" + "github.com/EduOJ/backend/base/utils" + "github.com/EduOJ/backend/database/models" + "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "gorm.io/gorm" +) + +func GetSolutionComments(c echo.Context) error { + sc, err := utils.FindSolutionComments(c.Param("id")) + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else if err != nil { + panic(err) + } + return c.JSON(http.StatusOK, response.GetSolutionCommentsResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + SolutionComments []resource.SolutionComment `json:"solution_comments"` + }{ + resource.GetSolutionComments(sc), + }, + }) +} + +func CreateSolutions(c echo.Context) error { + req := request.CreateSolutionCommentRequest{} + err, ok := utils.BindAndValidate(&req, c) + if !ok { + return err + } + + comment := models.SolutionComment{ + SolutionID: req.SolutionID, + FatherNode: req.FatherNode, + Description: req.Description, + Speaker: req.Speaker, + } + utils.PanicIfDBError(base.DB.Create(&comment), "could not create comment") + + return c.JSON(http.StatusOK, response.CreateSolutionCommentResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + *resource.SolutionComment `json:"solution_comment"` + }{ + resource.GetSolutionComment(&comment), + }, + }) + +} diff --git a/app/controller/solution_comment_tree.go b/app/controller/solution_comment_tree.go new file mode 100644 index 00000000..9e37b655 --- /dev/null +++ b/app/controller/solution_comment_tree.go @@ -0,0 +1,36 @@ +package controller + +import ( + "net/http" + + "github.com/EduOJ/backend/app/response" + "github.com/EduOJ/backend/app/response/resource" + "github.com/EduOJ/backend/base/utils" + "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "gorm.io/gorm" +) + +func GetCommentTree(c echo.Context) error { + solutionComments, err := utils.FindSolutionComments(c.Param("solution_id")) + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else if err != nil { + panic(err) + } + + commentNodes := make([]resource.SolutionCommentNode, len(solutionComments)) + for i, solutionComment := range solutionComments { + commentNodes[i].ConvertCommentToNode(&solutionComment) + } + + return c.JSON(http.StatusOK, response.GetCommentTreeResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + *resource.SolutionCommentTree `json:"solution_comment_tree"` + }{ + resource.GetSolutionCommentTree(commentNodes), + }, + }) +} diff --git a/app/response/resource/solution_comment.go b/app/response/resource/solution_comment.go index f9b679ef..69483e31 100644 --- a/app/response/resource/solution_comment.go +++ b/app/response/resource/solution_comment.go @@ -25,3 +25,11 @@ func GetSolutionComment(solutionComment *models.SolutionComment) *SolutionCommen sc.convert(solutionComment) return &sc } + +func GetSolutionComments(solutionComments []models.SolutionComment) []SolutionComment { + scs := make([]SolutionComment, 0) + for _, sc := range solutionComments { + scs = append(scs, *GetSolutionComment(&sc)) + } + return scs +} diff --git a/app/response/resource/solution_comment_node.go b/app/response/resource/solution_comment_node.go new file mode 100644 index 00000000..59e5a610 --- /dev/null +++ b/app/response/resource/solution_comment_node.go @@ -0,0 +1,34 @@ +package resource + +import ( + "github.com/EduOJ/backend/database/models" +) + +type SolutionCommentNode struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` + + Kids []SolutionCommentNode `json:"kids"` +} + +func (cn *SolutionCommentNode) ConvertCommentToNode(solutionComment *models.SolutionComment) { + cn.ID = solutionComment.ID + cn.SolutionID = solutionComment.SolutionID + cn.FatherNode = solutionComment.FatherNode + cn.Description = solutionComment.Description + cn.Speaker = solutionComment.Speaker + cn.Kids = make([]SolutionCommentNode, 0) +} + +func (commentNode *SolutionCommentNode) GetKids(commentNodes []SolutionCommentNode) { + for _, cn := range commentNodes { + if cn.FatherNode == commentNode.FatherNode { + cn.GetKids(commentNodes) + commentNode.Kids = append(commentNode.Kids, cn) + } + } +} diff --git a/app/response/resource/solution_comment_tree.go b/app/response/resource/solution_comment_tree.go new file mode 100644 index 00000000..0f421fd3 --- /dev/null +++ b/app/response/resource/solution_comment_tree.go @@ -0,0 +1,20 @@ +package resource + +type SolutionCommentTree struct { + Roots []SolutionCommentNode `json:"roots"` +} + +func (t *SolutionCommentTree) BuildTree(commentNodes []SolutionCommentNode) { + for _, commentNode := range commentNodes { + if commentNode.FatherNode == 0 { + commentNode.GetKids(commentNodes) + t.Roots = append(t.Roots, commentNode) + } + } +} + +func GetSolutionCommentTree(commentNodes []SolutionCommentNode) *SolutionCommentTree { + sct := SolutionCommentTree{} + sct.BuildTree(commentNodes) + return &sct +} diff --git a/app/response/solution_comment.go b/app/response/solution_comment.go index fef79ff5..a621652d 100644 --- a/app/response/solution_comment.go +++ b/app/response/solution_comment.go @@ -6,7 +6,7 @@ type GetSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution"` + *resource.SolutionComment `json:"solution_comment"` } `json:"data"` } @@ -14,7 +14,7 @@ type CreateSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution"` + *resource.SolutionComment `json:"solution_comment"` } `json:"data"` } @@ -22,6 +22,14 @@ type UpdateSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solutiong_comment"` + *resource.SolutionComment `json:"solution_comment"` + } `json:"data"` +} + +type GetSolutionCommentsResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + SolutionComments []resource.SolutionComment `json:"solution_comments"` } `json:"data"` } diff --git a/app/response/solution_comment_tree.go b/app/response/solution_comment_tree.go new file mode 100644 index 00000000..c094cb20 --- /dev/null +++ b/app/response/solution_comment_tree.go @@ -0,0 +1,11 @@ +package response + +import "github.com/EduOJ/backend/app/response/resource" + +type GetCommentTreeResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.SolutionCommentTree `json:"solution_comment_tree"` + } `json:"data"` +} diff --git a/base/utils/query_helper.go b/base/utils/query_helper.go index 95df35d1..ebc11977 100644 --- a/base/utils/query_helper.go +++ b/base/utils/query_helper.go @@ -152,6 +152,20 @@ func FindSolution(id string) (*models.Solution, error) { return &solution, nil } +func FindSolutionComments(solutionID string) ([]models.SolutionComment, error) { + sc := []models.SolutionComment{} + query := base.DB + err := query.Where("SolutionID = ?", solutionID).Find(&sc).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, err + } else { + return nil, errors.Wrap(err, "could not query solution comment") + } + } + return sc, nil +} + // This function checks if the user has permission to get problems which are not public. // nil user pointer is regarded as admin(skip the permission judgement). func FindTestCase(problemId string, testCaseIdStr string, user *models.User) (*models.TestCase, *models.Problem, error) { diff --git a/database.db b/database.db index 05c2c143c5b28b55c7286919d6b71719134cf3c5..2c464d98762759470413fde54d7bf62f29b90622 100644 GIT binary patch delta 2675 zcmeH}O>7%Q7>0NJlQ^**C!r8kEzOd)B&n0>%&Zaue4Xe|#Cm&zgP;W)sJ}4sMX)QZmH>%+&O$J8 z&+bB855Ea} zT)0vy=k?W6RbMQvt>#y9#Z{OuWeVk$Vx^)QZeeB;M98RLnHUzO5D94-NbWD58B~?W zPS1txy@}BSnS@waKq-(Zx#@29S%0%cSCtsEnA2It4D1%mp7b}{f)K_{>~8jiv)RT% zEeK{@y8Xx;_ZzPeY#GEt98x4PM(zxA1D+PNKV@n$3JGRN7_QvxGoF@KgfdRO#_Nuj z6RJIrMCSS%?U}WIWY9S*E{H75p%932;kNOZ(k$w|{O1nm;Euv;sjpHXlmUlo;Y~0c zh<~?-HUSHR(;GOn}_Cw#{!(hX#6}LgAcKc({TYK?SP?B%1B-{J?`@zO=HTTML z!M{BIk5khZ)05e>o}HY!kk%Kx|7)Aqz{%SE4G`-ZS;(zbmrCUYy;`_ht);fWli}s! ztA&c4YU6fy^r_mNEpTY>n{9CJZY=Ixux{r|8?N_U|246d34eY)pntd<3PNqiZb##f z@7?2j_rJe)zju(n$Ym|Dow$%_>)P#_jo**oh(8yP#Okq3^v~$m(JN7{^JeE#XK%-? zj+Z+6BHu;#aM#$TePe5`f=pG# zwWQ3HZ)^>OsyL#MG0ur(uE|ceY9ZWW0&>JC@j@q?YSrQ))WpOc)67JxmcKzVXPdPs zH>VaQkTb-v@X~F(SxW;k2t-`v2k}hyOtY3Igb3_u8S_lmX`PQSQ>b*>-}Ic-YO+2^ z7&Hi`%=PP>=?hY>Pn=*-u8$F+n7I9$mrne9v3`Ic;m=7pdc3r4B2)so>s;hYk5Fk_ zE-e@SP0n)GoU>R3uSE!yrWB@kf-W&t^B}?J|67DNN@D|ZZc65*?i_ufeX2R?S%q1K zgp4yodh;}z+t(n7goLRC=U#vlf1X~E2ay@I NO&{@}Odftr`wNS)gLnV{ delta 318 zcmZoTz}?WmJwaMfoPmKs2Z*(Rm=TDLC+Zk8if>FEU|;|M diff --git a/database/models/solution_comment_node.go b/database/models/solution_comment_node.go new file mode 100644 index 00000000..b55651cc --- /dev/null +++ b/database/models/solution_comment_node.go @@ -0,0 +1,22 @@ +package models + +import ( + "time" + + "gorm.io/gorm" +) + +type SolutionCommentNode struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` + + Kids []SolutionCommentNode `json:"kids"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} diff --git a/database/models/solution_comment_tree.go b/database/models/solution_comment_tree.go new file mode 100644 index 00000000..a07c4afc --- /dev/null +++ b/database/models/solution_comment_tree.go @@ -0,0 +1,15 @@ +package models + +import ( + "time" + + "gorm.io/gorm" +) + +type SolutionCommentTree struct { + Roots []SolutionCommentNode `json:"roots"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} From 6ff50ae0aee1d19ea10110401ab0b3f997195a8d Mon Sep 17 00:00:00 2001 From: Invariant64 <1319438556@qq.com> Date: Tue, 25 Oct 2022 19:47:47 +0800 Subject: [PATCH 13/21] =?UTF-8?q?=E9=A2=98=E8=A7=A3=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E7=9A=84=E5=88=9B=E5=BB=BA=E4=B8=8E=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution_comment.go | 44 ++++++++++++++++++++---- app/controller/solution_comment_tree.go | 36 ------------------- app/response/solution_comment.go | 8 +++++ app/response/solution_comment_tree.go | 11 ------ base/utils/query_helper.go | 14 -------- database/models/solution_comment.go | 23 +++++++++++++ database/models/solution_comment_node.go | 22 ------------ database/models/solution_comment_tree.go | 15 -------- 8 files changed, 69 insertions(+), 104 deletions(-) delete mode 100644 app/controller/solution_comment_tree.go delete mode 100644 app/response/solution_comment_tree.go delete mode 100644 database/models/solution_comment_node.go delete mode 100644 database/models/solution_comment_tree.go diff --git a/app/controller/solution_comment.go b/app/controller/solution_comment.go index ee902685..3e5911b0 100644 --- a/app/controller/solution_comment.go +++ b/app/controller/solution_comment.go @@ -15,12 +15,17 @@ import ( ) func GetSolutionComments(c echo.Context) error { - sc, err := utils.FindSolutionComments(c.Param("id")) - if errors.Is(err, gorm.ErrRecordNotFound) { - return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) - } else if err != nil { - panic(err) + sc := []models.SolutionComment{} + query := base.DB + err := query.Where("SolutionID = ?", c.Param("id")).Find(&sc).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else { + panic(errors.Wrap(err, "could not query solution comment")) + } } + return c.JSON(http.StatusOK, response.GetSolutionCommentsResponse{ Message: "SUCCESS", Error: nil, @@ -32,7 +37,7 @@ func GetSolutionComments(c echo.Context) error { }) } -func CreateSolutions(c echo.Context) error { +func CreateSolutionComment(c echo.Context) error { req := request.CreateSolutionCommentRequest{} err, ok := utils.BindAndValidate(&req, c) if !ok { @@ -56,5 +61,32 @@ func CreateSolutions(c echo.Context) error { resource.GetSolutionComment(&comment), }, }) +} + +func GetCommentTree(c echo.Context) error { + solutionComments := []models.SolutionComment{} + query := base.DB + err := query.Where("SolutionID = ?", c.Param("id")).Find(&solutionComments).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else { + panic(errors.Wrap(err, "could not query solution comment")) + } + } + + commentNodes := make([]resource.SolutionCommentNode, len(solutionComments)) + for i, solutionComment := range solutionComments { + commentNodes[i].ConvertCommentToNode(&solutionComment) + } + return c.JSON(http.StatusOK, response.GetCommentTreeResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + *resource.SolutionCommentTree `json:"solution_comment_tree"` + }{ + resource.GetSolutionCommentTree(commentNodes), + }, + }) } diff --git a/app/controller/solution_comment_tree.go b/app/controller/solution_comment_tree.go deleted file mode 100644 index 9e37b655..00000000 --- a/app/controller/solution_comment_tree.go +++ /dev/null @@ -1,36 +0,0 @@ -package controller - -import ( - "net/http" - - "github.com/EduOJ/backend/app/response" - "github.com/EduOJ/backend/app/response/resource" - "github.com/EduOJ/backend/base/utils" - "github.com/labstack/echo/v4" - "github.com/pkg/errors" - "gorm.io/gorm" -) - -func GetCommentTree(c echo.Context) error { - solutionComments, err := utils.FindSolutionComments(c.Param("solution_id")) - if errors.Is(err, gorm.ErrRecordNotFound) { - return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) - } else if err != nil { - panic(err) - } - - commentNodes := make([]resource.SolutionCommentNode, len(solutionComments)) - for i, solutionComment := range solutionComments { - commentNodes[i].ConvertCommentToNode(&solutionComment) - } - - return c.JSON(http.StatusOK, response.GetCommentTreeResponse{ - Message: "SUCCESS", - Error: nil, - Data: struct { - *resource.SolutionCommentTree `json:"solution_comment_tree"` - }{ - resource.GetSolutionCommentTree(commentNodes), - }, - }) -} diff --git a/app/response/solution_comment.go b/app/response/solution_comment.go index a621652d..13cee372 100644 --- a/app/response/solution_comment.go +++ b/app/response/solution_comment.go @@ -33,3 +33,11 @@ type GetSolutionCommentsResponse struct { SolutionComments []resource.SolutionComment `json:"solution_comments"` } `json:"data"` } + +type GetCommentTreeResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.SolutionCommentTree `json:"solution_comment_tree"` + } `json:"data"` +} diff --git a/app/response/solution_comment_tree.go b/app/response/solution_comment_tree.go deleted file mode 100644 index c094cb20..00000000 --- a/app/response/solution_comment_tree.go +++ /dev/null @@ -1,11 +0,0 @@ -package response - -import "github.com/EduOJ/backend/app/response/resource" - -type GetCommentTreeResponse struct { - Message string `json:"message"` - Error interface{} `json:"error"` - Data struct { - *resource.SolutionCommentTree `json:"solution_comment_tree"` - } `json:"data"` -} diff --git a/base/utils/query_helper.go b/base/utils/query_helper.go index ebc11977..95df35d1 100644 --- a/base/utils/query_helper.go +++ b/base/utils/query_helper.go @@ -152,20 +152,6 @@ func FindSolution(id string) (*models.Solution, error) { return &solution, nil } -func FindSolutionComments(solutionID string) ([]models.SolutionComment, error) { - sc := []models.SolutionComment{} - query := base.DB - err := query.Where("SolutionID = ?", solutionID).Find(&sc).Error - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, err - } else { - return nil, errors.Wrap(err, "could not query solution comment") - } - } - return sc, nil -} - // This function checks if the user has permission to get problems which are not public. // nil user pointer is regarded as admin(skip the permission judgement). func FindTestCase(problemId string, testCaseIdStr string, user *models.User) (*models.TestCase, *models.Problem, error) { diff --git a/database/models/solution_comment.go b/database/models/solution_comment.go index b127d7f7..4ed5a073 100644 --- a/database/models/solution_comment.go +++ b/database/models/solution_comment.go @@ -19,6 +19,29 @@ type SolutionComment struct { DeletedAt gorm.DeletedAt `json:"deleted_at"` } +type SolutionCommentNode struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` + + Kids []SolutionCommentNode `json:"kids"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +type SolutionCommentTree struct { + Roots []SolutionCommentNode `json:"roots"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + func (sc SolutionComment) GetID() uint { return sc.ID } diff --git a/database/models/solution_comment_node.go b/database/models/solution_comment_node.go deleted file mode 100644 index b55651cc..00000000 --- a/database/models/solution_comment_node.go +++ /dev/null @@ -1,22 +0,0 @@ -package models - -import ( - "time" - - "gorm.io/gorm" -) - -type SolutionCommentNode struct { - ID uint `gorm:"primaryKey" json:"id"` - - SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` - FatherNode uint `json:"father_node" gorm:"not null"` - Description string `json:"description"` - Speaker string `json:"speaker"` - - Kids []SolutionCommentNode `json:"kids"` - - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"-"` - DeletedAt gorm.DeletedAt `json:"deleted_at"` -} diff --git a/database/models/solution_comment_tree.go b/database/models/solution_comment_tree.go deleted file mode 100644 index a07c4afc..00000000 --- a/database/models/solution_comment_tree.go +++ /dev/null @@ -1,15 +0,0 @@ -package models - -import ( - "time" - - "gorm.io/gorm" -) - -type SolutionCommentTree struct { - Roots []SolutionCommentNode `json:"roots"` - - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"-"` - DeletedAt gorm.DeletedAt `json:"deleted_at"` -} From cb155db9496ef0e642d20ab7cb8573b3a0d51681 Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Fri, 28 Oct 2022 17:42:23 +0800 Subject: [PATCH 14/21] =?UTF-8?q?Revert=20"=E9=A2=98=E8=A7=A3=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E7=9A=84=E5=88=9B=E5=BB=BA=E4=B8=8E=E8=8E=B7=E5=8F=96?= =?UTF-8?q?"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5a0691dd6e383ac0dfc5cdd71f748d48ff8eebc1. --- app/controller/solution_comment.go | 60 ------------------ app/controller/solution_comment_tree.go | 36 ----------- app/response/resource/solution_comment.go | 8 --- .../resource/solution_comment_node.go | 34 ---------- .../resource/solution_comment_tree.go | 20 ------ app/response/solution_comment.go | 14 +--- app/response/solution_comment_tree.go | 11 ---- base/utils/query_helper.go | 14 ---- database.db | Bin 188416 -> 180224 bytes database/models/solution_comment_node.go | 22 ------- database/models/solution_comment_tree.go | 15 ----- 11 files changed, 3 insertions(+), 231 deletions(-) delete mode 100644 app/controller/solution_comment.go delete mode 100644 app/controller/solution_comment_tree.go delete mode 100644 app/response/resource/solution_comment_node.go delete mode 100644 app/response/resource/solution_comment_tree.go delete mode 100644 app/response/solution_comment_tree.go delete mode 100644 database/models/solution_comment_node.go delete mode 100644 database/models/solution_comment_tree.go diff --git a/app/controller/solution_comment.go b/app/controller/solution_comment.go deleted file mode 100644 index ee902685..00000000 --- a/app/controller/solution_comment.go +++ /dev/null @@ -1,60 +0,0 @@ -package controller - -import ( - "net/http" - - "github.com/EduOJ/backend/app/request" - "github.com/EduOJ/backend/app/response" - "github.com/EduOJ/backend/app/response/resource" - "github.com/EduOJ/backend/base" - "github.com/EduOJ/backend/base/utils" - "github.com/EduOJ/backend/database/models" - "github.com/labstack/echo/v4" - "github.com/pkg/errors" - "gorm.io/gorm" -) - -func GetSolutionComments(c echo.Context) error { - sc, err := utils.FindSolutionComments(c.Param("id")) - if errors.Is(err, gorm.ErrRecordNotFound) { - return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) - } else if err != nil { - panic(err) - } - return c.JSON(http.StatusOK, response.GetSolutionCommentsResponse{ - Message: "SUCCESS", - Error: nil, - Data: struct { - SolutionComments []resource.SolutionComment `json:"solution_comments"` - }{ - resource.GetSolutionComments(sc), - }, - }) -} - -func CreateSolutions(c echo.Context) error { - req := request.CreateSolutionCommentRequest{} - err, ok := utils.BindAndValidate(&req, c) - if !ok { - return err - } - - comment := models.SolutionComment{ - SolutionID: req.SolutionID, - FatherNode: req.FatherNode, - Description: req.Description, - Speaker: req.Speaker, - } - utils.PanicIfDBError(base.DB.Create(&comment), "could not create comment") - - return c.JSON(http.StatusOK, response.CreateSolutionCommentResponse{ - Message: "SUCCESS", - Error: nil, - Data: struct { - *resource.SolutionComment `json:"solution_comment"` - }{ - resource.GetSolutionComment(&comment), - }, - }) - -} diff --git a/app/controller/solution_comment_tree.go b/app/controller/solution_comment_tree.go deleted file mode 100644 index 9e37b655..00000000 --- a/app/controller/solution_comment_tree.go +++ /dev/null @@ -1,36 +0,0 @@ -package controller - -import ( - "net/http" - - "github.com/EduOJ/backend/app/response" - "github.com/EduOJ/backend/app/response/resource" - "github.com/EduOJ/backend/base/utils" - "github.com/labstack/echo/v4" - "github.com/pkg/errors" - "gorm.io/gorm" -) - -func GetCommentTree(c echo.Context) error { - solutionComments, err := utils.FindSolutionComments(c.Param("solution_id")) - if errors.Is(err, gorm.ErrRecordNotFound) { - return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) - } else if err != nil { - panic(err) - } - - commentNodes := make([]resource.SolutionCommentNode, len(solutionComments)) - for i, solutionComment := range solutionComments { - commentNodes[i].ConvertCommentToNode(&solutionComment) - } - - return c.JSON(http.StatusOK, response.GetCommentTreeResponse{ - Message: "SUCCESS", - Error: nil, - Data: struct { - *resource.SolutionCommentTree `json:"solution_comment_tree"` - }{ - resource.GetSolutionCommentTree(commentNodes), - }, - }) -} diff --git a/app/response/resource/solution_comment.go b/app/response/resource/solution_comment.go index 69483e31..f9b679ef 100644 --- a/app/response/resource/solution_comment.go +++ b/app/response/resource/solution_comment.go @@ -25,11 +25,3 @@ func GetSolutionComment(solutionComment *models.SolutionComment) *SolutionCommen sc.convert(solutionComment) return &sc } - -func GetSolutionComments(solutionComments []models.SolutionComment) []SolutionComment { - scs := make([]SolutionComment, 0) - for _, sc := range solutionComments { - scs = append(scs, *GetSolutionComment(&sc)) - } - return scs -} diff --git a/app/response/resource/solution_comment_node.go b/app/response/resource/solution_comment_node.go deleted file mode 100644 index 59e5a610..00000000 --- a/app/response/resource/solution_comment_node.go +++ /dev/null @@ -1,34 +0,0 @@ -package resource - -import ( - "github.com/EduOJ/backend/database/models" -) - -type SolutionCommentNode struct { - ID uint `gorm:"primaryKey" json:"id"` - - SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` - FatherNode uint `json:"father_node" gorm:"not null"` - Description string `json:"description"` - Speaker string `json:"speaker"` - - Kids []SolutionCommentNode `json:"kids"` -} - -func (cn *SolutionCommentNode) ConvertCommentToNode(solutionComment *models.SolutionComment) { - cn.ID = solutionComment.ID - cn.SolutionID = solutionComment.SolutionID - cn.FatherNode = solutionComment.FatherNode - cn.Description = solutionComment.Description - cn.Speaker = solutionComment.Speaker - cn.Kids = make([]SolutionCommentNode, 0) -} - -func (commentNode *SolutionCommentNode) GetKids(commentNodes []SolutionCommentNode) { - for _, cn := range commentNodes { - if cn.FatherNode == commentNode.FatherNode { - cn.GetKids(commentNodes) - commentNode.Kids = append(commentNode.Kids, cn) - } - } -} diff --git a/app/response/resource/solution_comment_tree.go b/app/response/resource/solution_comment_tree.go deleted file mode 100644 index 0f421fd3..00000000 --- a/app/response/resource/solution_comment_tree.go +++ /dev/null @@ -1,20 +0,0 @@ -package resource - -type SolutionCommentTree struct { - Roots []SolutionCommentNode `json:"roots"` -} - -func (t *SolutionCommentTree) BuildTree(commentNodes []SolutionCommentNode) { - for _, commentNode := range commentNodes { - if commentNode.FatherNode == 0 { - commentNode.GetKids(commentNodes) - t.Roots = append(t.Roots, commentNode) - } - } -} - -func GetSolutionCommentTree(commentNodes []SolutionCommentNode) *SolutionCommentTree { - sct := SolutionCommentTree{} - sct.BuildTree(commentNodes) - return &sct -} diff --git a/app/response/solution_comment.go b/app/response/solution_comment.go index a621652d..fef79ff5 100644 --- a/app/response/solution_comment.go +++ b/app/response/solution_comment.go @@ -6,7 +6,7 @@ type GetSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution_comment"` + *resource.SolutionComment `json:"solution"` } `json:"data"` } @@ -14,7 +14,7 @@ type CreateSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution_comment"` + *resource.SolutionComment `json:"solution"` } `json:"data"` } @@ -22,14 +22,6 @@ type UpdateSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution_comment"` - } `json:"data"` -} - -type GetSolutionCommentsResponse struct { - Message string `json:"message"` - Error interface{} `json:"error"` - Data struct { - SolutionComments []resource.SolutionComment `json:"solution_comments"` + *resource.SolutionComment `json:"solutiong_comment"` } `json:"data"` } diff --git a/app/response/solution_comment_tree.go b/app/response/solution_comment_tree.go deleted file mode 100644 index c094cb20..00000000 --- a/app/response/solution_comment_tree.go +++ /dev/null @@ -1,11 +0,0 @@ -package response - -import "github.com/EduOJ/backend/app/response/resource" - -type GetCommentTreeResponse struct { - Message string `json:"message"` - Error interface{} `json:"error"` - Data struct { - *resource.SolutionCommentTree `json:"solution_comment_tree"` - } `json:"data"` -} diff --git a/base/utils/query_helper.go b/base/utils/query_helper.go index ebc11977..95df35d1 100644 --- a/base/utils/query_helper.go +++ b/base/utils/query_helper.go @@ -152,20 +152,6 @@ func FindSolution(id string) (*models.Solution, error) { return &solution, nil } -func FindSolutionComments(solutionID string) ([]models.SolutionComment, error) { - sc := []models.SolutionComment{} - query := base.DB - err := query.Where("SolutionID = ?", solutionID).Find(&sc).Error - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, err - } else { - return nil, errors.Wrap(err, "could not query solution comment") - } - } - return sc, nil -} - // This function checks if the user has permission to get problems which are not public. // nil user pointer is regarded as admin(skip the permission judgement). func FindTestCase(problemId string, testCaseIdStr string, user *models.User) (*models.TestCase, *models.Problem, error) { diff --git a/database.db b/database.db index 2c464d98762759470413fde54d7bf62f29b90622..05c2c143c5b28b55c7286919d6b71719134cf3c5 100644 GIT binary patch delta 318 zcmZoTz}?WmJwaMfoPmKs2Z*(Rm=TDLC+Zk8if>FEU|;|M delta 2675 zcmeH}O>7%Q7>0NJlQ^**C!r8kEzOd)B&n0>%&Zaue4Xe|#Cm&zgP;W)sJ}4sMX)QZmH>%+&O$J8 z&+bB855Ea} zT)0vy=k?W6RbMQvt>#y9#Z{OuWeVk$Vx^)QZeeB;M98RLnHUzO5D94-NbWD58B~?W zPS1txy@}BSnS@waKq-(Zx#@29S%0%cSCtsEnA2It4D1%mp7b}{f)K_{>~8jiv)RT% zEeK{@y8Xx;_ZzPeY#GEt98x4PM(zxA1D+PNKV@n$3JGRN7_QvxGoF@KgfdRO#_Nuj z6RJIrMCSS%?U}WIWY9S*E{H75p%932;kNOZ(k$w|{O1nm;Euv;sjpHXlmUlo;Y~0c zh<~?-HUSHR(;GOn}_Cw#{!(hX#6}LgAcKc({TYK?SP?B%1B-{J?`@zO=HTTML z!M{BIk5khZ)05e>o}HY!kk%Kx|7)Aqz{%SE4G`-ZS;(zbmrCUYy;`_ht);fWli}s! ztA&c4YU6fy^r_mNEpTY>n{9CJZY=Ixux{r|8?N_U|246d34eY)pntd<3PNqiZb##f z@7?2j_rJe)zju(n$Ym|Dow$%_>)P#_jo**oh(8yP#Okq3^v~$m(JN7{^JeE#XK%-? zj+Z+6BHu;#aM#$TePe5`f=pG# zwWQ3HZ)^>OsyL#MG0ur(uE|ceY9ZWW0&>JC@j@q?YSrQ))WpOc)67JxmcKzVXPdPs zH>VaQkTb-v@X~F(SxW;k2t-`v2k}hyOtY3Igb3_u8S_lmX`PQSQ>b*>-}Ic-YO+2^ z7&Hi`%=PP>=?hY>Pn=*-u8$F+n7I9$mrne9v3`Ic;m=7pdc3r4B2)so>s;hYk5Fk_ zE-e@SP0n)GoU>R3uSE!yrWB@kf-W&t^B}?J|67DNN@D|ZZc65*?i_ufeX2R?S%q1K zgp4yodh;}z+t(n7goLRC=U#vlf1X~E2ay@I NO&{@}Odftr`wNS)gLnV{ diff --git a/database/models/solution_comment_node.go b/database/models/solution_comment_node.go deleted file mode 100644 index b55651cc..00000000 --- a/database/models/solution_comment_node.go +++ /dev/null @@ -1,22 +0,0 @@ -package models - -import ( - "time" - - "gorm.io/gorm" -) - -type SolutionCommentNode struct { - ID uint `gorm:"primaryKey" json:"id"` - - SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` - FatherNode uint `json:"father_node" gorm:"not null"` - Description string `json:"description"` - Speaker string `json:"speaker"` - - Kids []SolutionCommentNode `json:"kids"` - - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"-"` - DeletedAt gorm.DeletedAt `json:"deleted_at"` -} diff --git a/database/models/solution_comment_tree.go b/database/models/solution_comment_tree.go deleted file mode 100644 index a07c4afc..00000000 --- a/database/models/solution_comment_tree.go +++ /dev/null @@ -1,15 +0,0 @@ -package models - -import ( - "time" - - "gorm.io/gorm" -) - -type SolutionCommentTree struct { - Roots []SolutionCommentNode `json:"roots"` - - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"-"` - DeletedAt gorm.DeletedAt `json:"deleted_at"` -} From 3c019fc6e36df18d5d75adeb07f13088ad3684dd Mon Sep 17 00:00:00 2001 From: Invariant64 <1319438556@qq.com> Date: Tue, 25 Oct 2022 19:47:47 +0800 Subject: [PATCH 15/21] =?UTF-8?q?=E9=A2=98=E8=A7=A3=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E7=9A=84=E5=88=9B=E5=BB=BA=E4=B8=8E=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/response/solution_comment.go | 8 ++++++++ database/models/solution_comment.go | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/app/response/solution_comment.go b/app/response/solution_comment.go index fef79ff5..ee6b7b13 100644 --- a/app/response/solution_comment.go +++ b/app/response/solution_comment.go @@ -25,3 +25,11 @@ type UpdateSolutionCommentResponse struct { *resource.SolutionComment `json:"solutiong_comment"` } `json:"data"` } + +type GetCommentTreeResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + *resource.SolutionCommentTree `json:"solution_comment_tree"` + } `json:"data"` +} diff --git a/database/models/solution_comment.go b/database/models/solution_comment.go index b127d7f7..4ed5a073 100644 --- a/database/models/solution_comment.go +++ b/database/models/solution_comment.go @@ -19,6 +19,29 @@ type SolutionComment struct { DeletedAt gorm.DeletedAt `json:"deleted_at"` } +type SolutionCommentNode struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` + + Kids []SolutionCommentNode `json:"kids"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +type SolutionCommentTree struct { + Roots []SolutionCommentNode `json:"roots"` + + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + func (sc SolutionComment) GetID() uint { return sc.ID } From 40a080e5ba2bb5d324b19e1b05a20f4e84558174 Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Sun, 30 Oct 2022 01:33:17 +0800 Subject: [PATCH 16/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=90=8E=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/soulution_comment.go | 90 ++++++++++++++++++++++ app/response/resource/solution_comment.go | 56 ++++++++++++++ app/response/solution_comment.go | 10 +-- database.db | Bin 180224 -> 208896 bytes database/migrate.go | 31 ++++++++ 5 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 app/controller/soulution_comment.go diff --git a/app/controller/soulution_comment.go b/app/controller/soulution_comment.go new file mode 100644 index 00000000..795d0afe --- /dev/null +++ b/app/controller/soulution_comment.go @@ -0,0 +1,90 @@ +package controller + +import ( + "net/http" + + "github.com/EduOJ/backend/app/request" + "github.com/EduOJ/backend/app/response" + "github.com/EduOJ/backend/app/response/resource" + "github.com/EduOJ/backend/base" + "github.com/EduOJ/backend/base/utils" + "github.com/EduOJ/backend/database/models" + "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "gorm.io/gorm" +) + +func GetSolutionComments(c echo.Context) error { + sc := []models.SolutionComment{} + query := base.DB + err := query.Where("SolutionID = ?", c.Param("id")).Find(&sc).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else { + panic(errors.Wrap(err, "could not query solution comment")) + } + } + + return c.JSON(http.StatusOK, response.GetSolutionCommentsResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + SolutionComments []resource.SolutionComment `json:"solution_comments"` + }{ + resource.GetSolutionComments(sc), + }, + }) +} + +func CreateSolutionComment(c echo.Context) error { + req := request.CreateSolutionCommentRequest{} + err, ok := utils.BindAndValidate(&req, c) + if !ok { + return err + } + comment := models.SolutionComment{ + SolutionID: req.SolutionID, + FatherNode: req.FatherNode, + Description: req.Description, + Speaker: req.Speaker, + } + utils.PanicIfDBError(base.DB.Create(&comment), "could not create comment") + return c.JSON(http.StatusOK, response.CreateSolutionCommentResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + *resource.SolutionComment `json:"solution_comment_create"` + }{ + resource.GetSolutionComment(&comment), + }, + }) +} + +func GetCommentTree(c echo.Context) error { + solutionComments := []models.SolutionComment{} + query := base.DB + err := query.Where("SolutionID = ?", c.Param("id")).Find(&solutionComments).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else { + panic(errors.Wrap(err, "could not query solution comment")) + } + } + + commentNodes := make([]resource.SolutionCommentNode, len(solutionComments)) + for i, solutionComment := range solutionComments { + commentNodes[i].ConvertCommentToNode(&solutionComment) + } + + return c.JSON(http.StatusOK, response.GetCommentTreeResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + *resource.SolutionCommentTree `json:"solution_comment_tree"` + }{ + resource.GetSolutionCommentTree(commentNodes), + }, + }) +} diff --git a/app/response/resource/solution_comment.go b/app/response/resource/solution_comment.go index f9b679ef..e79e4402 100644 --- a/app/response/resource/solution_comment.go +++ b/app/response/resource/solution_comment.go @@ -25,3 +25,59 @@ func GetSolutionComment(solutionComment *models.SolutionComment) *SolutionCommen sc.convert(solutionComment) return &sc } + +func GetSolutionComments(solutionComments []models.SolutionComment) []SolutionComment { + scs := make([]SolutionComment, 0) + for _, sc := range solutionComments { + scs = append(scs, *GetSolutionComment(&sc)) + } + return scs +} + +type SolutionCommentNode struct { + ID uint `gorm:"primaryKey" json:"id"` + + SolutionID uint `sql:"index" json:"solution_id" gorm:"not null"` + FatherNode uint `json:"father_node" gorm:"not null"` + Description string `json:"description"` + Speaker string `json:"speaker"` + + Kids []SolutionCommentNode `json:"kids"` +} + +func (cn *SolutionCommentNode) ConvertCommentToNode(solutionComment *models.SolutionComment) { + cn.ID = solutionComment.ID + cn.SolutionID = solutionComment.SolutionID + cn.FatherNode = solutionComment.FatherNode + cn.Description = solutionComment.Description + cn.Speaker = solutionComment.Speaker + cn.Kids = make([]SolutionCommentNode, 0) +} + +func (commentNode *SolutionCommentNode) GetKids(commentNodes []SolutionCommentNode) { + for _, cn := range commentNodes { + if cn.FatherNode == commentNode.FatherNode { + cn.GetKids(commentNodes) + commentNode.Kids = append(commentNode.Kids, cn) + } + } +} + +type SolutionCommentTree struct { + Roots []SolutionCommentNode `json:"roots"` +} + +func (t *SolutionCommentTree) BuildTree(commentNodes []SolutionCommentNode) { + for _, commentNode := range commentNodes { + if commentNode.FatherNode == 0 { + commentNode.GetKids(commentNodes) + t.Roots = append(t.Roots, commentNode) + } + } +} + +func GetSolutionCommentTree(commentNodes []SolutionCommentNode) *SolutionCommentTree { + sct := SolutionCommentTree{} + sct.BuildTree(commentNodes) + return &sct +} diff --git a/app/response/solution_comment.go b/app/response/solution_comment.go index d5c4662d..3032b263 100644 --- a/app/response/solution_comment.go +++ b/app/response/solution_comment.go @@ -6,7 +6,7 @@ type GetSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution"` + *resource.SolutionComment `json:"solution_comment"` } `json:"data"` } @@ -14,7 +14,7 @@ type CreateSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solution"` + *resource.SolutionComment `json:"solution_comment_create"` } `json:"data"` } @@ -22,15 +22,15 @@ type UpdateSolutionCommentResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionComment `json:"solutiong_comment"` + *resource.SolutionComment `json:"solution_comment"` } `json:"data"` } -type GetCommentTreeResponse struct { +type GetSolutionCommentsResponse struct { Message string `json:"message"` Error interface{} `json:"error"` Data struct { - *resource.SolutionCommentTree `json:"solution_comment_tree"` + SolutionComments []resource.SolutionComment `json:"solution_comments"` } `json:"data"` } diff --git a/database.db b/database.db index 05c2c143c5b28b55c7286919d6b71719134cf3c5..8bfe24610adb06f3de70f10278ba72bee3e75735 100644 GIT binary patch delta 12386 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 fK$<>l$-9e>urvaO@7gQOwcF0$ Date: Mon, 31 Oct 2022 23:54:36 +0800 Subject: [PATCH 17/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AF=B7=E6=B1=82=E4=BF=AE=E5=A4=8D=E5=AE=8C?= =?UTF-8?q?=E5=96=84=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/soulution_comment.go | 12 ++++++++++-- app/request/solution_comment.go | 17 +++++++++-------- app/routes.go | 12 ++++++++++++ database.db | Bin 208896 -> 217088 bytes 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/controller/soulution_comment.go b/app/controller/soulution_comment.go index 795d0afe..3965ec8d 100644 --- a/app/controller/soulution_comment.go +++ b/app/controller/soulution_comment.go @@ -1,6 +1,7 @@ package controller import ( + "fmt" "net/http" "github.com/EduOJ/backend/app/request" @@ -17,7 +18,7 @@ import ( func GetSolutionComments(c echo.Context) error { sc := []models.SolutionComment{} query := base.DB - err := query.Where("SolutionID = ?", c.Param("id")).Find(&sc).Error + err := query.Where("solution_id = ?", c.Param("solutionId")).Find(&sc).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) @@ -43,9 +44,16 @@ func CreateSolutionComment(c echo.Context) error { if !ok { return err } + var FatherNode uint + if req.IsRoot { + FatherNode = 0 + } else { + FatherNode = req.FatherNode + } + fmt.Println("aaaaaaaaaaaaaaaaaaaaaa") comment := models.SolutionComment{ SolutionID: req.SolutionID, - FatherNode: req.FatherNode, + FatherNode: FatherNode, Description: req.Description, Speaker: req.Speaker, } diff --git a/app/request/solution_comment.go b/app/request/solution_comment.go index 10afa144..eed4949d 100644 --- a/app/request/solution_comment.go +++ b/app/request/solution_comment.go @@ -1,15 +1,16 @@ package request type CreateSolutionCommentRequest struct { - SolutionID uint `json:"solution_id" from:"solution_id" query:"solution_id" validate:"required"` - FatherNode uint `json:"father_node" from:"father_node" query:"father_node" validate:"father_node"` - Description string `json:"description" from:"description" query:"description" validate:"description"` - Speaker string `json:"speaker" from:"speaker" query:"speaker" validate:"speaker"` + SolutionID uint `json:"solutionId" form:"solutionId" query:"solutionId" validate:"required"` + FatherNode uint `json:"fatherNode" form:"fatherNode" query:"fatherNode" validate:"required"` + Description string `json:"reply" form:"reply" query:"reply" validate:"required"` + Speaker string `json:"speaker" form:"speaker" query:"speaker" validate:"required"` + IsRoot bool `json:"isRoot" form:"isRoot" query:"isRoot" validate:"required"` } type UpdateSolutionCommentRequest struct { - SolutionID uint `json:"solution_id" from:"solution_id" query:"solution_id" validate:"required"` - FatherNode uint `json:"father_node" from:"father_node" query:"father_node" validate:"father_node"` - Description string `json:"description" from:"description" query:"description" validate:"description"` - Speaker string `json:"speaker" from:"speaker" query:"speaker" validate:"speaker"` + SolutionID uint `json:"solutionId" form:"solutionId" query:"solutionId" validate:"required"` + FatherNode uint `json:"fatherNode" form:"fatherNode" query:"fatherNode" validate:"required"` + Description string `json:"reply" form:"reply" query:"reply" validate:"required"` + Speaker string `json:"speaker" form:"speaker" query:"speaker" validate:"required"` } diff --git a/app/routes.go b/app/routes.go index ac3648c0..4b031b04 100644 --- a/app/routes.go +++ b/app/routes.go @@ -179,6 +179,18 @@ func Register(e *echo.Echo) { ).Name = "solution.createSolution" solution.GET("/solutions", controller.GetSolutions).Name = "solution.getSolutions" + // solution comments APIs + solution_comments := api.Group("", + middleware.ValidateParams(map[string]string{ + "id": "NOT_FOUND", + }), + middleware.Logged, middleware.EmailVerified) + api.POST("/solution/comment", controller.CreateSolutionComment, + middleware.Logged, middleware.EmailVerified, + middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution_comment"}), + ).Name = "solution.createSolutionComment" + solution_comments.GET("/solution/comments", controller.GetSolutionComments).Name = "solution.getSolutionComments" + // log API api.GET("/admin/logs", controller.AdminGetLogs, middleware.Logged, middleware.EmailVerified, diff --git a/database.db b/database.db index 8bfe24610adb06f3de70f10278ba72bee3e75735..6c0f3726902e27c0aca22036d8c44ba2394accd3 100644 GIT binary patch delta 3824 zcmcgvOKcof7Ok#ox81h8%fNt>IAI#{F%v`a{`FoF2qc}DBy!x~9))-@Lnn5U4oMps z8-z#1FDaRYkS?T6<~?|@IDZ@qYB=cbxlzGUS~XW-A>Uapt^dGVHqTcxGRk%y(O3#qsgtaetCbPEv7f^w5dDN7dwiC z)zMLc2)PfV`zQ({VH!~35hR&pERNIxU;$U2&wND{A3=-JS&lht;^e}9HgSkA?Am*9 z_whq}#tzp&}Dr54M+E$-R=h*ZOAZv4JzrxW2W0 zsn_v`C>)6cj-n$8=fu!!=v&&2L1*7k^q#4JNl#&gG52Hsbv@9&@RR+(#yCQPkOE;N zcU8OX%Z@X$*nvPo8pK(t%RN@^EI*qYcaF}q=4NM3otmDlJl$wDk3JJr{@j|HKGtka zPgS06oN7)r=9)9D%CY&@(deJyV~x2J)3bkV%}h-XSHd^V=~Gjc;l0u0gW=QT&AAiv z?T=S%x{cs8CDD~AR2uat@)aIg-lk|88WjA-coL=}Vr0u@9& z#3ZKJ$X3^VsVW(Sk2o_Ss=7B-C4=CEGD8DYDgI8XEM`=Rx`yHa6KD!(2|r1auX_xg zvHy3Hx}q$#FRj>eYbO;@moN`ugcB#I>28ysh%2-aL!M%wt&&N83SoW@tOo-?IILO3 z5ktvU>blEhCk_xJsLv%9ae%7MN7>mJn}~^#MbxwtkysB1Oacxugok|Ob7eC8&R+(d zH+p)V@{g8#-rZmR5j^hu^5UdZw2D2OhQ`OOsRsN$Gu3!>X12L7)5;bmSRf6E@FWH1 z#8kxp1UzBKvB$pUgq%+)zk6Z(?_bhJGTTLO`Gy zq(VMbv6$J=WbsCb5=@5e))~vKmVYh3QQlShSBdsN*N^+Y?R&0oOYe!^&Bf1)CyRqU zU-mrTb9?s(-GA%eQg|QSZClqDT~Bqb%U{kfTtHdNg7XT3D2_*zVsY%GxB(eykgsJ1I_DvbaG?N&sh?*8_Xh0?UpuR+$ zq+Z3dG$2FLlY;m%8Bul3*3d{0L~=v4s_7aU*CT40WN8o)VBaH5Fe*$DJgM>0z(adB zrJ4f3QPuZndE5X|(_X~Gqzy(|*!$4>n3&FP z==SSZ?S0810KgtoTo9hJxHl_D7$QPoLQ)zd5sl0t9f%qn@*i88L$Dt%Gh9g|d1_F9 z$|NNOU{3;1K@H8iz9-8fM)*o8k(fbM4`;==0ive2Ws?$aLd;WyF_fIr&|5P!kP5RV zDN{(MG`3`EqzEwEv_v;&Y1{x&(|2cSAU`0~6PPgRr=4|{B*r-6)YS0f zx>B%m2Zj%{8=u=`b6P_QlqHqAOaBpoBLKu7*;}KHBixhXfGG+l>zy}$vL5l;pRU-r zW8(li9Q*~GfJljrh&8=wjYP0efJB@KjEp@u^u}zaSim@}$G*f#9wzkAT2Dg>h9aZl zZoMJ$v_zKc0HDkI-$9r5Co49|t{idNVG#rCQqX7EG#c<(ceD6pR*vg46z$dm3k)qA zds9shu4V`pWf_)~@DX7+&Cnfbh5+D)Ml4}_;?z`mUEjXiOBn=}H0`B7M7?A-05g#wJ^}}sv0$Vx5(N+B00000G7tL?_7Ct6>JQ|% z7LWqY53}Sy9Z(AomH+|{zX1-v4=S?}K(h{$ew|YiFd#57Ix{djF*zb|p8^YT0~!Zjmj@67HM3C= QA_uo#7XzjUvjm|057;F#RsaA1 From fbfe619b452ddfd930c2dfc0bd2d7eeee9252dac Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Wed, 2 Nov 2022 19:22:05 +0800 Subject: [PATCH 18/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E9=A2=98=E8=A7=A3?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=BAbug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/soulution_comment.go | 2 -- app/response/resource/solution.go | 1 + database.db | Bin 217088 -> 217088 bytes 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controller/soulution_comment.go b/app/controller/soulution_comment.go index 3965ec8d..1332e72f 100644 --- a/app/controller/soulution_comment.go +++ b/app/controller/soulution_comment.go @@ -1,7 +1,6 @@ package controller import ( - "fmt" "net/http" "github.com/EduOJ/backend/app/request" @@ -50,7 +49,6 @@ func CreateSolutionComment(c echo.Context) error { } else { FatherNode = req.FatherNode } - fmt.Println("aaaaaaaaaaaaaaaaaaaaaa") comment := models.SolutionComment{ SolutionID: req.SolutionID, FatherNode: FatherNode, diff --git a/app/response/resource/solution.go b/app/response/resource/solution.go index ec629a6d..1852f4eb 100644 --- a/app/response/resource/solution.go +++ b/app/response/resource/solution.go @@ -19,6 +19,7 @@ func (s *Solution) convert(solution *models.Solution) { s.ProblemID = solution.ProblemID s.Name = solution.Name + s.Author = solution.Author s.Description = solution.Description s.Likes = solution.Likes } diff --git a/database.db b/database.db index 6c0f3726902e27c0aca22036d8c44ba2394accd3..e80b7f282e252a32ed60d7521fb3b7189ac1b69c 100644 GIT binary patch delta 635 zcmajdy-yTD7zXfV_l(?fv&%`KK*fu(QNv{Bov+;~jKKr$P`M+a(vUz04J4Knmt!bw zOyIJ`Hjq7tosERzT0aVF^$)PHvZ2w2tK7?S7m0~xlBs_CK2P4+W*arzXn)dnU$t(` zr1#0{@t*g=%Av*;)bQ_l%jm~x@!=+l8i)09I!&NNLruBnfI}ui1|s@?_-)vat@Wq* zS~W_N%C(fy5|x@sO$b(ks_0JgaV+~<>2v@Dm`TOtZZ~<^O@=z%#CDs7oY%7a*ZzWc z=C#t$9dG4%E^pvO zQizapo@K6?g}C_1p8L~KibKIUaF&^6Q;ko4+TmY@1;E10luaf6>^OJ-Wol+Ve(yTs zW`D1QX#!XVAcV@steUxK^ug>@Z%woWM1#~^;Xo?IMZeALpv@&Bq$C%nY|4W+mkgHx j7p86=4Yrd$KGz^Lr2hzkkSNHq>Sm^AR0l6QUxt1IkV~KQ delta 183 zcmZozz}v8ZcY+iX=lqE>PC#;F!lHh@gA6RZbwI?g#TUZ+a*+o+keex;%eYx=6lD$zl7h5?;X&J2YlP#=`o853b65hVc?&` h@5#@^x0=tL_X|jlmpP!xY5K$iOy=A5{FpB>0sw>tIuif@ From ea4e3c6b596716f98080a39d931392a9863e90c5 Mon Sep 17 00:00:00 2001 From: Horizon-srt Date: Sat, 5 Nov 2022 17:16:25 +0800 Subject: [PATCH 19/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/soulution_comment.go | 12 ++++++++++-- app/request/solution_comment.go | 4 ++++ app/routes.go | 2 +- database.db | Bin 217088 -> 237568 bytes 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/controller/soulution_comment.go b/app/controller/soulution_comment.go index 1332e72f..ccea53ff 100644 --- a/app/controller/soulution_comment.go +++ b/app/controller/soulution_comment.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "strconv" "github.com/EduOJ/backend/app/request" "github.com/EduOJ/backend/app/response" @@ -68,9 +69,16 @@ func CreateSolutionComment(c echo.Context) error { } func GetCommentTree(c echo.Context) error { + req := request.GetSolutionCommentsTreeRequest{} + if err, ok := utils.BindAndValidate(&req, c); !ok { + return err + } + + solutionID, _ := strconv.ParseUint(req.SolutionID, 10, 64) + solutionComments := []models.SolutionComment{} - query := base.DB - err := query.Where("SolutionID = ?", c.Param("id")).Find(&solutionComments).Error + query := base.DB.Model(&models.SolutionComment{}) + err := query.Where("solution_id = ?", solutionID).Find(&solutionComments).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) diff --git a/app/request/solution_comment.go b/app/request/solution_comment.go index eed4949d..65713b42 100644 --- a/app/request/solution_comment.go +++ b/app/request/solution_comment.go @@ -8,6 +8,10 @@ type CreateSolutionCommentRequest struct { IsRoot bool `json:"isRoot" form:"isRoot" query:"isRoot" validate:"required"` } +type GetSolutionCommentsTreeRequest struct { + SolutionID string `json:"solutionID" form:"solutionID" query:"solutionID" validate:"required"` +} + type UpdateSolutionCommentRequest struct { SolutionID uint `json:"solutionId" form:"solutionId" query:"solutionId" validate:"required"` FatherNode uint `json:"fatherNode" form:"fatherNode" query:"fatherNode" validate:"required"` diff --git a/app/routes.go b/app/routes.go index 4b031b04..9756b97a 100644 --- a/app/routes.go +++ b/app/routes.go @@ -189,7 +189,7 @@ func Register(e *echo.Echo) { middleware.Logged, middleware.EmailVerified, middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution_comment"}), ).Name = "solution.createSolutionComment" - solution_comments.GET("/solution/comments", controller.GetSolutionComments).Name = "solution.getSolutionComments" + solution_comments.GET("/solution/comments", controller.GetCommentTree).Name = "solution.getSolutionComments" // log API api.GET("/admin/logs", controller.AdminGetLogs, diff --git a/database.db b/database.db index e80b7f282e252a32ed60d7521fb3b7189ac1b69c..d30a679b47334df39f95d5a28fbb6b732093929a 100644 GIT binary patch delta 13855 zcmeHOZ)_9i8Ml2&>^Og%($cPU&?}>BDR8`h?!EW!w3TEylqd;yh$%3Z5;wWvtceY_ z(~kY4d9TtwuB_8MO>JRS#fPpFLitds`!M!p`!Z?TK2@4DY1$;DZPixMqK#JD9@}?^ z@8V{Pv`Aos&>@+h@1FN}zxVe(&-1>1@nYYLSNmVy($#Y#6bhN=5|~M-$&iAH z%2k!`0;&*Nrs6BHP_!A5tVLwP|9#q!tI-S| z2|NpNVld5l)@gC#&SuUx8Y;fLfy^Nt>r^EUa|Lm{&fNHIp}FDpY7Rz23G*a(Y@>)% z4TW>gbe(#VJ9_6zu09&X*{#X?^hPqLVcp=ayliRISo^t>vbKZMW%B8 zYJ_cTuqTx$8dg zbmu;4k@m*}?u-nDVyq$EsK=ZYDK8!(gLe~Vs+ywej3d_=GUAXIj~_!2cIH4*jC=9; zFq9fxb@>_d;sFdXnQl_57?e?}c^r<`Fz?_|={FtE^ugNuXy`;JG17me@AclddalR+ z6F(RacfZwrAa*_WcI-&>gXo3mv1qvKwXV^wj?SNUj&$7UxZH6}`cQg9Iw5sLE=I;9 zUE#~&(a=9bSKwCepGiAXSw@nv)qPv68j!-cPN+j*(hhrrs;zA~M^)$Vf(lNR3$#6wMr z6itKoK(PDLzY&NB-aA!Pt{F^q3^XIY9*D=qs0=$VG%3yo;#rMJiLX^A#w2}9eNY6F zCxxmyCk}sE@j@ULY%)X938seb#qxY076$_|)*MVyECpg&jY*5LpBrkJ1o$%yP37LZ zD*5993|1A6unq&S^Oq4te>@(Ba8Enpj6a?xn3Oo(zzyXl0Y?FQ)Vx>TdimO6$TpixJEDY4KP3#vK=5QE)!kQLAQVu7^ z8SzzrEKM*;G4GGX!Dt5fsKaks~L)Wo)x?gTc7!VGPmDzhSimAH9r{$Er$}XCPosG z{-5+e)%RiV<(~cB|BihxI^Oxmj#niV{#$7I{Ev_Kic|I`i0h@z%i-}#dY^RP(El!k z=kw2J7v^W>xp@mp=DEUBzIrXnrE+m;rYu*h;RnynX3N=Uvn6ZqVgU;IlHxW9oGSeg zeEL|)xy9)GY-zWgx2##YT##q2x%s>$XJzLpg`zcoDlb20ovl5kXf0%`oraPOkDM=i zUz=Y%yUhWlh}!z-QU(i(J`W)p$yr5cZC8qe%(+YEoa27=0GUD z?JN|e6OFp%5I9QDU7>hF@pF^2<83Vzrs|sN+Utx_{+>Y-Oxo@U#6wL) z72P13!JQsa)|P7V?DNtMx8+B%;q)-78GV0P3-$l3FV!25zutX3`hN6MG}ZOjt{-+z zO4lN9gte84flc9V@Km`?rwTV!3hhgc8^n6P+n=lnH#vJ-`wE39 zhCw-Y`>P<7t*tARwLG?LHhf(;aUHhx<&M3b)>_&?#2k%?=Rm1Fb9EwH&T_zrx2&&c45` zg`&ZJR>M-b`L0mB@y0R?ELB zWJ3hq>LBlI-Fddw%H32aREJ{M-86+1@A0-4iUwzS+`JhK`LWg&%E%gq+*~NIaue!K zqB;BXHK8nrN84rhGU@e+>ZU@WB~|ZiiGB8?b)}59;HFe^-AZX-CTH(xYeOM~>F&u% zFqF@=uA!`d*foQn=Wy5pg|j9^W7zTQlufIbJ1PyQg*kIiQKoGaz`#LD9Xfa##_oyNX?yQ0 z15XZb^L{Y{oi{k~ic}qDM}2N&Y-LpguLj|8+|oVNY42Ipzzbp^yW8DXbL=7iiVY=^ K0Y5~lllos7-fA=e delta 142 zcmZoTz}K*VcY+ifR}TXNgXu&CJ0`B4jR{Ni#n}0807V!~`G50&{$fa2y>Kq(^&J!3O-W3%R8 u^V@&TXWag4J`>jhW`3@p)7c%E Date: Tue, 8 Nov 2022 20:39:29 +0800 Subject: [PATCH 20/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=B5=8C=E5=A5=97=E8=AF=84=E8=AE=BAbug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/request/solution_comment.go | 2 +- app/response/resource/solution_comment.go | 2 +- database.db | Bin 237568 -> 237568 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/request/solution_comment.go b/app/request/solution_comment.go index 65713b42..47738cd0 100644 --- a/app/request/solution_comment.go +++ b/app/request/solution_comment.go @@ -5,7 +5,7 @@ type CreateSolutionCommentRequest struct { FatherNode uint `json:"fatherNode" form:"fatherNode" query:"fatherNode" validate:"required"` Description string `json:"reply" form:"reply" query:"reply" validate:"required"` Speaker string `json:"speaker" form:"speaker" query:"speaker" validate:"required"` - IsRoot bool `json:"isRoot" form:"isRoot" query:"isRoot" validate:"required"` + IsRoot bool `json:"isRoot" form:"isRoot" query:"isRoot"` } type GetSolutionCommentsTreeRequest struct { diff --git a/app/response/resource/solution_comment.go b/app/response/resource/solution_comment.go index e79e4402..12c2c6a8 100644 --- a/app/response/resource/solution_comment.go +++ b/app/response/resource/solution_comment.go @@ -56,7 +56,7 @@ func (cn *SolutionCommentNode) ConvertCommentToNode(solutionComment *models.Solu func (commentNode *SolutionCommentNode) GetKids(commentNodes []SolutionCommentNode) { for _, cn := range commentNodes { - if cn.FatherNode == commentNode.FatherNode { + if cn.FatherNode == commentNode.ID { cn.GetKids(commentNodes) commentNode.Kids = append(commentNode.Kids, cn) } diff --git a/database.db b/database.db index d30a679b47334df39f95d5a28fbb6b732093929a..e30714a189c7f8226bf9c9496f2d5a0cd5e1c7df 100644 GIT binary patch delta 1457 zcmah}J8KkC7~P#A`gJZ=YTD`pSWvFu|0cKE8)7p65+DLD=HmpK@ z#BughgC7QOmwuHRCFJh8&)s72bMc|Gzjp*F^wdEk_#vgTdsvm9f^3Hi;^jqQ&xs1rn^BTBStaSlxT(kfrMd{@ZabC zqgpobeXx#f-3i0!hGpCfMRaC@_FK6Z6;NPa7M=#BUL$5{f<>BmwgS z!3LK?0o0vX;1EB8nqi;>$B@&I|6;d0p@Uuo+-?B-WtE@KY^6$XOJ(=3yXsC9e-_^r zXPiIIduP_k6`F-|zLnp~&*xgXPq~F$KKn6yH|u1!{F1L^>^U>-HGf;`eAr{u+qAip+5Lkb{b1c`RBs^+FQ{MEV@V4_f|W*lJ3 z6ld*P&zXsipMIEWb0hR~?iikm@tV69?@AGkFu+nONTPgU)m#tlbZLCc3?S&65p6s7 zj8})Y?tw6-+DlEDYu>9L*4QzSiqV~HqMfjY900BV Date: Fri, 18 Nov 2022 00:24:58 +0800 Subject: [PATCH 21/21] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E7=82=B9=E8=B5=9E?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/solution.go | 72 +++++++++++++++++++++++++++++- app/request/solution.go | 8 +++- app/response/resource/solution.go | 18 +++++++- app/response/solution.go | 8 ++++ app/routes.go | 1 + database.db | Bin 237568 -> 253952 bytes database/migrate.go | 2 +- database/models/solution.go | 7 ++- 8 files changed, 111 insertions(+), 5 deletions(-) diff --git a/app/controller/solution.go b/app/controller/solution.go index fb926875..a079fd88 100644 --- a/app/controller/solution.go +++ b/app/controller/solution.go @@ -1,8 +1,10 @@ package controller import ( + "fmt" "net/http" "strconv" + "strings" "github.com/EduOJ/backend/app/request" "github.com/EduOJ/backend/app/response" @@ -11,6 +13,8 @@ import ( "github.com/EduOJ/backend/base/utils" "github.com/EduOJ/backend/database/models" "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "gorm.io/gorm" ) func GetSolutions(c echo.Context) error { @@ -54,7 +58,7 @@ func CreateSolution(c echo.Context) error { Name: req.Name, Author: req.Author, Description: req.Description, - Likes: 0, + Likes: "", } utils.PanicIfDBError(base.DB.Create(&solution), "could not create solution") @@ -68,3 +72,69 @@ func CreateSolution(c echo.Context) error { }, }) } + +func GetLikes(c echo.Context) error { + req := request.LikesRequest{} + err, ok := utils.BindAndValidate(&req, c) + if !ok { + return err + } + solution := models.Solution{} + query := base.DB.Model(&models.Solution{}) + err = query.Where("id = ?", req.SolutionId).Find(&solution).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return c.JSON(http.StatusNotFound, response.ErrorResp("NOT_FOUND", nil)) + } else { + panic(errors.Wrap(err, "could not query solution")) + } + } + // err = query.Where("id = ?", req.SolutionId).Update("likes", "").Error + // fmt.Println(solution.Likes) + // "1,2,3,4" + likeList := strings.Split(solution.Likes, ",") + // likeList := strings.Split("2,3,4,", ",") + // fmt.Println(likeList) + count := len(likeList) - 1 + isLike := false + // fmt.Println(count) + switch req.IsLike { + case 1: + newLikes := solution.Likes + fmt.Sprint(req.UserId) + "," + query.Where("id = ?", req.SolutionId).Update("likes", newLikes) + count = count + 1 + isLike = true + // fmt.Println(newLikes) + case -1: + newLikes := strings.Replace(solution.Likes, fmt.Sprint(req.UserId)+",", "", -1) + query.Where("id = ?", req.SolutionId).Update("likes", newLikes) + count = count - 1 + isLike = false + // fmt.Println(newLikes) + + default: + for i := 0; i < count; i++ { + // fmt.Print(i) + // fmt.Print(": ") + // fmt.Println(likeList[i]) + if fmt.Sprint(req.UserId) == likeList[i] { + isLike = true + } + } + } + + likes := &models.Likes{ + Count: count, + IsLike: isLike, + } + + return c.JSON(http.StatusOK, response.GetLikesResponse{ + Message: "SUCCESS", + Error: nil, + Data: struct { + Likes resource.Likes `json:"likes"` + }{ + Likes: *resource.GetLikes(likes), + }, + }) +} diff --git a/app/request/solution.go b/app/request/solution.go index af58102e..12178121 100644 --- a/app/request/solution.go +++ b/app/request/solution.go @@ -16,7 +16,13 @@ type UpdateSolutionRequest struct { Name string `json:"name" form:"name" query:"name" validate:"required,max=255"` Author string `json:"author" form:"author" query:"author" validate:"required"` Description string `json:"description" form:"description" query:"description" validate:"required"` - Likes uint `json:"likes" form:"likes" query:"likes" validate:"required"` + Likes string `json:"likes" form:"likes" query:"likes" validate:"required"` +} + +type LikesRequest struct { + SolutionId uint `json:"solutionId" form:"solutionId" query:"solutionId" validate:"required"` + UserId uint `json:"userId" form:"userId" query:"userId" validate:"required"` + IsLike int `json:"isLike" form:"isLike" query:"isLike"` } // type GetSolutionsRequest struct { diff --git a/app/response/resource/solution.go b/app/response/resource/solution.go index 1852f4eb..2f4237bb 100644 --- a/app/response/resource/solution.go +++ b/app/response/resource/solution.go @@ -11,7 +11,12 @@ type Solution struct { Name string `sql:"index" json:"name"` Author string `json:"author"` Description string `json:"description"` - Likes uint `json:"likes"` + Likes string `json:"likes"` +} + +type Likes struct { + Count int `json:"count"` + IsLike bool `json:"isLike"` } func (s *Solution) convert(solution *models.Solution) { @@ -24,6 +29,11 @@ func (s *Solution) convert(solution *models.Solution) { s.Likes = solution.Likes } +func (l *Likes) convert(likes *models.Likes) { + l.Count = likes.Count + l.IsLike = likes.IsLike +} + func GetSolution(solution *models.Solution) *Solution { s := Solution{} s.convert(solution) @@ -37,3 +47,9 @@ func GetSolutions(solutions []*models.Solution) (profiles []Solution) { } return } + +func GetLikes(likes *models.Likes) *Likes { + l := Likes{} + l.convert(likes) + return &l +} diff --git a/app/response/solution.go b/app/response/solution.go index d1641edf..4da88d55 100644 --- a/app/response/solution.go +++ b/app/response/solution.go @@ -19,3 +19,11 @@ type GetSolutionsResponse struct { Solutions []resource.Solution `json:"solutions"` } `json:"data"` } + +type GetLikesResponse struct { + Message string `json:"message"` + Error interface{} `json:"error"` + Data struct { + Likes resource.Likes `json:"likes"` + } `json:"data"` +} diff --git a/app/routes.go b/app/routes.go index 9756b97a..0f0791af 100644 --- a/app/routes.go +++ b/app/routes.go @@ -178,6 +178,7 @@ func Register(e *echo.Echo) { middleware.HasPermission(middleware.UnscopedPermission{P: "create_solution"}), ).Name = "solution.createSolution" solution.GET("/solutions", controller.GetSolutions).Name = "solution.getSolutions" + solution.GET("/likes", controller.GetLikes).Name = "solution.likes" // solution comments APIs solution_comments := api.Group("", diff --git a/database.db b/database.db index e30714a189c7f8226bf9c9496f2d5a0cd5e1c7df..c422fa41ca494b468f63ab3c9645576ffaf951fa 100644 GIT binary patch delta 11025 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 LwFX)9ccK3Ut|vAC delta 706 zcmZoTz~69yZ-NvXZ#@G8gVjU@J0{-xjR{NiIe7SY0Yww1rE_;sv zzC#QwymhR+b^KaR)685mianCe+r7#bRw8)_R^SQ!{V6d39nSST1; zS{YbcnV9PtnHd|IS(-x>WU|1lGLJHfiZV7!a}S^Vckb~7h76z!JgM#i3y=#eO$`hu ztIRJ;$OPKqO$$3L^o&dm%uSkq&2RrTpK<%I`AqBvlEC2S&{>@H9&oed}^E3L{gea{^x*Xa-L0L7A6fnt)<@*LAy?lCz` zSH8z2&7Hvl5|h;B@b{lydz;B+`T~%NDa>39jN;PD9Mk9BWpbMS8K{yoj|r$!Sz4E4 zy2X7apXtf>fx6=vfnuW4vcSYKef51N>*+^ z-U418o=rSa++Q{a3S8sf{zaQvAca|yZOe4_3CzYou_`v^kY<