From 9789b86920913be6a562f5f294c6fb0fea92741b Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Wed, 22 Oct 2025 20:29:17 +0800 Subject: [PATCH] add admin --- public/badge-1.png | Bin 0 -> 2214 bytes public/badge-2.png | Bin 0 -> 2250 bytes public/badge-3.png | Bin 0 -> 2894 bytes public/badge-4.png | Bin 0 -> 2749 bytes public/badge-5.png | Bin 0 -> 1659 bytes src/admin/api.ts | 28 +- .../problemset/components/AddBadgeModal.vue | 154 ++++++++ .../problemset/components/AddProblemModal.vue | 99 +++++ .../problemset/components/BadgeManagement.vue | 102 +++++ .../problemset/components/EditBadgeModal.vue | 156 ++++++++ .../components/EditProblemModal.vue | 94 +++++ .../components/ProblemManagement.vue | 77 ++++ .../problemset/components/ProblemSetInfo.vue | 80 ++++ .../components/ProgressManagement.vue | 72 ++++ src/admin/problemset/detail.vue | 368 +++++------------- src/admin/problemset/edit.vue | 114 +++--- src/admin/problemset/list.vue | 4 +- src/shared/layout/admin.vue | 1 + src/utils/types.ts | 4 - 19 files changed, 1015 insertions(+), 338 deletions(-) create mode 100644 public/badge-1.png create mode 100644 public/badge-2.png create mode 100644 public/badge-3.png create mode 100644 public/badge-4.png create mode 100644 public/badge-5.png create mode 100644 src/admin/problemset/components/AddBadgeModal.vue create mode 100644 src/admin/problemset/components/AddProblemModal.vue create mode 100644 src/admin/problemset/components/BadgeManagement.vue create mode 100644 src/admin/problemset/components/EditBadgeModal.vue create mode 100644 src/admin/problemset/components/EditProblemModal.vue create mode 100644 src/admin/problemset/components/ProblemManagement.vue create mode 100644 src/admin/problemset/components/ProblemSetInfo.vue create mode 100644 src/admin/problemset/components/ProgressManagement.vue diff --git a/public/badge-1.png b/public/badge-1.png new file mode 100644 index 0000000000000000000000000000000000000000..5bb14aa763f914eb2a4f5e6af5348a1725e20a35 GIT binary patch literal 2214 zcmV;X2wC@uP)^ zO>7la6vyv$g=`T`+|X{s4-72W5ef|piHojuL1F@hMvXCX1tgMCYJv%{GBL)O(sp4& zjIO#curO2zyDmyJDsF5yT_|j^8yU~juAp8Ijm`QMK@_s$z} z|MS0X1z_ia)0d#_9D{8G;JN*0Zl`H71MS>@W?{QP*cJdXhmWe$sdJ~cYbJCK0FL6Y zIWjcM{!i0yE%8({r1BZ%{s~eC>L~)=nMdyPtx?Z`h@f22lu)? zFYR()e>$aNKsebY2%P{BI*-FRuU@}9dB}n=nx@G~+Gu&3yfFYf4xBzEJ9^rW?8smE zVAA1m=oB)_GWjTN`t>Pgf5w<8jR8o~r1C2)a5D4tDFXoLsibep&y>D3Dik&bKy|Q| zaj=YVjH$2n%Q)?+2QMRZW$i~ZJ~WF4z~O_h_;rl&MFap#xd`-yiZ^ExE{ z`umZCNJAbZspIPkSjZqi1PIcQ)g?A8G>Hg@0)X&W6z2yU-rEqyh2)(Pr$YIUKizZF zAD#Df+TC~3L zuvUGoToHgL%Sn>X(r8^``S&l**N)WK(0Cov2gGX)BJ$(4i43v<5&0@az(veq>Mn1t z&M%sLX|fUko2!d!k5}g}Sr9NB2TFS`C?F09K?t2EAS!5DD#8xyeB#{VKliUslr{(o zDgmHvLJ$A|(()=i1VP&{@^zg@w*`;^dVK%-(;HUpybrGh0R31H$YTUVx`@KHPn{5i zGUtoh(jLNbt2a&3DQu&x4%G&L&QXLy(h!C)6-h&OQ~PB0st(|wka}hPAV=4reyWx?27vgxsxlmd%IZ^wgJtER+(x5eS=D@F z00@ia^p#jr<*aR9X{>XV;UuJayZ(_!? zt8(4xwQlGv=Xs{SmgBsBE!y|`UKO{(qXRIKCP&m#uCF!CY~XcAo;3^zI1btKymg+s z_I79_O-~|=Nznn2i_`q>kde2>0)hrQfWXa?b)L%-9eHiXVF@B{`z9ZQq5~jC`Co0| ztfZfL005!@5a19;Vvfk9Lo&0#_Z^lu$wvjCX#E!%2LO@Upn7T{u}urLtXfGFlZAa)0uhRvqQ9&I|FU5IKv7RKz)ddP_D-Sf_xFN5w@`pL;;}6nq<`Z-H?s> z#nH8l{7+>7BD@@x^89IIABX~gb5HX1Kb{?ca;qi5Xfx_}R~|@i>){wJC%ZBEwlG0@ zOX?gKq-C?AjeQ^r0A&G?jyeFSgTmK1)^d!NwBy?XX#s+dEdB!r`vJ3o{ed*~pf>h_ zC;-U%&!aPa1>$tssBad0%m4@hVam=1oVT-~jeQ^r05Up$39tcjyv1<<5V=0f;@lV` zt%4#B2-Kl2pSh_62s#^B9Ov*|0i)Nq}IJ^s_-bEYPh*m3daHHaV%+=m7`;p=UNohq-P^ z5A`$#KwfFHtX1I?Y+yrKQLzyqphJKd18m{7ehyQlrZE7FHft4Lq@WF%0s(K@|9=1g o0RR6nS*{)c000I_L_t&o05)5By-4N&%m4rY07*qoM6N<$f;IOE)&Kwi literal 0 HcmV?d00001 diff --git a/public/badge-2.png b/public/badge-2.png new file mode 100644 index 0000000000000000000000000000000000000000..7610c6bfa46083387c5b83e612ebb3812e1b0bb2 GIT binary patch literal 2250 zcmV;*2sQVKP)9*~6vwBoWT}Y>6rO2ur7Q&zLZn@|$IuiOCX}5C3v0SlNilxJg$;GVy139FX`_1< zZ43cX+(}%R+9riUqKWP_#!&yi)0z9`-FM%8bKCcoD7ojInKLtI&iT)o&+>%(kN^80 zfPMzR-o1NAL}UH5p)V0IJUqOxZ{NPHp`oEQ(X!HO0^(9Xfaoaza&kn@E^lpZP34>& z5fHN~1Bj7aSy!_?1wc+N$Quj!+JR@>%=BqD|H&JUwB&pMu}q>@)H47yx;SReAA9+E zcjxA(2EgRRD{k@HyAGLmdW0$B(_Lph0YIV8{5Izq?WJoM8yrIxM*>sCw`r)?jZD`8 zkRxLX{n=prWrci5#~cudgdkI!bF>ZlZt)!fAj8OpXxxR=lW@Kd$h% zOu-Kz5DC7B^tpPyarnIGNcso~Hs zQDD&;1g&@y0BW28z^EucIG>z%f8R8FYWtrwUiOnOO9fy(G~BrVYe@E=N6ur+#)H3L zfijzepopgekhL8c0CLV_;KqYLVU;KefJcuWWoQlr00qwHy^d|pm&N%c0DJ=j;r{*K ze6~-l#QEFb{~nAoTSKOdR|cR=S=Y--oX_>$c>uJxn$o^afduEn8W3#Ffl`=FjsP8R zZ7b}{HkjZ%-qrj;DArev4un~Jh^jOtTLO^3`r093i* z>6-g|ufrZAr{B2;Gn&!dCcG_^_%kCA?%X($U6Iv{bs?M1%G=if0MAa6+Q{?hz}>qa z&NJ^r=pTEDd3{i3RsV>F#j7tmbokayPwou>X#ccT6X%!oz~LKppZTz-qj=uqz|z&j zh<8lrnE&ul27-LF0S*c?05m_cf-`;C>M$rj?=OFJ2=T6n#(;4A$kQaDhBHD2fJ*GB zEABdR+?|_Wa;ML}U#=?}dHUV$yhleXs?`rkRLOje0ieL>`r0C4-;pWMXR z4~jv^Ip3*y-^%7MzuwG>;;V8707C5mSE+>qM^C(2Y&aF#5ch={{o#{p=xPEX=X|H< zJ^cn^TE*Z7A47Qt0D{MlAHOHQA~NTj45uKGCiO?pLJ)G!V_>}BcWT~ars+)^f zr!&?708$UaxGED376||VQC@|bKzQ(no6v{^qvFtHujcSlMSrWhb60+Gaa5_^%EN~b zNAXSRhOY?#N~tKi6hJ@*01)XaWFWluY<4uoc|e$c`(75Bwf%eCZuk3O6VA_FSq)i- z4|2X~03c~96!&RfXiLz%Iq z0MJkhOc80;gt_@el4&I8>wmP^qrcqLK|lc`zxdfj6w5l1W@@1)*h;z`B?F+48fmA@%G)?^b-MhMY^&@@20(QU09JLSi@!cQ&sORU zGh2PSlvM_Rt8$^nK09A%Q-ZJx0Ik&xi1W4K?f)PlL%H%MML`k(@moRD6c`Za<+MG2 z!98^j0I$$k0{{c$JjT@;@BE0`Qc?s+i*148^=)v#oHyHg@gF2O4!Z$#9suIwwGKkr zpi$O}k|F?Q+FQ9MTLc_E`LW~DL5FaNn;kU#!VL#;6(vudR-Lz#bGAnZx`Iy9$fk9f zqF?mGDGvuB*=jf0cKRt#0)UDlj+T(4BQ71=Myv{qRlC_m4-Zy{JjOw4U+JR_S6Xz? zAC2J|@$1_L>iRpC1Vph^cabVZKXqQv}tON$pguLBunK~5XmhJ3ep*8#wAIl{Eb zK;TIXc}zTx0)m$@s>utPZ?hxT69Bwr4GSaN8EXPWnw8zx;{mhf8=kMzG1fBx6a}`6 z$a0&nj5doML|SsbbuDr|bDj=+1^}IT5LmTsIw143&ekdCD{W!E?XFl)0l-o~5V0n( zg+Xj{qimg&_nLYRKyXkXu!TW|+gzyEZQeHkI_21I_52F}0RR8l>6s}2000I_L_t&o Y0GdsZz1U1K761SM07*qoM6N<$g84%_+5i9m literal 0 HcmV?d00001 diff --git a/public/badge-3.png b/public/badge-3.png new file mode 100644 index 0000000000000000000000000000000000000000..73247e252510fc0d4ade1b9b2db92e3d36a3d6d8 GIT binary patch literal 2894 zcmV-U3$gTxP)W zCp!`19{@|cM9K~q!f`id9pOEAa{yrlN9K?mVr44t(>=9QUB7y!ckI!=sj646-j8p+ zs+z9eN}kbYwD$gBwD!--qwnp$asI;Yt#Sp=vz3b=&Up*nOT^-2p|8TaZU;TQh?Nc>ThffJ1%b1)#Y^lvH zZ0BX>>p2tvY*M6V&J=+VbRE?9Pv~qvmlLh|1PxtOS;j!;_c{Zuo zFA;*Mo!3ByXUajR#ycK*92i4gE{^Y)OaK$%^A@T10-!Ny^%!fLsvXu;CwS`Z-u^9g zy>|7K#aV}VyQ=J*1HA6|cI%>u@yd`bC?Y)G8|OxM%E9|-ECpU>;6r)K|KFCG)fAKNDj z@CBcIJzCfMhwgiYP5>%vzN5-of2noX5|}nzFw8tOWgirmet1Hl1IDyM762H_0Uc9z zu}Jw;+3Hepkal(gkV+*G*RicX93@DOGsvCs>o@o7BaeQ605kvX7oQV|y5EN^zYQ46 z?*vEiu;I(PIzA20w2#Gl`i)4fT=?$sx({%Yg99d+7O;9XivWZg zQ^6zi{K^+8A|j}tUwuJ-dt)H)Y@C%py*aFdj0Bb8gM%Ez*j#3$Y_6;vtsliz-NBzR z@g{!Isg)uC;U@BYCeW8(`I4%N|90N{xIX4c@whk70St(2c=M0VGeao-s@^q(JlZ)Q z=}S=&fN;QyA{_E)a|WlL)&KkOiTv#KeW65d5n{{_F6||UU~d?2cu83i8|`Dh;6ebf z`S^qVI-BFNK-hlo6UhaSjnpqc=SyyqTz^=00ATjR0i|{cgx}np|C#^B&GbVNfn%fO zL%cbbW9R^&ZEBv~9tWAF_DGQ(-496Xke_O&q z6+D2>tFN?7(H~L~fQgk4`~fKE_qoqoq|VOXC65f`%iW*zq6Gi^an!>Y;Q3SpK&r{u z7p8vyU)?`*k=qMyeZruS$I4s z6xW9=d`H-XTsv2WGDf5ryy&M0fcA?upIxW)>D|9S_M1^Xl_dlZMZzA#0g;mXNN_3IW*Lj{>WE+m55~!rc!ON zaJyU5=l5~EK|U{6U-|OUTvzhNO6YTLa3=r^OdTbpd2TN_^R@QP3_5%o>dg&rk}m24 z4Me@`oL|X2h~Wbn>FcMS@)>?ea{*v7|M9`yU8s=uP#;uM0S%{t^D@Q%%}$+PdH{h8 zI(&jRRGmK0)pI_m&-$9|{o;cVIywO;-LJD0a<@UuEI|PTX-;rq;5gtDKp?|7#taoO z>hOFyS6|mxZ1~{XK{=@GhkJOKa(ZEsky$~eXl zIQ5h;!KYH+m&JEt@Ofdq2!OFiA_UzJ8edTk1Yc&E^<3~N-%>I7zGMMtZiH>?LXjUR zTvKt?Q@B=+|yyOZAgUm zxXyb3JtC=x{e9c$x}!SLO+D0uFI==b-@<;Ah{eey0hs=$MQaDeh`Zav5NHF0Q{fC%^9X?4e}RO-0s_WD{?uTd4LFVS5P=Yo z>(7!|#OB(ri~vae7YKp6*>?je0Rbnt!ln){ zMRiab2mv`FKu!;cI^|tH=as?ZuA+8U9QcJXwtCJOChf?D+=WY_CHmw5yQbz^B^K8zQ_IbU*aTgY}dEwEhXn)h!=Fl=@YwQ)C&>#`R zC5v9R2p>u%Gd6mGVXa(;q>&N#A;`3D5%`Yq3qNV^=uLELsra$h08EdFfivbxlmGz8 zI-VPp?h3TEd3JSc^W14AqeQ86c9p*IU(dY(S!1rC(lEKt*!^;o<+s;W7jm~wjkbqN?d!AvlYS*7enRmGj2E|1x0Y;1eL?<8!_ zq>HuspDHVmD2mNG)e+O0NoHhw>P+f&7VCaCeDPYH1;$2qlFkt2VPPaRe}CL#dhZxZ_G1sct%={u!m2B(_)z4*Xe<2tID<9%D^) z8sCj>tP*UfGW}@ZxSE*ix>hvR%)u_awRx@%n9ax!f*H}VnhE+n{Ui9)+PAv#O+^k> zU^Ar)yE}>WM;?Qe_|6jCiU5&)qrlKtAxH%wN`jW+$Fu-oHbQZu%Evu6zEF>AH@Zxe z1)*)DcHNk;B+jvBBr$I32}FrZ#n&Q~nvHNgSrzgQ+qQ}27wVkM@g5)?voHXXcu(Lf zW#0g8pSO%UI?-L$#ePwi2z#rL(bdKg$!sbjvfsUgRI2Y^;#l-mHNN?r?)t(2pwe2K zeC1@#IHx#UYm<%#dwJupJYB`-N;03N$}~j{!!5nfO;P= ztzFqJ>Da@mF0%24xZeQNH8Sq+1wfOErhd8;oegUytK(-d`!fAB_N&t(W^DB6Q~SM_ s-sb=S0RR8N16G^>000I_L_t&o0KrO1G%mckApigX07*qoM6N<$g13l{M*si- literal 0 HcmV?d00001 diff --git a/public/badge-4.png b/public/badge-4.png new file mode 100644 index 0000000000000000000000000000000000000000..dae57cc30dadda29d0c3bcdf473dcc44d567fb8f GIT binary patch literal 2749 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 +import { NModal, NForm, NFormItem, NInput, NInputNumber, NSelect, NButton, NFlex, NImage } from "naive-ui" + +interface Props { + show: boolean +} + +interface Emits { + (e: "update:show", value: boolean): void + (e: "confirm", data: { + name: string + description: string + icon: string + condition_type: "all_problems" | "problem_count" | "score" + condition_value?: number + }): void +} + +const props = defineProps() +const emit = defineEmits() + +const newBadgeName = ref("") +const newBadgeDescription = ref("") +const newBadgeIcon = ref("") +const newBadgeConditionType = ref<"all_problems" | "problem_count" | "score">("all_problems") +const newBadgeConditionValue = ref(1) + +// 预设奖章图标选项 +const badgeIconOptions = [ + { label: "奖章1", value: "/badge-1.png", icon: "/badge-1.png" }, + { label: "奖章2", value: "/badge-2.png", icon: "/badge-2.png" }, + { label: "奖章3", value: "/badge-3.png", icon: "/badge-3.png" }, + { label: "奖章4", value: "/badge-4.png", icon: "/badge-4.png" }, + { label: "奖章5", value: "/badge-5.png", icon: "/badge-5.png" }, +] + +const conditionTypeOptions = [ + { label: "完成所有题目", value: "all_problems" }, + { label: "完成指定数量题目", value: "problem_count" }, + { label: "达到指定分数", value: "score" }, +] + +function handleConfirm() { + const data: any = { + name: newBadgeName.value, + description: newBadgeDescription.value, + icon: newBadgeIcon.value, + condition_type: newBadgeConditionType.value, + } + + // 只有非"完成所有题目"时才添加条件值 + if (newBadgeConditionType.value !== "all_problems") { + data.condition_value = newBadgeConditionValue.value + } + + emit("confirm", data) +} + +function handleCancel() { + emit("update:show", false) +} + +// 重置表单 +watch(() => props.show, (newVal) => { + if (newVal) { + newBadgeName.value = "" + newBadgeDescription.value = "" + newBadgeIcon.value = "" + newBadgeConditionType.value = "all_problems" + newBadgeConditionValue.value = 1 + } +}) + + + diff --git a/src/admin/problemset/components/AddProblemModal.vue b/src/admin/problemset/components/AddProblemModal.vue new file mode 100644 index 0000000..dd8bf04 --- /dev/null +++ b/src/admin/problemset/components/AddProblemModal.vue @@ -0,0 +1,99 @@ + + + diff --git a/src/admin/problemset/components/BadgeManagement.vue b/src/admin/problemset/components/BadgeManagement.vue new file mode 100644 index 0000000..30f6d1d --- /dev/null +++ b/src/admin/problemset/components/BadgeManagement.vue @@ -0,0 +1,102 @@ + + + diff --git a/src/admin/problemset/components/EditBadgeModal.vue b/src/admin/problemset/components/EditBadgeModal.vue new file mode 100644 index 0000000..d0fe361 --- /dev/null +++ b/src/admin/problemset/components/EditBadgeModal.vue @@ -0,0 +1,156 @@ + + + diff --git a/src/admin/problemset/components/EditProblemModal.vue b/src/admin/problemset/components/EditProblemModal.vue new file mode 100644 index 0000000..db37376 --- /dev/null +++ b/src/admin/problemset/components/EditProblemModal.vue @@ -0,0 +1,94 @@ + + + diff --git a/src/admin/problemset/components/ProblemManagement.vue b/src/admin/problemset/components/ProblemManagement.vue new file mode 100644 index 0000000..65d21a1 --- /dev/null +++ b/src/admin/problemset/components/ProblemManagement.vue @@ -0,0 +1,77 @@ + + + diff --git a/src/admin/problemset/components/ProblemSetInfo.vue b/src/admin/problemset/components/ProblemSetInfo.vue new file mode 100644 index 0000000..d5a1cc2 --- /dev/null +++ b/src/admin/problemset/components/ProblemSetInfo.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/admin/problemset/components/ProgressManagement.vue b/src/admin/problemset/components/ProgressManagement.vue new file mode 100644 index 0000000..feefc84 --- /dev/null +++ b/src/admin/problemset/components/ProgressManagement.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/admin/problemset/detail.vue b/src/admin/problemset/detail.vue index 0950e20..080bdee 100644 --- a/src/admin/problemset/detail.vue +++ b/src/admin/problemset/detail.vue @@ -1,19 +1,32 @@ diff --git a/src/admin/problemset/list.vue b/src/admin/problemset/list.vue index 436f062..8a68180 100644 --- a/src/admin/problemset/list.vue +++ b/src/admin/problemset/list.vue @@ -106,7 +106,7 @@ const columns: DataTableColumn[] = [ { title: "选项", key: "actions", - width: 200, + width: 300, render: (row) => h(Actions, { problemSetId: row.id, @@ -162,7 +162,7 @@ watch(() => [query.page, query.limit, query.difficulty, query.status], listProbl 新建题单 - + 难度: { if (path === "/") return "return to OJ" if (path === "/admin") return "admin home" if (path.startsWith("/admin/config")) return "admin config" + if (path.startsWith("/admin/problemset")) return "admin problemset list" if (path.startsWith("/admin/problem")) return "admin problem list" if (path.startsWith("/admin/contest")) return "admin contest list" if (path.startsWith("/admin/user")) return "admin user list" diff --git a/src/utils/types.ts b/src/utils/types.ts index 69119e3..c065904 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -191,7 +191,6 @@ export interface ProblemSet { create_time: Date difficulty: "Easy" | "Medium" | "Hard" status: "active" | "archived" | "draft" - is_public: boolean visible: boolean problems_count: number completed_count: number @@ -234,7 +233,6 @@ export interface ProblemSetBadge { icon: string condition_type: "all_problems" | "problem_count" | "score" condition_value: number - level: number } export interface ProblemSetProgress { @@ -252,7 +250,6 @@ export interface CreateProblemSetData { title: string description: string difficulty: "Easy" | "Medium" | "Hard" - is_public: boolean status: "active" | "archived" | "draft" } @@ -261,7 +258,6 @@ export interface EditProblemSetData { title?: string description?: string difficulty?: "Easy" | "Medium" | "Hard" - is_public?: boolean status?: "active" | "archived" | "draft" visible?: boolean }