From b203ac8e9dca9cc34d0071dc123682e956339bbe Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 6 Aug 2025 16:09:47 +0800 Subject: [PATCH 01/42] =?UTF-8?q?=E7=AD=BE=E5=88=B0=E4=BA=8C=E7=BB=B4?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Repositories/YuanheRepository.php | 1 + public/wx-icon/alumni-benefits-bg.png | Bin 0 -> 146653 bytes public/wx-icon/alumni-benefits-icon1.png | Bin 0 -> 3385 bytes public/wx-icon/alumni-benefits-icon2.png | Bin 0 -> 3302 bytes public/wx-icon/alumni-benefits-icon3.png | Bin 0 -> 2725 bytes public/wx-icon/alumni-benefits-icon4.png | Bin 0 -> 2443 bytes public/wx-icon/alumni-benefits-item1.png | Bin 0 -> 7651 bytes public/wx-icon/alumni-benefits-item2.png | Bin 0 -> 7623 bytes public/wx-icon/demand.png | Bin 0 -> 1800 bytes public/wx-icon/email.png | Bin 0 -> 1253 bytes public/wx-icon/phone.png | Bin 0 -> 2397 bytes public/wx-icon/publish.png | Bin 0 -> 4123 bytes public/wx-icon/supply.png | Bin 0 -> 2299 bytes public/wx-icon/wechat.png | Bin 0 -> 4199 bytes storage/api-docs/api-docs.json | 11817 +++++++++++++++++++++ 15 files changed, 11818 insertions(+) create mode 100755 public/wx-icon/alumni-benefits-bg.png create mode 100755 public/wx-icon/alumni-benefits-icon1.png create mode 100755 public/wx-icon/alumni-benefits-icon2.png create mode 100755 public/wx-icon/alumni-benefits-icon3.png create mode 100755 public/wx-icon/alumni-benefits-icon4.png create mode 100755 public/wx-icon/alumni-benefits-item1.png create mode 100755 public/wx-icon/alumni-benefits-item2.png create mode 100755 public/wx-icon/demand.png create mode 100755 public/wx-icon/email.png create mode 100755 public/wx-icon/phone.png create mode 100755 public/wx-icon/publish.png create mode 100755 public/wx-icon/supply.png create mode 100755 public/wx-icon/wechat.png create mode 100644 storage/api-docs/api-docs.json diff --git a/app/Repositories/YuanheRepository.php b/app/Repositories/YuanheRepository.php index 8ced4f4..10f715d 100755 --- a/app/Repositories/YuanheRepository.php +++ b/app/Repositories/YuanheRepository.php @@ -46,6 +46,7 @@ class YuanheRepository $header = $this->getHeader(); try { $result = httpCurl($url, 'POST', $params, $header); + dd($url,json_encode($params),$result); $result = json_decode($result, true); if ($result['code'] == 200) { return $result['data']; diff --git a/public/wx-icon/alumni-benefits-bg.png b/public/wx-icon/alumni-benefits-bg.png new file mode 100755 index 0000000000000000000000000000000000000000..23a26596fa754539412ecf8f781f390ac0418c30 GIT binary patch literal 146653 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 z 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 Ef~$IsbpQYW literal 0 HcmV?d00001 diff --git a/public/wx-icon/alumni-benefits-icon1.png b/public/wx-icon/alumni-benefits-icon1.png new file mode 100755 index 0000000000000000000000000000000000000000..0d3298b17fbce52dcd52762d8691eadd8c7c3e04 GIT binary patch literal 3385 zcmd^C_g7PAACHP{9XKlDdc_zO2ZRhDkVsq%p@tztDOMna3j|1lNmwaGL2DJU2!aAC zQ;?w`LuC(a+7LITMCoIH?PItq=V4j|yDxRt;6sjW(fkvZYa3l5~X#)yXsH~ z?j(RrH_*XCq+e9*iS`(K0s%k*C_AV+UY!6{L*mg;JOZT&)g-6^a3p}XgCiZ*?EI6y zx~d)mi9#XO^mNq_2tByw1-QDdIs&b&s;z<6MkCgA4ahV)o=gDNd=sUZ_cGxOfy!2CRWu($4QFEfKZ*gP~aUzN=0Z+t&J z)G8J&&&>(gQ+&a~TxF71c>=xZ!=wBszl;p?TJoQWmicAzZYwJikx($$KQ9rBS_>nl zCi!#Y-BbMy^V374BMXfmg2p;4@7f?k5^s5l z$C>DE$_W|ouHte8<6Tu^k&rvp-{0_Va(uDqnLX>%%faTn;^z+4slQdH`i`;6Yu?p$M?aU9#kqBqMmJ|=^W zlA1Su6Fs%<#m_5~ya$_eTMM4%hFmFlYSUiwqN^flpz%F-vTu`DH@-1uZ~9dBmjV=TF|B2jva z=u=}kQZh|9H8PX7^#9EQO`g}0Ue6mD20G`>y*jfa_%^!?8sp7yyM)-br;e% zH_PdqKNqQQrZb`7-;?#cm(}3=Wd60|EF)@!FLD2K(YZ)a62<`x{{vbg&eyGe&ZXp+gI(#7KHPgu7j*=*YB2>Yi#Pjy*JeI zk#>-uF%{>xaRqwJQYn7azaivOVy26n=n?p&yiQUXdwU!Ek*#hDLS7VN86ObPyK9^8 zPdQG?w&Px@#pY99>y%8=8}nUVYEmLrhEF&@Q=+E4nvIV1@Edp;OY2j_&V$U}X-se{ zE8#yTr#g41wY5SLOmV*n*_6F|if_uSWHW~R_R$I6r>ZZ8T^9}>3al#zwv_zZvt^5b ztHC6BAGJ}8PfVJ0i5AQ$me!<>SYn43lidqE7~JmD<~^n|rv@+9PQACmGzSF}?iMSi zcQXpI{L-Htj3_j;Mt72wFRK3}_O-q??;KbVj{05AC*dZuSXN`7zHwN^CcR+iUD*ab z)t;N~KDT;>z3;DT=^U!tuPB_dRV{Xo#}S-XcI^6X|a85djsG0g8bsef%Sg| z5RxZtH0Iyvy>`WMWuQG&i??wfq7J3(@LRtBaw2s1>2ek?0fkIHonrFK{@PCgdvWhh zwmU9^$k_S_vkT`W0@@+#o$k<}IGa6H-#2^$MFf4*x>lM8}LVx!KsGX=sM3L;qUxPZl}S-9yr&BbJ?h?+{iiCW;n?zw$t`k zxhRJqk`wOMW2H3+BCH)!IIhRRdZ z(OKro3Msxvil$y#D%gdihgb9xzKiDs9R&o26%Et8O$JJN+Mxho~%viG(wE^kFZQM&y59_kel$KQ8dL zn8%SdY1a7Lu8tb(sYg>Y@*gE%zBiv?DcZBU%R($^{JiO1(k7=55nzkw_;6*5v-snI zO&7%=*5W<$%RzE3VPZRTg}X*fhj1bxA>g-rR%u!z4}5FW9xQLRdYKsm-*9>RsXRO- z3Gr6hJq_1#M^SP(c@PxmtGEBkh0w#XinSM_Hp}EHTDvXf*GzqJ{i8c6HkSm{!Z zzNOXQ5+eV{WdXX`wY=$CVx-kam_SlbJGhA)wrh7#0Mzo;(wn%eiOS7K5B8o`koO__ z&^WaVsmq_oj^%V71iJtHZy(cVWrGxv4BtP^G>K5g?vnK}Vb^8wt^ckG-cMI8$YxgUw=N-(`K0SM3 z@qsTu(_}OHVy4tpjeRXI)rRC|oC%!9IqNk%l;xs?dxsAT_r~Co54ddQBU4Y~9KXZx zZq}b0+Uj%9(Lw)_#1%byg;B%4$_QiaA)}D8oga4G#idgY%cNzTi0p4vZqhC43D+lk z+67Q$W91+3er*i3mUFIx25`h4$4xXYugh28@>w>T!i@%P0EPPZgeqok*IfOXG0-*A JNxNX{|6fd!58wa* literal 0 HcmV?d00001 diff --git a/public/wx-icon/alumni-benefits-icon2.png b/public/wx-icon/alumni-benefits-icon2.png new file mode 100755 index 0000000000000000000000000000000000000000..e85e0dff66e85d9feedec1a3c1602d147c1c6d28 GIT binary patch literal 3302 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 bAZifH?QcjPiI9xtKM!jQd-Kd=XTtsqhFbZy literal 0 HcmV?d00001 diff --git a/public/wx-icon/alumni-benefits-icon3.png b/public/wx-icon/alumni-benefits-icon3.png new file mode 100755 index 0000000000000000000000000000000000000000..798bb2bf5dbf3478084114b1fbbdb4ca7c9f33ad GIT binary patch literal 2725 zcmdT_cT`hZ8qdh+QCURR!I9C~$%&(*VtRo@P)a~?#X?bFRwX142#{hD>h7x8#V(E% zT^&S}1f(dTDIg$KswC9V6+#FJ2}vk{un!e?{_xEId(V6C-uvC}_x10-%Ln)GHd*<@ zN(cmE;C}Coi5m%byoc;Q$bO8p{uWx-cjKfEz%eMV_bu zY#!eG}x}4P@4!6D1ZU*D9{K-2$M^Su!Vh;O9IymWF!pw zk%bp*3;Sf0m+L{OBZ~t-i3l{Dib7$bRzw7mKtxfjt^BFmp%@efk3?aSC;}XVBH>Xa zGy(c~z(9o@nm@^n?EG0BxU+=?@_1|#5*Z#IjtIvhSeyVPnn)xfQ5Yl!0|zs&H!eyb16(SH&gRisOz46{iXSVKXA1+3{p1CM?dtkPFq8W^R$$bS5fnBOjX)t8 zj0M*|a&viZ!2itnDmT|7k_{l;04^((Lj_afzi|-^hVRc6Eii)CkPdL@U|uL8WEM4) z0Wf(kWLp?`f}qi9BpQ_pU;u(298bYh;W!M12&bS4)^KYo4nSc5q8|$5zbNNxcsv?| z!8tmiaL&#IG};;EV2^bq6EI}50~U|7vUXU+x-hvs3X=*f>ZXIbKViwve~KkJasUdC z#qnUVLKX|*U?7Xf;s&zVP)A2F>u4f$iz|gnXD$%8E+p!c-(-M84+Ch<92NumG14UZ zSFFI{a5OX)i~x~BAi%LW90u;^kG6&bIDb41i^F66uvpkg3(^*%v!2pUzIIXQ#DegQ9Us`OL)Vj0Sw!iH)s!bOE1rb*)<2&d z>#ckmrup!$IsbNZ-c4m^iCWgH?teSl*Qn?y(vC}u6a7@Z)f&b7+GnTb{Y@R^$h zm8_@YF}J(+nR2+Zy)0>VQdRjhT-{$=|NK%{Rcb-3*Q|cJ<>g&*apKIBMl~XlN^11e zI`wGZaA#$;;Ggx`7m5?9`YDZWT-x89-zdB)DoUv4M~RCPl|vmh=_dB}* zYSJgh2B(w*+L89@iIJwf8;bX>TIG-)L`td~h1ZG`X*!imQkyCifM*{xgFmsu5`RTu{=U$*oDqkSDF z1d(Mz7*c#3dds-SF8BVfK!nrv1`%PTCHOsO^2gc1OOD?^n46D=R3A8NUGvS^P2NL_ z;4Qk!wdW||M`?@!qO$O6+EMWLZcslUR!7KY%T??;&FuuK)VDFyN7;t8+?u}Pd(u!)Ry{$1_ z@)?qjBzfhxOwu&x<^P#`r~PD&a+g$o!m7CFN1xoAK!oVYWbqHWBcT=;xyMk>h|CF>iPtE$siIpE#ZwWFliSlr2JakfY&uzFcU#z_tD?Qw)+Ug_V z50&rre8_k8%n<3S2JaYIrg8Jdd(9bfy>iFY*RS4QdbGESvMjGNmYf;g$-uimxbobm z?%68X(F1t%q^(0o*U|-Xzt+b!8*kb!^l=}Q1YHsF?~5*IX!s0%vP72f>OmLZiiUs0 zM?jKxUg0}1#mylCGu4ZVq{@Pf^u2>EZ2Mo>N4?Wu_K7T8lJzUt-AmJVgx!v`%ev0r ztn^Cj0n&v+yN9iL$Kz#}u03d)3Hhy4Duj!9nQ-;FY`2T=8lTzeL?=CgT?NNC1Seid zp${Lu>r;!bokD~GBfBlGnl-=Fr#+>57X@8Sda|4R*YyppCyvIK?uiu)Y;@hdeTU$r z$G#1vU5B#GY)<5=+T4oHH-)x_l-pn(q_HW5kff*S3AfV23fNlv2cG*kYVH%SV7qhU zRv)>J4Y*$`Z_oVciISNRlJKO>t3LfKZa7Tjj7i|^4qAbYEDMF+UB{Q*OkTO7Ag({d zmbgwZc&)xR_N-5&Tf2ID4sM5ek!fAbvD+pqkNMt;chaJ3S~JY-=Y)5Ed-wQPGqx%b zks=uFOS21y_dCX&BU&~E32jQ<;k}K=;ceUWrQ347g-)r@ANq7GSN@*i@ExhVEN%6S z`I?fEI`iqb-MYj3vc&&6YPoY&MRJq3^{XfC#Nj>5(smU1T(0d9csCrLl7A?H7(rIv XDT^&k2!?_e7R1GAKRLs}_so9*#5a)6 literal 0 HcmV?d00001 diff --git a/public/wx-icon/alumni-benefits-icon4.png b/public/wx-icon/alumni-benefits-icon4.png new file mode 100755 index 0000000000000000000000000000000000000000..8d54804aa735215bf76e321a6b2408c2e11e2967 GIT binary patch literal 2443 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 tK+l?Jf$Ebjh`24jS1Ae&h+D@@tj;NGS9iTY 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 L80o3-k3anfr9Q)5 literal 0 HcmV?d00001 diff --git a/public/wx-icon/email.png b/public/wx-icon/email.png new file mode 100755 index 0000000000000000000000000000000000000000..f622025d4879983de41b89455bcecb5572814c7e GIT binary patch literal 1253 zcmaJ=U1%It6rNfd+hPI*#nz``g3^dHbNBAdW@gM76@wlj&xD zoVm$vLXEYGP)oIv)>?dNr8I8^e?Zy_KJ=xfLjA#?s!)VfD-omMgJ6T+-R#CbgbvJ{ zd(WKjobUV{DGu%K-1^v7j^jG>IkUuMoV`zO-pIZ^=jR8Q*g-R+bi}XF8VU*5Z~GSE z^DY`EC4%gk7p{>$j@x*|DUZ_8!k~eDS3(UNsqO|0&2fFZ>H)%4LV1gfJ6=*)zWk}c zJ9bjorxrjVNRtUCHye_X*`YF?tzz94c0I%Q)eYvrB^2>>chZZDdQxcmHQ2eKmIc0P zLaRw(mDFgV$fx~~@VXQeF#vJCSC{mJ4v^Mc!B6oJKvf2D86-pq3>6r$1mAiD7BI9c zM#;>!!m(RYn4mN;WVu$WNwv7-hvRZg*L4{{8A6d+h|!EkQC;++?zRV$L^yN;>i8bt z@Q5sbiY5g{b~Ot(C=}Kldr_-atZH%{1#(ORvgUtiI;<~f()96^OFWu4lLGrA*^X`47!ybmmZ%~XiwZ=#h++v% z)UZMTB)SD)rR`@uyq*S1KTKtmY$hFxWq}?`n<-5(6_`zFX_#tb^Ik-ehe{*?&~*iDHve3a$DaKF+(LKW zdp@JdU6t*Nzn!`}zinh#!ag+;jB+hcC%x^(TGE4js$?Hhj0RAKiy`8xyM zaeo+i<@indXeWR9_R+6WUiZTvy?ju6{miQ=uw~(pwezUhPtN@PP-@Tc-Yst*13%8y z-kAU9v)t$6TW>nYc3V&M<_{n0x{Gg6Vbko=yJx>v4_rF`QV^Yb(Kwy^>A?@5d;As} z{Nm*A#}ms3PpC6X-~I)LcSt|qct2i!`j@%W3;$eP*|wjPikoWM!ifVcJ1(CYGB2d| GAN~(i52Jwq literal 0 HcmV?d00001 diff --git a/public/wx-icon/phone.png b/public/wx-icon/phone.png new file mode 100755 index 0000000000000000000000000000000000000000..88d8c37bb3dc21004552cdd935b1fc011249dc07 GIT binary patch literal 2397 zcmV-j38MCiP)}(m~*~iRK&0f1X&j3QmZT!Sd9p10=r&X zHZ(@Vj}^5e>RRgRpSH14`a`2O3tq5b6{)VV?q+u}Ml=Gp8X;=btwrcEii66<3StMj zr~~u8Pk-=zbQ}j+&FZ|#mwa>P%sJ2dyw`Jv6A|N_GhG01&bh)Ei>Rxso7K?JFt@k2 z_m?J1PrX6EASi?=Z%|yeR;fs;UeCBO(r9>fytOH_Vq^GB2#flYJxNsrHjvcEj&{0xSvX+Q^yvaBxqMv4E zWtA$5(j$a`5CZGhuSa`(I{<))008;<`8w;!&CUHQ0O?KO0oB#jzgHBcU3ZBC2M)kp zhzJ!G6~q3Xk&$tch|Jyu{!vOw$|W82(xpqEW7$>e>gu2e>*UFk+W-W44R}jS%O2MN zynp}x3xIX$>+8d~apQE>pSHHP&VZK!)Nu9c)lc=b7#|8#=FOWSZxQQrVh9Nd8PwgtX0tJ; z)A_CR}p8@zdEiKKe13Gr>m^)|!FwoJ_L3+6tLLeq4=2UNQ?@X`damLucl9H0H>A_c7 zS;-h<05HHge+J+YW9-)D%a{8Y8*-btxHyN^YCSt<%$O@|gudLp7W~*^V2nMOKY#uu z#+XA@Rd)95Sun=_%Q-&_ppgNV9c7R0WZ=#7Y~s@&ml zd|)=4ZwnzHr9^FQ?biT)0bmM%FaYm49F8@?!NK2abJVR{w-ymmpf}t^_i?7G>V!p$ z7JVtDBq0PW7E3J=%?99$q1M#^;JuQPk^(7ZzmyVYv-$h3uC65*YKvc3SU*+0G2q&! zKGoILzm`(=2qEC-=hyCZIzQF`>ytTvw22cZ)@T8$rlzKr1DN3oUOP<n)07h555*&yqH7-1vut zgoJBz=FItS)v8q`MMXtxDk>`G*lf0NRaO0=WiajLfRCn(r$OG_+`Ldqc}WY@C(D*C zD3Y*_4`^TGY|eG2)qa zL~{^PL}q5@Ulc{@(>AzST3VXt>YJ`^Lqs7bPoB()j*dPqgm~x*&SWx?l(M~`py0&m z)2Bb*wr$%^i^cMFa&q#uprD`!LI{Um{9F`#6dxbI7eK(MuHw$5s;a5c(a|TQl!F?O z@5;)`e&r$fhJOPfs<^m#b!24Zw^GVSQp$dRfB(Pl+O_Mq01}AE0KlmEv-!!BCljq! z>-#58oXFm>V@Kig<;(x+>+7p4al59bCdE@Azp%MmspbzKK3o_W7+5KUP&Fp5@7=q1 z0}+LL3L^a;62RE1s;YO(%gcY#)z$S505Q^hJzj`Ns;asqD=VwXXf#4ml!1c>53be} z9W^*#2-cRCmdw!5&@(~^r)K_pt5>hy3n0aneOIMj$?#;I5x(aDd@UBsKQw>G?%lip zNJOUB0j@JYKQ1n=TnN#pE!vxqkZ}6q#f!@TguE;RjP|(wCNeoW*{TKXz~RG(R}j%_ zG4AT~vllO3Tw*jDTlL_RQrgz8UAwQdvvZ*qNFKAmXjah~@9OGWDy4j^-N(1o*ViX| zTJr}3*EZw;B6jZF`I(gRq7Y(03!(u(Kfi{}n>X+3?(UvPMDMs;zynD4^*Ml9+1c6O zYM|BF*x0YMwO*c8UcsdN#*G^bGBPp_Nh#Z1*dGiC2)MO!<;sKS&Yk-NKokJeNLJ9- z)O>qZVPWBZDWzR2P|fA#a65V3#%{!b$#BP*qp-7ZB0Qp*0Yu(0}^ zoSd?0ci~(R$RaL=InU85`Xjq<;lT$8)uxliAFJ8QOk6!RRJsfzw zb0IK%al`>678e)K+p}lShj;GWdEa0#_-o^?XHVz&@#Fi#!^7=9?w+9J;Rh==i4_3;q{7k~mF^3Ge`S#?6nymfqmTqrvCo^(3+Z>pIx|cA?eDMD{*)4 z-i>N&Ynuqb*I+Oh^nE$!4kEgnk&$sJH#fH`D=X^)=luTAvLjyy{wTm-BAg9ffr!Du zL8ZC5c}zz~$GFbUPIFgRmoH)V2A1U> P00000NkvXXu0mjfSoWbP literal 0 HcmV?d00001 diff --git a/public/wx-icon/publish.png b/public/wx-icon/publish.png new file mode 100755 index 0000000000000000000000000000000000000000..3b5f0ab6275523f880d15627b1e02942a075be5a GIT binary patch literal 4123 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 Vza)7QL%IL}002ovPDHLkV1mKOHva$s literal 0 HcmV?d00001 diff --git a/public/wx-icon/wechat.png b/public/wx-icon/wechat.png new file mode 100755 index 0000000000000000000000000000000000000000..46a199c8972977193606c93b3d0256920f95dfe9 GIT binary patch literal 4199 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 literal 0 HcmV?d00001 diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json new file mode 100644 index 0000000..b7d21ba --- /dev/null +++ b/storage/api-docs/api-docs.json @@ -0,0 +1,11817 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Laravel", + "version": "1.0" + }, + "paths": { + "/api/admin/admin": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取后台用户", + "description": "", + "operationId": "8fd1da113086757bc0cc9672b6dbf0db", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "description": "关键词", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取后台用户" + } + } + } + }, + "/api/admin/show": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取后台用户详情", + "description": "", + "operationId": "86eabe57c0f2f08613e5508af14c3863", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取后台用户" + } + } + } + }, + "/api/admin/admin/save": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "保存后台用户", + "description": "", + "operationId": "b861dab00723e315f99ad0da933b90ce", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "菜单ID,为空表示新增,不为空表示更新", + "schema": { + "type": "integer" + } + }, + { + "name": "name", + "in": "query", + "description": "名称", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "username", + "in": "query", + "description": "用户名", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "query", + "description": "密码,新建时请前端处理为必填,修改时留空表示不修改", + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "手机号码", + "schema": { + "type": "string" + } + }, + { + "name": "department_id", + "in": "query", + "description": "所属部门ID", + "schema": { + "type": "integer" + } + }, + { + "name": "position", + "in": "query", + "description": "职位", + "schema": { + "type": "string" + } + }, + { + "name": "sortnumber", + "in": "query", + "description": "同级排序,默认为0", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "保存后台用户" + } + } + } + }, + "/api/admin/admin/delete": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "删除后台用户", + "description": "", + "operationId": "cc166224c2a6f8a3acd7a4b5198e3573", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "ID", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "删除后台用户" + } + } + } + }, + "/api/admin/admin/set-roles": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "后台用户授权", + "description": "", + "operationId": "1e31da222d2ab67e65588982390279ad", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "ID", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "role_id", + "in": "query", + "description": "角色id,数组形式", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "后台用户授权" + } + } + } + }, + "/api/admin/admin/set-roles-many": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "后台用户授权批量处理", + "description": "", + "operationId": "9d44dcbfdc79b89f2bd6845fb28bd2ee", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ids", + "in": "query", + "description": "用户id数组", + "required": true, + "schema": { + "type": "object" + } + }, + { + "name": "role_id", + "in": "query", + "description": "角色id", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "后台用户授权" + } + } + } + }, + "/api/admin/appointment-configs/index": { + "get": { + "tags": [ + "地点配置管理" + ], + "summary": "列表", + "description": "", + "operationId": "2150f2ca8bb570e6b5da366bc041f7f2", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-configs/show": { + "get": { + "tags": [ + "地点配置管理" + ], + "summary": "详情", + "description": "", + "operationId": "e29a50d2335ed08bfeceeefd626f3e2a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-configs/save": { + "post": { + "tags": [ + "地点配置管理" + ], + "summary": "更新或新增", + "operationId": "567158a69a46c18d95f0f49a376fb163", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "配置名字", + "schema": { + "type": "string" + } + }, + { + "name": "no", + "in": "query", + "description": "编号", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "content", + "in": "query", + "description": "内容", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "total", + "in": "query", + "description": "人数", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "file_ids", + "in": "query", + "description": "文件id数组", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "status", + "in": "query", + "description": "状态-0禁用1启用", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "value", + "in": "query", + "description": "会议室id(技术人员填写)", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "room", + "in": "query", + "description": "第三方会议室信息(技术人员填写)", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "door", + "in": "query", + "description": "第三方门禁信息(技术填写)", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "use_student", + "in": "query", + "description": "是否只有学员可以预约0否1是", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "start_time", + "in": "query", + "description": "开始时间", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "end_time", + "in": "query", + "description": "结束时间", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "address", + "in": "query", + "description": "地址", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "appointment_type_id", + "in": "query", + "description": "场地类型id", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "sort", + "in": "query", + "description": "排序", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/appointment-configs/destroy": { + "get": { + "tags": [ + "地点配置管理" + ], + "summary": "删除", + "description": "", + "operationId": "99b930f43b86c9229235a619cdd4582a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-configs/excel-show": { + "post": { + "tags": [ + "地点配置管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "1d2f7f5be62c8c5f6fe192cfef917456", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-configs/import": { + "post": { + "tags": [ + "地点配置管理" + ], + "summary": "导入", + "description": "", + "operationId": "75f4a6faf26a4d061ff7ffbadd900333", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointments/index": { + "get": { + "tags": [ + "预约管理" + ], + "summary": "列表", + "description": "", + "operationId": "8bb057d0d49b85cb93488dc3842322c3", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods,thirdAppointmentLogs第三方日志记录,thirdPlateLogs第三方车牌预约记录", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "user_name", + "in": "query", + "description": "用户名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointments/show": { + "get": { + "tags": [ + "预约管理" + ], + "summary": "详情", + "description": "", + "operationId": "67ebd2358368b235c256ca7464e37145", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods,thirdAppointmentLogs第三方日志记录,thirdPlateLogs第三方车牌预约记录", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointments/save": { + "post": { + "tags": [ + "预约管理" + ], + "summary": "更新或新增", + "operationId": "879743c2b4755654fab3af74acd1bb77", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "user_id", + "in": "query", + "description": "用户id,创建时多个用户英文逗号分隔", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "date", + "in": "query", + "description": "预约日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "start_time", + "in": "query", + "description": "开始时间,例如:2023-01-01 11:11:11", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "end_time", + "in": "query", + "description": "结束时间,例如:2023-01-01 11:11:11", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "content", + "in": "query", + "description": "预约事项", + "schema": { + "type": "string" + } + }, + { + "name": "site", + "in": "query", + "description": "预约地点ID。数字1-6", + "schema": { + "type": "integer" + } + }, + { + "name": "plate", + "in": "query", + "description": "车牌号。多个英文逗号分隔", + "schema": { + "type": "string" + } + }, + { + "name": "accompany_total", + "in": "query", + "description": "陪同人数", + "schema": { + "type": "integer" + } + }, + { + "name": "status", + "in": "query", + "description": "状态 0未审核 1审核通过 2审核不通过3取消", + "schema": { + "type": "integer" + } + }, + { + "name": "reason", + "in": "query", + "description": "审核不通过原因", + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "手机号", + "schema": { + "type": "string" + } + }, + { + "name": "idcard", + "in": "query", + "description": "身份证号码", + "schema": { + "type": "string" + } + }, + { + "name": "accompany", + "in": "query", + "description": "陪同人员,二维数组,包括:name,idcard,mobile", + "schema": { + "type": "string" + } + }, + { + "name": "is_hand", + "in": "query", + "description": "是否手动预约0否1是", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/appointments/destroy": { + "get": { + "tags": [ + "预约管理" + ], + "summary": "删除", + "description": "", + "operationId": "b20d16ca7083a9d3182bccac566e8b18", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointments/excel-show": { + "post": { + "tags": [ + "预约管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "055484c0d9da4bcb227896159ced332f", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointments/import": { + "post": { + "tags": [ + "预约管理" + ], + "summary": "导入", + "description": "", + "operationId": "60b6f9a377c7ca89d4fb8cb1c5b734c0", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointments/retry-appointment": { + "get": { + "tags": [ + "预约管理" + ], + "summary": "重新发送第三方预约信息", + "description": "", + "operationId": "57354b71b14bb179a143f9bb0f1753f8", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-type/index": { + "get": { + "tags": [ + "地点类型管理" + ], + "summary": "列表", + "description": "", + "operationId": "eeb81e371c23e14993a2573bdfde5af4", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-type/show": { + "get": { + "tags": [ + "地点类型管理" + ], + "summary": "详情", + "description": "", + "operationId": "d5a7bfba32aa336a1978bea377aef1f7", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-type/save": { + "post": { + "tags": [ + "地点类型管理" + ], + "summary": "更新或新增", + "operationId": "e16600924fff505e1fb17dede09237f7", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "配置名字", + "schema": { + "type": "string" + } + }, + { + "name": "image_id", + "in": "query", + "description": "封面图id数组", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "introduce", + "in": "query", + "description": "内容", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "start_time", + "in": "query", + "description": "开始时间", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "end_time", + "in": "query", + "description": "结束时间", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "tips", + "in": "query", + "description": "预约须知", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "is_show", + "in": "query", + "description": "是否小程序显示0否1是", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/appointment-type/destroy": { + "get": { + "tags": [ + "地点类型管理" + ], + "summary": "删除", + "description": "", + "operationId": "656586563a854b6b50e62cde77ecfb27", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-type/excel-show": { + "post": { + "tags": [ + "地点类型管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "28bd549516289a214535be933ff3a6e1", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/appointment-type/import": { + "post": { + "tags": [ + "地点类型管理" + ], + "summary": "导入", + "description": "", + "operationId": "b8027714a0f1a7a3351d55732d8f99b2", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/auth/login": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "用户名密码登录", + "description": "", + "operationId": "b8098605e389c86dcb60db12b1b4dfe2", + "parameters": [ + { + "name": "username", + "in": "query", + "description": "用户名", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "query", + "description": "密码", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "用户名密码登录" + } + } + } + }, + "/api/admin/auth/me": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "获取用户基本信息", + "description": "", + "operationId": "328064bf31986debc9b4ae90c3a4b52d", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取用户基本信息" + } + } + } + }, + "/api/admin/auth/logout": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "退出登录", + "description": "", + "operationId": "59a49d30177042d9f58b1de69afbc903", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "退出登录" + } + } + } + }, + "/api/admin/auth/permissions": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取权限菜单", + "description": "", + "operationId": "ee71984d6aee2fad6d0a4352b07e058a", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取权限菜单" + } + } + } + }, + "/api/admin/auth/sms-login": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "验证码登陆", + "description": "", + "operationId": "edb56f7b1c5eaaa28693e2ab4a8be9e4", + "parameters": [ + { + "name": "mobile", + "in": "query", + "description": "手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "code", + "in": "query", + "description": "验证码", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/admin/auth/send-sms": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "短信发送", + "description": "", + "operationId": "3bd46af932e33c7b8f448151934a5329", + "parameters": [ + { + "name": "mobile", + "in": "query", + "description": "手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/admin/auth-node/index": { + "get": { + "tags": [ + "权限" + ], + "summary": "列表", + "description": "", + "operationId": "ef68cfd66f342a7c4dca72f2d5b1909d", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/auth-node/store": { + "post": { + "tags": [ + "权限" + ], + "summary": "添加", + "description": "", + "operationId": "63c9fb30bb87ed88459f1556fb0a09ed", + "parameters": [ + { + "name": "tag", + "in": "query", + "description": "标示", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/auth-node/show": { + "get": { + "tags": [ + "权限" + ], + "summary": "详情", + "description": "", + "operationId": "50814a73c80d41f3673014603d642874", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/auth-node/save": { + "post": { + "tags": [ + "权限" + ], + "summary": "更新", + "description": "", + "operationId": "1a8f6d67f7c7481e583d83b2a39f8390", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "Id", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "tag", + "in": "query", + "description": "标示", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/auth-node/delete": { + "get": { + "tags": [ + "权限" + ], + "summary": "删除", + "description": "", + "operationId": "16361fae0137319c97269359264c91da", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/banners/index": { + "get": { + "tags": [ + "Banner图管理" + ], + "summary": "列表", + "description": "", + "operationId": "906c0ec359b736e3e90cf6eb23f15361", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/banners/show": { + "get": { + "tags": [ + "Banner图管理" + ], + "summary": "详情", + "description": "", + "operationId": "1ae017725b187beff165e20ec69d0990", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/banners/save": { + "post": { + "tags": [ + "Banner图管理" + ], + "summary": "更新或新增", + "operationId": "2d37e8e4dcdecdd273c12237bede971d", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名称", + "schema": { + "type": "string" + } + }, + { + "name": "image_id", + "in": "query", + "description": "图片ID", + "schema": { + "type": "integer" + } + }, + { + "name": "jump_type", + "in": "query", + "description": "跳转类型(1小程序,2H5)", + "schema": { + "type": "integer" + } + }, + { + "name": "jump_url", + "in": "query", + "description": "跳转地址", + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "排序", + "schema": { + "type": "integer" + } + }, + { + "name": "position", + "in": "query", + "description": "显示位置(1首页)", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/banners/destroy": { + "get": { + "tags": [ + "Banner图管理" + ], + "summary": "删除", + "description": "", + "operationId": "57744ac92f87348e48d0cb80bae8a751", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/banners/excel-show": { + "post": { + "tags": [ + "Banner图管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "5286cae2b9b967cc099f4a533769a745", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/banners/import": { + "post": { + "tags": [ + "Banner图管理" + ], + "summary": "导入", + "description": "", + "operationId": "5e0b5004372524cd22f5a4f6c46fb233", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/{table_name}/index": { + "get": { + "tags": [ + "通用接口" + ], + "summary": "列表", + "description": "", + "operationId": "7241eaefadbac3463d3c3cea0a57e1e1", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/{table_name}/show": { + "get": { + "tags": [ + "通用接口" + ], + "summary": "详情", + "description": "", + "operationId": "3d2ed0dbfbbf20b49108beb46a707e6d", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/{table_name}/save": { + "post": { + "tags": [ + "通用接口" + ], + "summary": "更新", + "description": "", + "operationId": "55b3ba836ca415276f64a0b23539a60a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "Id(存在更新,不存在新增)", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/{table_name}/destroy": { + "get": { + "tags": [ + "通用接口" + ], + "summary": "删除", + "description": "", + "operationId": "c1888a2d9a21c1611e40c87c8e25c147", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/{table_name}/excel-show": { + "post": { + "tags": [ + "通用接口" + ], + "summary": "导入预览", + "description": "", + "operationId": "b19a44939dbcca2d2b489947d4672f80", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "统一数据键值对数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/{table_name}/import": { + "post": { + "tags": [ + "通用接口" + ], + "summary": "导入", + "description": "", + "operationId": "ec86790f4d2a2526a64b9f83ae2349b1", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/index": { + "get": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "列表", + "description": "", + "operationId": "b4e1bb0b1ffef6488893ae2ac594be3f", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_auth", + "in": "query", + "description": "是否鉴权 0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,不填输出全部,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/show": { + "get": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "详情", + "description": "", + "operationId": "8c76430d593ba0664d275c9f34da95b7", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/save": { + "post": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "更新", + "description": "", + "operationId": "7f8d3c3203c6341ed080dd70c34056f2", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "Id(存在更新,不存在新增)", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "字段名_relation", + "in": "query", + "description": "关联表数据,二维数组。如果存在id则更新,否则新增 ", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/destroy": { + "get": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "删除", + "description": "", + "operationId": "f87f3ec868377d10a6e090fbcbb60dd9", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "destroy_relation", + "in": "query", + "description": "需要删除的关联关系字段数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/excel-show": { + "post": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "导入预览", + "description": "", + "operationId": "e79142dfe67152c8fa91c48e9a240649", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/import": { + "post": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "导入", + "description": "", + "operationId": "0b83282c40a7e952aa420cefdb398e34", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/base-form/logs": { + "get": { + "tags": [ + "自定义表单增删改查操作" + ], + "summary": "更新记录", + "description": "", + "operationId": "69b6dafd72f7f5396f6a87ccb5c3b4f9", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "table_id", + "in": "query", + "description": "记录id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/configs/index": { + "get": { + "tags": [ + "配置管理" + ], + "summary": "列表", + "description": "", + "operationId": "b626aaed2b5da7076169d725e424f34e", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/configs/show": { + "get": { + "tags": [ + "配置管理" + ], + "summary": "详情", + "description": "", + "operationId": "4a0fcb73d8390abb9a050665d71bdb3a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/configs/save": { + "post": { + "tags": [ + "配置管理" + ], + "summary": "更新或新增", + "operationId": "86f4fd5633bbc06192449200685a2fcc", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "配置名字", + "schema": { + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "英文标识", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "value", + "in": "query", + "description": "配置值", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/configs/destroy": { + "get": { + "tags": [ + "配置管理" + ], + "summary": "删除", + "description": "", + "operationId": "c89c950110864d93af0a027394a5031e", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/configs/excel-show": { + "post": { + "tags": [ + "配置管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "c012b459fd123b084bc0357381e581b0", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/configs/import": { + "post": { + "tags": [ + "配置管理" + ], + "summary": "导入", + "description": "", + "operationId": "5e3dede7137f5bd215563f5e715cbabd", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-appointment-total/index": { + "get": { + "tags": [ + "预约次数管理" + ], + "summary": "列表", + "description": "", + "operationId": "d2feea81974074ab518b69be7247db5a", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "course_name", + "in": "query", + "description": "课程名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-appointment-total/show": { + "get": { + "tags": [ + "预约次数管理" + ], + "summary": "详情", + "description": "", + "operationId": "16ee1c22c700c721a34e4ec248454486", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-appointment-total/batch-update-total": { + "post": { + "tags": [ + "预约次数管理" + ], + "summary": "批量调整次数", + "description": "", + "operationId": "f00e69677ede4d246cb41710540363fe", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "total", + "in": "query", + "description": "次数", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-appointment-total/save": { + "post": { + "tags": [ + "预约次数管理" + ], + "summary": "更新或新增", + "operationId": "310f9c2fe52e655c06f3286b3a3abfd9", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程id", + "schema": { + "type": "string" + } + }, + { + "name": "user_id", + "in": "query", + "description": "用户id", + "schema": { + "type": "string" + } + }, + { + "name": "start_time", + "in": "query", + "description": "开始时间", + "schema": { + "type": "string" + } + }, + { + "name": "end_time", + "in": "query", + "description": "结束时间", + "schema": { + "type": "string" + } + }, + { + "name": "total", + "in": "query", + "description": "次数", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-appointment-total/destroy": { + "get": { + "tags": [ + "预约次数管理" + ], + "summary": "删除", + "description": "", + "operationId": "9705797a3221f3d163f691163d37f51e", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-contents/index": { + "get": { + "tags": [ + "排课" + ], + "summary": "列表", + "description": "", + "operationId": "968acbc628f375eaef6bc16f8b70aa23", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "file_name", + "in": "query", + "description": "导出文件名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,不填输出全部,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-contents/show": { + "get": { + "tags": [ + "排课" + ], + "summary": "详情", + "description": "", + "operationId": "961a5266eb8718e0750b4f40f5d8b597", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-contents/save": { + "post": { + "tags": [ + "排课" + ], + "summary": "更新或新增", + "operationId": "f0e2c5678be89a8e8d1c91da77545a22", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程ID", + "schema": { + "type": "integer" + } + }, + { + "name": "period", + "in": "query", + "description": "时段", + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "teacher_id", + "in": "query", + "description": "老师ID", + "schema": { + "type": "integer" + } + }, + { + "name": "address", + "in": "query", + "description": "地址", + "schema": { + "type": "string" + } + }, + { + "name": "theme", + "in": "query", + "description": "主题", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-contents/destroy": { + "get": { + "tags": [ + "排课" + ], + "summary": "删除", + "description": "", + "operationId": "4656cd160a1a88cfb1cdf46c5c8ae90d", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-contents/excel-show": { + "post": { + "tags": [ + "排课" + ], + "summary": "导入预览", + "description": "", + "operationId": "ce7706493c98efe49f540fa7f8927a4a", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程ID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-contents/import": { + "post": { + "tags": [ + "排课" + ], + "summary": "导入", + "description": "", + "operationId": "fd6618cb0b9a2cdb6e74bb3c586fd855", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/index": { + "get": { + "tags": [ + "课程管理" + ], + "summary": "列表", + "description": "", + "operationId": "4c2f19a2f43cfdd34c3d5fdffb5aa201", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字。当值是sign_status是按照课程状态排序", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "has_course_forms", + "in": "query", + "description": "是否有自定义表单0否1是", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/show": { + "get": { + "tags": [ + "课程管理" + ], + "summary": "详情", + "description": "", + "operationId": "a8f83f1d9be0307ffb54ea5bba848f3a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/save": { + "post": { + "tags": [ + "课程管理" + ], + "summary": "更新或新增课程信息", + "description": "根据传入的id决定是更新现有课程还是新增新的课程信息。", + "operationId": "21bd2dfd26d228ef7267e9556ffe4632", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "课程名称", + "schema": { + "type": "string" + } + }, + { + "name": "start_date", + "in": "query", + "description": "开课日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "end_date", + "in": "query", + "description": "结课日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "sign_start_date", + "in": "query", + "description": "报名开始日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "sign_end_date", + "in": "query", + "description": "报名结束日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "type", + "in": "query", + "description": "课程类型:接口获取", + "schema": { + "type": "integer" + } + }, + { + "name": "content", + "in": "query", + "description": "课程内容", + "schema": { + "type": "string" + } + }, + { + "name": "total", + "in": "query", + "description": "开课人数", + "schema": { + "type": "integer" + } + }, + { + "name": "class", + "in": "query", + "description": "所在班级", + "schema": { + "type": "string" + } + }, + { + "name": "is_arrange", + "in": "query", + "description": "是否排课-0否1是", + "schema": { + "type": "integer" + } + }, + { + "name": "is_fee", + "in": "query", + "description": "是否缴费-0否1是", + "schema": { + "type": "integer" + } + }, + { + "name": "status", + "in": "query", + "description": "课程状态:0待发布, 1已发布", + "schema": { + "type": "integer" + } + }, + { + "name": "teacher_id", + "in": "query", + "description": "班主任ID,多个英文逗号分隔", + "schema": { + "type": "integer" + } + }, + { + "name": "publicize_content", + "in": "query", + "description": "宣传内容", + "schema": { + "type": "integer" + } + }, + { + "name": "publicize_ids", + "in": "query", + "description": "宣传内容附件id数组", + "schema": { + "type": "integer" + } + }, + { + "name": "sign_total", + "in": "query", + "description": "报名人数,默认0不限制", + "schema": { + "type": "integer" + } + }, + { + "name": "image_id", + "in": "query", + "description": "图片id", + "schema": { + "type": "integer" + } + }, + { + "name": "qun_image_id", + "in": "query", + "description": "群图片id", + "schema": { + "type": "integer" + } + }, + { + "name": "is_virtual", + "in": "query", + "description": "是否虚拟课程0否1是", + "schema": { + "type": "integer" + } + }, + { + "name": "course_content_status", + "in": "query", + "description": "课表状态:0未发布, 1已发布", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/courses/destroy": { + "get": { + "tags": [ + "课程管理" + ], + "summary": "删除", + "description": "", + "operationId": "57c19e7073bcd1c76d11f6499ca55b75", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/excel-show": { + "post": { + "tags": [ + "课程管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "08732fba18f8e3f63f0c8740dfc6e3b8", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/import": { + "post": { + "tags": [ + "课程管理" + ], + "summary": "导入", + "description": "", + "operationId": "04537b21457c077b1542bb2f26c96abf", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/qrcode": { + "get": { + "tags": [ + "课程管理" + ], + "summary": "报名二维码", + "description": "", + "operationId": "7b03b84a0c2771dc81fe580e46e29e79", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/courses/send-sms": { + "get": { + "tags": [ + "课程管理" + ], + "summary": "发送短信通知", + "description": "", + "operationId": "87cf77e1662eafc1e5deb6c35a89b209", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-forms/index": { + "get": { + "tags": [ + "课程表单" + ], + "summary": "列表", + "description": "", + "operationId": "6e382657c1bf238491c17496645b0c53", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-forms/show": { + "get": { + "tags": [ + "课程表单" + ], + "summary": "详情", + "description": "", + "operationId": "19d8aa68eed452cc449b0d9fc633e24b", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-forms/save": { + "post": { + "tags": [ + "课程表单" + ], + "summary": "更新或新增", + "operationId": "5662e235e0983b28f98b71362dc85ee5", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "配置名字", + "schema": { + "type": "string" + } + }, + { + "name": "field", + "in": "query", + "description": "英文标识", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "edit_input", + "in": "query", + "description": "输入框类型。包括:text文本,radio单选,checkbox多选,date日期,日期时间datetime,file单文件,files多文件上传", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "rule", + "in": "query", + "description": "检测规则,多个英文逗号分隔。包括:required", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "sort", + "in": "query", + "description": "排序", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程id", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "help", + "in": "query", + "description": "提示文字", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "select_item", + "in": "query", + "description": "数组,选项文字", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "need_fill", + "in": "query", + "description": "是否需要填写0否1是", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "belong_user", + "in": "query", + "description": "是否属于用户数据0否1是", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-forms/destroy": { + "get": { + "tags": [ + "课程表单" + ], + "summary": "删除", + "description": "", + "operationId": "f4b196b7021a67b530b5d279379879ef", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-forms/excel-show": { + "post": { + "tags": [ + "课程表单" + ], + "summary": "导入预览", + "description": "", + "operationId": "05e7b4a58c1d9e74623dfedf9e4d6484", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-forms/import": { + "post": { + "tags": [ + "课程表单" + ], + "summary": "导入", + "description": "", + "operationId": "f2f992498d1082ef93becd8d872eac4a", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-forms/clone": { + "get": { + "tags": [ + "课程表单" + ], + "summary": "克隆表单", + "operationId": "26fa2f996832fad8fda399ffac9e1eba", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "from_course_id", + "in": "query", + "description": "来源课程id", + "schema": { + "type": "string" + } + }, + { + "name": "to_course_id", + "in": "query", + "description": "目标课程id", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-keeps/index": { + "get": { + "tags": [ + "考勤管理" + ], + "summary": "列表", + "description": "", + "operationId": "c60027a2708f7127a5778d3da1dea414", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "file_name", + "in": "query", + "description": "导出文件名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-keeps/show": { + "get": { + "tags": [ + "考勤管理" + ], + "summary": "详情", + "description": "", + "operationId": "bc866531362c5712cd24490d4ac39219", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-keeps/save": { + "post": { + "tags": [ + "考勤管理" + ], + "summary": "更新或新增", + "operationId": "9701d2bdb6656be8176a7eb1a082e34a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "访问令牌", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程ID", + "schema": { + "type": "integer" + } + }, + { + "name": "course_content_id", + "in": "query", + "description": "排课ID", + "schema": { + "type": "integer" + } + }, + { + "name": "user_id", + "in": "query", + "description": "用户ID", + "schema": { + "type": "integer" + } + }, + { + "name": "status", + "in": "query", + "description": "考勤状态(0缺勤,1正常)", + "schema": { + "type": "integer" + } + }, + { + "name": "date", + "in": "query", + "description": "考勤日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "time", + "in": "query", + "description": "考勤时间", + "schema": { + "type": "string", + "format": "date-time" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-keeps/destroy": { + "get": { + "tags": [ + "考勤管理" + ], + "summary": "删除", + "description": "", + "operationId": "223aef89cc377e79c6bd3d7a309e8c88", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course_keeps/excel-show": { + "post": { + "tags": [ + "考勤管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "26a2cb8a10d2bf8b2e7dfb86b2c5a190", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "里面包含course_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "file", + "in": "query", + "description": "文件。包含字段:学员名字,日期,考勤时间,状态", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-keeps/import": { + "post": { + "tags": [ + "考勤管理" + ], + "summary": "导入", + "description": "", + "operationId": "50628100aaf8d5626bca82509a938c7d", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/index": { + "get": { + "tags": [ + "报名管理" + ], + "summary": "列表", + "description": "", + "operationId": "c53c6d0af329f648b9c4e4168eb8d4c5", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "file_name", + "in": "query", + "description": "导出文件名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据.thirdAppointmentLogs第三方日志记录,thirdPlateLogs第三方车牌预约记录", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_name", + "in": "query", + "description": "公司名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_position", + "in": "query", + "description": "职务", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_area", + "in": "query", + "description": "所属区域", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_type", + "in": "query", + "description": "企业性质", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_industry", + "in": "query", + "description": "所属行业", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_schoolmate", + "in": "query", + "description": "is_schoolmate", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "education", + "in": "query", + "description": "education学历", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "filter_date", + "in": "query", + "description": "自定义字段筛选二维数组,包含键名name,value", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/show": { + "get": { + "tags": [ + "报名管理" + ], + "summary": "详情", + "description": "", + "operationId": "3ef520467da444a68441eded7386b30b", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据.thirdAppointmentLogs第三方日志记录,thirdPlateLogs第三方车牌预约记录", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/save": { + "post": { + "tags": [ + "报名管理" + ], + "summary": "更新或新增", + "operationId": "8803ce4fe51b25c4735d8bde371ca928", + "parameters": [ + { + "name": "update_user", + "in": "query", + "description": "是否更新用户信息0否1是", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程id", + "schema": { + "type": "string" + } + }, + { + "name": "title", + "in": "query", + "description": "标题", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "content", + "in": "query", + "description": "内容", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "status", + "in": "query", + "description": "状态0待审核1通过2拒绝3备选", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "reason", + "in": "query", + "description": "原因", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "score", + "in": "query", + "description": "分数", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "position", + "in": "query", + "description": "职位", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "fee_status", + "in": "query", + "description": "0未缴费1缴费成功2缴费失败3待确认", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "file_ids", + "in": "query", + "description": "附件id数组", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-signs/destroy": { + "get": { + "tags": [ + "报名管理" + ], + "summary": "删除", + "description": "", + "operationId": "0a422f4e709fb6cd2cf7ee6069dd1752", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/excel-show": { + "post": { + "tags": [ + "报名管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "9cc5f42a669c2e47cc954ae44b3f39bb", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/import": { + "post": { + "tags": [ + "报名管理" + ], + "summary": "导入", + "description": "", + "operationId": "0d52b99e4b8ea093fffd93a0525db980", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/batch-update-status": { + "post": { + "tags": [ + "报名管理" + ], + "summary": "批量修改审核状态", + "description": "", + "operationId": "198b9776ae8982aa478136a93283d9a4", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ids", + "in": "query", + "description": "英文逗号分隔的id数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "状态0待审核1通过2拒绝", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "reason", + "in": "query", + "description": "reason", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/batch-update-fee-status": { + "post": { + "tags": [ + "报名管理" + ], + "summary": "批量修改缴费状态", + "description": "", + "operationId": "d4a9c3ee591decfd9b4af959ca774faa", + "parameters": [ + { + "name": "ids", + "in": "query", + "description": "英文逗号分隔的id数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "fee_status", + "in": "query", + "description": "0未缴费1缴费成功2缴费失败", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/batch-notice": { + "post": { + "tags": [ + "报名管理" + ], + "summary": "批量发送缴费通知", + "description": "", + "operationId": "6593138f5f39ddd0d32c7471a327baa6", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ids", + "in": "query", + "description": "英文逗号分隔的id数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "content", + "in": "query", + "description": "发送内容", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-signs/retry-appointment": { + "get": { + "tags": [ + "报名管理" + ], + "summary": "重新发送第三方预约信息", + "description": "", + "operationId": "6f00aa5eeb9b6050a4983aa392abe11d", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-types/index": { + "get": { + "tags": [ + "课程类别" + ], + "summary": "列表", + "description": "", + "operationId": "b5eba398cb8624da725bdb04c80495dd", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-types/show": { + "get": { + "tags": [ + "课程类别" + ], + "summary": "详情", + "description": "", + "operationId": "f64e6348dfef33c47af5e366717bee87", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-types/save": { + "post": { + "tags": [ + "课程类别" + ], + "summary": "更新或新增", + "operationId": "649da1a2ea57c67bc4c2b1b25076a08e", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "验证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "配置名字", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "状态0禁用1启用", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "wait_tip", + "in": "query", + "description": "待审核提示", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "pass_tip", + "in": "query", + "description": "通过提示", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "fault_tip", + "in": "query", + "description": "不通过提示", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "back_tip", + "in": "query", + "description": "备选提示", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "year_total", + "in": "query", + "description": "年预约次数", + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/course-types/destroy": { + "get": { + "tags": [ + "课程类别" + ], + "summary": "删除", + "description": "", + "operationId": "5d7a2a7b4ffc50b46472ea483c3b4b21", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-types/excel-show": { + "post": { + "tags": [ + "课程类别" + ], + "summary": "导入预览", + "description": "", + "operationId": "670baacc934508947e38f648997c1976", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/course-types/import": { + "post": { + "tags": [ + "课程类别" + ], + "summary": "导入", + "description": "", + "operationId": "966b7cd8208939ed566984ae4a74f4bc", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/index": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "列表", + "description": "", + "operationId": "0b1750755af3319af2bbca10fac52dc1", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/real-table-index": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "获取实体数据表", + "description": "", + "operationId": "76b584eb528ef70c3b57906419110752", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/show": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "详情", + "description": "", + "operationId": "c28b3c78e085d578b8b8d2548e7fb862", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/real-table-show": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "获取实体表字段详情", + "description": "", + "operationId": "3a0852aea6a592e4f82aaa8a6c0b30d6", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "except", + "in": "query", + "description": "排除的字段名数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/save": { + "post": { + "tags": [ + "自定义表单" + ], + "summary": "更新", + "description": "", + "operationId": "d560b9e3a1247197b776605730beb029", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "Id(存在更新,不存在新增)", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "table_name", + "in": "query", + "description": "表名", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "relation", + "in": "query", + "description": "关联关系二维数组,包含字段:id存在更新,不存在新增,custom_form_field,link_table_name关联表名,link_relation关联关系,local_key本地字段,foreign_key关联表字段", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "fields", + "in": "query", + "description": "字段详情二维数组,包含字段:id存在更新,不存在新增。和其他字段详见字段更新接口", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/destroy": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "删除", + "description": "", + "operationId": "172be449a3f65455102b1c354fd84a9a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/relation-destroy": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "关联关系删除", + "description": "", + "operationId": "99a2c982970e1d3db53c5d16d7f37473", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "关联关系id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/update-table": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "数据表同步", + "description": "", + "operationId": "81e2deb6133c813ab874ae673f2e1926", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form/clone-table": { + "get": { + "tags": [ + "自定义表单" + ], + "summary": "克隆表结构", + "description": "", + "operationId": "83a83932e8ceff36011e176c1982653e", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "自定义表单表名", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form-field/index": { + "get": { + "tags": [ + "自定义表单字段" + ], + "summary": "列表", + "description": "", + "operationId": "61e668b036ec422261c707c1fef6d965", + "parameters": [ + { + "name": "custom_form_id", + "in": "query", + "description": "表id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form-field/show": { + "get": { + "tags": [ + "自定义表单字段" + ], + "summary": "详情", + "description": "", + "operationId": "46856168c3901d47e2e75e5b6826cd21", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form-field/save": { + "post": { + "tags": [ + "自定义表单字段" + ], + "summary": "更新", + "description": "", + "operationId": "7bbedc46a3effbf8d6fb31f7eb3bedea", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "Id(存在更新,不存在新增)", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "custom_form_id", + "in": "query", + "description": "表单id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "field", + "in": "query", + "description": "字段标示(汉字转拼音接口自动填充)", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "search_input", + "in": "query", + "description": "查询类型text输入框,radio单选,date_range日期范围选择,datetime_range日期时间范围选择", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "edit_input", + "in": "query", + "description": "编辑类型,从配置接口获取", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "排序", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "help", + "in": "query", + "description": "帮助文字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "validation", + "in": "query", + "description": "验证规则,config接口获取,一维数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "select_item", + "in": "query", + "description": "选择框选项", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "list_show", + "in": "query", + "description": "是否列表显示0和1", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "form_show", + "in": "query", + "description": "是否表单显示0和1", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_fix", + "in": "query", + "description": "是否固定0否1是", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "width", + "in": "query", + "description": "列宽度", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form-field/destroy": { + "get": { + "tags": [ + "自定义表单字段" + ], + "summary": "删除", + "description": "", + "operationId": "bfa4261e40462825865162011a328f51", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form-field/pinyin": { + "get": { + "tags": [ + "自定义表单字段" + ], + "summary": "汉字转拼音", + "description": "", + "operationId": "66540b5a3a661450be4385f679bc911c", + "parameters": [ + { + "name": "str", + "in": "query", + "description": "汉字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/custom-form-field/config": { + "get": { + "tags": [ + "自定义表单字段" + ], + "summary": "验证规则选项和编辑类型选项", + "description": "", + "operationId": "5b0ce8b3a8102cabcff05c1624e6045a", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/department": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取部门", + "description": "", + "operationId": "94d839b43560f5e94bb362f906d8a22f", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取部门" + } + } + } + }, + "/api/admin/department/show": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取部门详情", + "description": "", + "operationId": "4679dfab6b34f87596dbb1c3690aa3fc", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取部门" + } + } + } + }, + "/api/admin/department/save": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "保存部门", + "description": "", + "operationId": "d5946ac7c3ba761ca13e250c84f555c5", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "部门ID,为空表示新增,不为空表示更新", + "schema": { + "type": "integer" + } + }, + { + "name": "name", + "in": "query", + "description": "名称", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pid", + "in": "query", + "description": "父id,默认为0", + "schema": { + "type": "integer" + } + }, + { + "name": "manager_id", + "in": "query", + "description": "部门负责人ID", + "schema": { + "type": "integer" + } + }, + { + "name": "leader_id", + "in": "query", + "description": "部门分管人ID", + "schema": { + "type": "integer" + } + }, + { + "name": "sortnumber", + "in": "query", + "description": "同级排序,默认为0", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "保存部门" + } + } + } + }, + "/api/admin/department/delete": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "删除部门", + "description": "", + "operationId": "9fef22f933be4fcd1e732ccd2fd1e35a", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "ID", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "删除部门" + } + } + } + }, + "/api/admin/menu": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取菜单", + "description": "", + "operationId": "63d9065efe48814fea7ff1aff75e352b", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取菜单" + } + } + } + }, + "/api/admin/menu/show": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取菜单详情", + "description": "", + "operationId": "a9ac0af0b385e1b7b2e8706807f1be47", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取菜单" + } + } + } + }, + "/api/admin/menu/save": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "保存菜单", + "description": "", + "operationId": "3927c9c5ced2186bf414e49fcf5fe785", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "菜单ID,为空表示新增,不为空表示更新", + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名称", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pid", + "in": "query", + "description": "父id,默认为0", + "schema": { + "type": "string" + } + }, + { + "name": "url", + "in": "query", + "description": "页面路由", + "schema": { + "type": "string" + } + }, + { + "name": "ptah", + "in": "query", + "description": "路由", + "schema": { + "type": "string" + } + }, + { + "name": "api_prefix", + "in": "query", + "description": "API前缀(基于前后端约定同一个页面的API前缀相同)", + "schema": { + "type": "string" + } + }, + { + "name": "icon", + "in": "query", + "description": "图标样式", + "schema": { + "type": "string" + } + }, + { + "name": "visible", + "in": "query", + "description": "是否可见,默认为1", + "schema": { + "type": "string" + } + }, + { + "name": "auth_node_tags", + "in": "query", + "description": "绑定的权限节点tag,多个标示英文逗号分隔", + "schema": { + "type": "string" + } + }, + { + "name": "sortnumber", + "in": "query", + "description": "同级排序,默认为0", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "保存菜单" + } + } + } + }, + "/api/admin/menu/delete": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "删除菜单", + "description": "", + "operationId": "b555ee7c6cb8252db36c5af160f9a015", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "ID", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "删除菜单" + } + } + } + }, + "/api/admin/notifications/index": { + "get": { + "tags": [ + "通知管理" + ], + "summary": "列表", + "description": "", + "operationId": "93ff09d105fdeacb299e8c1b1a8d97a2", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/notifications/show": { + "get": { + "tags": [ + "通知管理" + ], + "summary": "详情", + "description": "", + "operationId": "f6218fbac1b87d89928a4aa341bd71c9", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/notifications/save": { + "post": { + "tags": [ + "通知管理" + ], + "summary": "重新发送", + "operationId": "4579829a2169cb12267db4acf0cd7382", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "消息id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/notifications/destroy": { + "get": { + "tags": [ + "通知管理" + ], + "summary": "删除", + "description": "", + "operationId": "36769340aa411d7cbfa5525836095514", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/operate-log/index": { + "get": { + "tags": [ + "操作日志" + ], + "summary": "列表", + "description": "", + "operationId": "898e3ea8176de2f2e45c908546a2b1f2", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "admin_id", + "in": "query", + "description": "管理员id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "内容", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/other/admin-user-list": { + "post": { + "tags": [ + "其他" + ], + "summary": "后台用户列表", + "description": "", + "operationId": "cc3b529c89b0bca19ec24623ba6fe837", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "department_id", + "in": "query", + "description": "部门id", + "required": false, + "schema": { + "type": "int" + } + }, + { + "name": "keyword", + "in": "query", + "description": "关键词", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/other/admin-department-list": { + "post": { + "tags": [ + "其他" + ], + "summary": "后台部门列表", + "description": "", + "operationId": "f4cf8d3e58b688c0e5ed89a20dbddd86", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码。不传则全部,传入则分页", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "description": "关键词", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_tree", + "in": "query", + "description": "是否显示树形结构 0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/other/table-fileds": { + "get": { + "tags": [ + "其他" + ], + "summary": "获取表字段", + "description": "", + "operationId": "f9ae89d3870d2313be027d91db581844", + "parameters": [ + { + "name": "table_name", + "in": "query", + "description": "table_name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "except", + "in": "query", + "description": "排除的字段数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/parameter/index": { + "get": { + "tags": [ + "数据参数字典" + ], + "summary": "数据参数字典列表", + "description": "", + "operationId": "1d06d4fb0d890b44517bb66d6cd1f2b1", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "number", + "in": "query", + "description": "编号", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "状态 0禁用 1启用", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/parameter/store": { + "post": { + "tags": [ + "数据参数字典" + ], + "summary": "添加数据参数字典", + "description": "", + "operationId": "143c606ca44e670840c2234c337a4cf3", + "parameters": [ + { + "name": "number", + "in": "query", + "description": "编号", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pid", + "in": "query", + "description": "父id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "排序", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "状态 0禁用1启用", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "remark", + "in": "query", + "description": "备注", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "detail_list", + "in": "query", + "description": "字典明细二维数组。包括:key数据源id,value数据值,sort排序,status状态0禁用1启用,remark备注", + "required": false, + "schema": { + "type": "object" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/parameter/show": { + "get": { + "tags": [ + "数据参数字典" + ], + "summary": "数据参数字典详情", + "description": "", + "operationId": "32d002bab4bca88636c64b140b359201", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id值或数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "number", + "in": "query", + "description": "number编号值或数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "pid", + "in": "query", + "description": "父id值或数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/parameter/save": { + "post": { + "tags": [ + "数据参数字典" + ], + "summary": "更新数据参数字典", + "description": "", + "operationId": "db745de23f8198982c6083d0f47de7a6", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "Id", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "number", + "in": "query", + "description": "编号", + "required": true, + "schema": { + "type": "int" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pid", + "in": "query", + "description": "父id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "排序", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "状态 0禁用1启用", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "remark", + "in": "query", + "description": "备注", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "detail_list", + "in": "query", + "description": "字典明细二维数组。包括:id数据原始id,有就传没有就传空,value数据值,sort排序,status状态0禁用1启用,remark备注", + "required": false, + "schema": { + "type": "object" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/parameter/delete": { + "get": { + "tags": [ + "数据参数字典" + ], + "summary": "删除数据参数字典", + "description": "", + "operationId": "a2578a0438837f0fcbe66460826c05f4", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "数据参数字典id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/parameter/detail-delete": { + "get": { + "tags": [ + "数据参数字典" + ], + "summary": "删除数据参数字典详情记录", + "description": "", + "operationId": "c042eb7796319e4e7291124e9cebb5ce", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "数据参数详情id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/role": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取角色", + "description": "", + "operationId": "432d0553165dc1c248421fa36871567e", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取角色" + } + } + } + }, + "/api/admin/role/show": { + "get": { + "tags": [ + "后台管理" + ], + "summary": "获取角色详情", + "description": "", + "operationId": "9815083cc76091a16a3388ba833efe31", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "获取角色" + } + } + } + }, + "/api/admin/role/save": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "保存角色", + "description": "", + "operationId": "80f92184eae29a6efd829fc0f82a6bf9", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "菜单ID,为空表示新增,不为空表示更新", + "schema": { + "type": "integer" + } + }, + { + "name": "name", + "in": "query", + "description": "名称", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "introduce", + "in": "query", + "description": "说明", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "allow_level", + "in": "query", + "description": "数据权限0全部1部分2自己", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "sortnumber", + "in": "query", + "description": "同级排序,默认为0", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "保存角色" + } + } + } + }, + "/api/admin/role/delete": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "删除角色", + "description": "", + "operationId": "dc85bbd29c8ecc9534c23543c2588f17", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "ID", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "删除角色" + } + } + } + }, + "/api/admin/role/set-permissions": { + "post": { + "tags": [ + "后台管理" + ], + "summary": "角色授权", + "description": "", + "operationId": "c6ac574837d7578e18a94b8ebfd79c36", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "in": "query", + "description": "ID", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "permission_list", + "in": "query", + "description": "二维数组形式,包括:permission_id权限id,auth_node_tags英文逗号分隔的权限标示", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "角色授权" + } + } + } + }, + "/api/admin/supply-demand/index": { + "get": { + "tags": [ + "供需信息管理" + ], + "summary": "列表", + "description": "", + "operationId": "0f7251b9f256e8fe64f2d0577499437f", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/supply-demand/show": { + "get": { + "tags": [ + "供需信息管理" + ], + "summary": "详情", + "description": "", + "operationId": "7b7e1c9c85848d37d22c6d2c34bcc04a", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/supply-demand/save": { + "post": { + "tags": [ + "供需信息管理" + ], + "summary": "更新或新增", + "operationId": "60da62531ba9ea53f0c0339709060101", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "需求供应表ID(存在则更新,不存在则新增)", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "title", + "in": "query", + "description": "标题", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "supply_demand_type_id", + "in": "query", + "description": "分类ID", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "content", + "in": "query", + "description": "内容", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "tag", + "in": "query", + "description": "标签", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "wechat", + "in": "query", + "description": "微信号", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "电话", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "email", + "in": "query", + "description": "邮箱", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "审核状态(0:待审核;1:通过;2:拒绝)", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/supply-demand/destroy": { + "get": { + "tags": [ + "供需信息管理" + ], + "summary": "删除", + "description": "", + "operationId": "8031bd3d6803d827fd962dc42e3b1066", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/teachers/index": { + "get": { + "tags": [ + "老师管理" + ], + "summary": "列表", + "description": "", + "operationId": "b9c77db2e25a7539cca27ea656a160b4", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/teachers/show": { + "get": { + "tags": [ + "老师管理" + ], + "summary": "详情", + "description": "", + "operationId": "8e50fd1d7d2f4ac4fba12b19895eae55", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/teachers/save": { + "post": { + "tags": [ + "时间段设置" + ], + "summary": "更新或新增", + "operationId": "32ce6f0497e018a7a40edda40159a67e", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "访问令牌", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "schema": { + "type": "integer" + } + }, + { + "name": "sex", + "in": "query", + "description": "性别", + "schema": { + "type": "string" + } + }, + { + "name": "speciality", + "in": "query", + "description": "专业", + "schema": { + "type": "string" + } + }, + { + "name": "theme", + "in": "query", + "description": "主题", + "schema": { + "type": "string" + } + }, + { + "name": "remark", + "in": "query", + "description": "备注", + "schema": { + "type": "string" + } + }, + { + "name": "introduce", + "in": "query", + "description": "介绍", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/teachers/destroy": { + "get": { + "tags": [ + "老师管理" + ], + "summary": "删除", + "description": "", + "operationId": "486544134d89a64d9fb4a0efe036e1fd", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/teachers/excel-show": { + "post": { + "tags": [ + "老师管理" + ], + "summary": "导入预览", + "description": "", + "operationId": "2ab672c4364b32a72a80f97df434a5ba", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/teachers/import": { + "post": { + "tags": [ + "老师管理" + ], + "summary": "导入", + "description": "", + "operationId": "e0731f9bed9c4b91e3044c3f19490739", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/upload-file": { + "post": { + "tags": [ + "其他" + ], + "summary": "上传文件", + "description": "", + "operationId": "2c233caa0e77aedf4bf95a402620b402", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "file" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/index": { + "get": { + "tags": [ + "用户信息" + ], + "summary": "所有用户列表", + "description": "", + "operationId": "0e65c24967a8ebe2771e38fdebdb4d27", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "export_fields", + "in": "query", + "description": "需要导出的字段数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "filter", + "in": "query", + "description": "查询条件。数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,包括:courses,courseSigns,teacher,courseSettings,coursePeriods", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/study": { + "get": { + "tags": [ + "用户信息" + ], + "summary": "学员管理(参与了课程的用户包含统计数据)", + "description": "", + "operationId": "3f874ae4d6232375fc98ec7b50499bb4", + "parameters": [ + { + "name": "is_export", + "in": "query", + "description": "是否导出0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "file_name", + "in": "query", + "description": "导出文件名", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "course_name", + "in": "query", + "description": "课程名称", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_name", + "in": "query", + "description": "公司名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_position", + "in": "query", + "description": "职务", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_area", + "in": "query", + "description": "所属区域", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_type", + "in": "query", + "description": "企业性质", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_industry", + "in": "query", + "description": "所属行业", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "courses_start_date", + "in": "query", + "description": "课程开始时间", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "courses_end_date", + "in": "query", + "description": "课程结束时间", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_vip", + "in": "query", + "description": "是否vip0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "courses_ing", + "in": "query", + "description": "是否课程进行中0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_schoolmate", + "in": "query", + "description": "is_schoolmate", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "mobile", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "审核状态", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "course_type", + "in": "query", + "description": "course_type", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "company_has_share", + "in": "query", + "description": "是否有股份", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "keyword", + "in": "query", + "description": "关键词", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start_company_date", + "in": "query", + "description": "开始成立日期", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "end_company_date", + "in": "query", + "description": "结束成立日期", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start_birthday", + "in": "query", + "description": "开始出生日期", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "end_birthday", + "in": "query", + "description": "结束出生日期", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "company_need_fund", + "in": "query", + "description": "是否需要融资", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "is_fee", + "in": "query", + "description": "是否缴费0否1是", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "has_openid", + "in": "query", + "description": "是否绑定小程序0否1是", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "year", + "in": "query", + "description": "年份", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/show": { + "get": { + "tags": [ + "用户信息" + ], + "summary": "详情", + "description": "", + "operationId": "e1c7e516645ea3e01d9228642f1f2e9d", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "show_relation", + "in": "query", + "description": "需要输出的关联关系数组,填写输出指定数据", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/save": { + "post": { + "tags": [ + "时间段设置" + ], + "summary": "更新或新增", + "operationId": "223b4be53194747c01738c8fa4b18041", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "课程ID(存在则更新,不存在则新增)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "token", + "in": "query", + "description": "访问令牌", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "openid", + "in": "query", + "description": "用户openid", + "schema": { + "type": "string" + } + }, + { + "name": "sex", + "in": "query", + "description": "性别男/女", + "schema": { + "type": "string" + } + }, + { + "name": "nickname", + "in": "query", + "description": "昵称", + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "手机号", + "schema": { + "type": "string" + } + }, + { + "name": "country", + "in": "query", + "description": "国家", + "schema": { + "type": "string" + } + }, + { + "name": "province", + "in": "query", + "description": "省份", + "schema": { + "type": "string" + } + }, + { + "name": "city", + "in": "query", + "description": "城市", + "schema": { + "type": "string" + } + }, + { + "name": "headimgurl", + "in": "query", + "description": "头像URL", + "schema": { + "type": "string" + } + }, + { + "name": "username", + "in": "query", + "description": "用户名", + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "query", + "description": "密码", + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "schema": { + "type": "string" + } + }, + { + "name": "birthday", + "in": "query", + "description": "生日", + "schema": { + "type": "string" + } + }, + { + "name": "email", + "in": "query", + "description": "邮箱", + "schema": { + "type": "string" + } + }, + { + "name": "education", + "in": "query", + "description": "学历", + "schema": { + "type": "integer" + } + }, + { + "name": "school", + "in": "query", + "description": "学校", + "schema": { + "type": "string" + } + }, + { + "name": "speciality", + "in": "query", + "description": "专业", + "schema": { + "type": "string" + } + }, + { + "name": "honour", + "in": "query", + "description": "荣誉", + "schema": { + "type": "string" + } + }, + { + "name": "introduce", + "in": "query", + "description": "介绍", + "schema": { + "type": "string" + } + }, + { + "name": "company_name", + "in": "query", + "description": "公司名称", + "schema": { + "type": "string" + } + }, + { + "name": "company_position", + "in": "query", + "description": "个人职务", + "schema": { + "type": "string" + } + }, + { + "name": "company_has_share", + "in": "query", + "description": "是否有股份0否1是", + "schema": { + "type": "string" + } + }, + { + "name": "company_build_date", + "in": "query", + "description": "公司成立日期", + "schema": { + "type": "string" + } + }, + { + "name": "company_area", + "in": "query", + "description": "公司区域-数据字典", + "schema": { + "type": "string" + } + }, + { + "name": "company_type", + "in": "query", + "description": "公司性质-数据字典", + "schema": { + "type": "string" + } + }, + { + "name": "company_industry", + "in": "query", + "description": "公司所属行业-数据字典", + "schema": { + "type": "string" + } + }, + { + "name": "company_business", + "in": "query", + "description": "公司主营业务", + "schema": { + "type": "string" + } + }, + { + "name": "company_fund", + "in": "query", + "description": "公司融资情况0否1是", + "schema": { + "type": "string" + } + }, + { + "name": "company_need_fund", + "in": "query", + "description": "公司是否需要融资0否1是", + "schema": { + "type": "integer" + } + }, + { + "name": "sign_from", + "in": "query", + "description": "报名信息来源", + "schema": { + "type": "string" + } + }, + { + "name": "remark", + "in": "query", + "description": "备注", + "schema": { + "type": "string" + } + }, + { + "name": "has_appointment_total", + "in": "query", + "description": "预约剩余次数", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/admin/users/destroy": { + "get": { + "tags": [ + "用户信息" + ], + "summary": "删除", + "description": "", + "operationId": "8e3cbeb0566f9efba6c2d2fc2fb3b707", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/excel-show": { + "post": { + "tags": [ + "用户信息" + ], + "summary": "导入预览", + "description": "", + "operationId": "ad1513c76e93120171377bdd24021da3", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/import": { + "post": { + "tags": [ + "用户信息" + ], + "summary": "导入", + "description": "", + "operationId": "1658fd176abf9de13048032aec3935c2", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/import-study": { + "post": { + "tags": [ + "用户信息" + ], + "summary": "导入学员信息(旧的校友库导入)", + "description": "", + "operationId": "85d3cac0c7e39908ce9c48b2376797a3", + "parameters": [ + { + "name": "data", + "in": "query", + "description": "导入分析获取到的二维数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/admin/users/batch-update-schoolmate": { + "post": { + "tags": [ + "用户信息" + ], + "summary": "设置取消校友库", + "description": "", + "operationId": "63f36c757324a37e05099c7ec7f4cd29", + "parameters": [ + { + "name": "ids", + "in": "query", + "description": "英文逗号分隔的id数组", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "is_schoolmate", + "in": "query", + "description": "是否校友库-0否1是", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/mobile/course/notices": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "通知公告", + "operationId": "c89adc994f0e7e02c1ef62b0aa96f94c", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/course": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "课程列表", + "operationId": "18e8ec736e952dd5385462b6dc66cc3a", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_name", + "in": "query", + "description": "排序字段名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort_type", + "in": "query", + "description": "排序类型", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "课程类型", + "schema": { + "type": "integer" + } + }, + { + "name": "status", + "in": "query", + "description": "状态", + "schema": { + "type": "integer" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/course-detail": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "课程详情", + "operationId": "2a58b695a93f7f214a77317134d8cf1f", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/course-detail-pc": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "课程详情PC", + "operationId": "6cfdce8dbd8b459da386bc3f40778e77", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/sign": { + "post": { + "tags": [ + "小程序-课程" + ], + "summary": "报名", + "operationId": "b99397a5c70340888a6883a0badde8cd", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "is_change", + "in": "query", + "description": "用户数据是否变化0否1是", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "change_data", + "in": "query", + "description": "变化的数组,键值对形式的一维数组", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "data", + "in": "query", + "description": "自定义数据的数据,二维数组。包括键名:name,field,value", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/my-course": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "我的课程", + "operationId": "b17ac0faa67da3f9ac681171d26b9f00", + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/my-course-content": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "我的课表", + "operationId": "232c814681b5da5edec505a0ec95808a", + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/get-sign": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "课程报名详情", + "operationId": "064d84918d3397ffec01adab588cd0da", + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/update-sign": { + "post": { + "tags": [ + "小程序-课程" + ], + "summary": "更新报名信息", + "operationId": "ed2ceffab06b5600cb3cce658b5ea668", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "报名id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "fee_file_ids", + "in": "query", + "description": "文件id数组", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/contents": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "课表", + "operationId": "2e9349656fbeb25f528ed45dcc060f14", + "parameters": [ + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/user-list": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "校友库和本班通讯录", + "operationId": "9412a8e90e1580453b460c99a9eead1d", + "parameters": [ + { + "name": "type", + "in": "query", + "description": "类型1校友库2本班通讯录", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "course_id", + "in": "query", + "description": "课程id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_business", + "in": "query", + "description": "主营业务", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_name", + "in": "query", + "description": "公司名字", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_position", + "in": "query", + "description": "职务", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_area", + "in": "query", + "description": "所属区域", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_type", + "in": "query", + "description": "企业性质", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "company_industry", + "in": "query", + "description": "所属行业", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "letter", + "in": "query", + "description": "首字母", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/news": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "文章列表", + "operationId": "f9b20de2bae8ad2f4f8fdca70ec6d120", + "parameters": [ + { + "name": "page_size", + "in": "query", + "description": "每页显示的条数", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/course/news-detail": { + "get": { + "tags": [ + "小程序-课程" + ], + "summary": "文章详情", + "operationId": "87d328e01768df3b8ba7c09d04d2833d", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/other/config": { + "get": { + "tags": [ + "小程序-其他" + ], + "summary": "获取配置信息", + "operationId": "f7601d94f6103fd195caad54e079a992", + "parameters": [ + { + "name": "appointment_type_id", + "in": "query", + "description": "场地类型", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/other/banner": { + "get": { + "tags": [ + "小程序-其他" + ], + "summary": "获取banner", + "operationId": "b2a8ae8e05645e34def69a97cae0cd6e", + "parameters": [ + { + "name": "position", + "in": "query", + "description": "位置1首页", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/schedule/index": { + "get": { + "tags": [ + "小程序-预约管理" + ], + "summary": "预约列表", + "description": "", + "operationId": "d417d99cfc0f00c75929ef9a539e1b6d", + "parameters": [ + { + "name": "status", + "in": "query", + "description": "status", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "page", + "in": "query", + "description": "页码", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/schedule/detail": { + "get": { + "tags": [ + "小程序-预约管理" + ], + "summary": "预约详情", + "description": "", + "operationId": "e065b8209c8c9a8bdced5bdae9fc1248", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/schedule/check": { + "get": { + "tags": [ + "小程序-预约管理" + ], + "summary": "检测是否可预约", + "description": "", + "operationId": "d52e662f5cba313152551cc8f741b526", + "parameters": [ + { + "name": "site", + "in": "query", + "description": "预约地点id,从config接口获取", + "schema": { + "type": "integer" + } + }, + { + "name": "myself", + "in": "query", + "description": "是否检测自己的数据0否1是", + "schema": { + "type": "integer" + } + }, + { + "name": "start_time", + "in": "query", + "description": "开始时间,例如:2023-01-01 11:11:11", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "end_time", + "in": "query", + "description": "结束时间,例如:2023-01-01 11:11:11", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/schedule/save": { + "post": { + "tags": [ + "小程序-预约管理" + ], + "summary": "创建更新预约", + "description": "", + "operationId": "646a96c009204748b4bfa8f477d3207c", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "存在更新,不存在新增", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "date", + "in": "query", + "description": "预约日期", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "start_time", + "in": "query", + "description": "开始时间,例如:2023-01-01 11:11:11", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "end_time", + "in": "query", + "description": "结束时间,例如:2023-01-01 11:11:11", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "content", + "in": "query", + "description": "预约事项", + "schema": { + "type": "string" + } + }, + { + "name": "site", + "in": "query", + "description": "预约地点id,从config接口获取", + "schema": { + "type": "integer" + } + }, + { + "name": "plate", + "in": "query", + "description": "车牌号。多个英文逗号分隔", + "schema": { + "type": "string" + } + }, + { + "name": "accompany_total", + "in": "query", + "description": "陪同人数", + "schema": { + "type": "integer" + } + }, + { + "name": "status", + "in": "query", + "description": "状态 0未审核 1审核通过 2审核不通过3取消", + "schema": { + "type": "integer" + } + }, + { + "name": "reason", + "in": "query", + "description": "审核不通过原因", + "schema": { + "type": "string" + } + }, + { + "name": "accompany", + "in": "query", + "description": "陪同人员,二维数组,包括:name,idcard,mobile", + "schema": { + "type": "string" + } + }, + { + "name": "idcard", + "in": "query", + "description": "身份证号码", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/schedule/cancel": { + "get": { + "tags": [ + "小程序-预约管理" + ], + "summary": "取消预约", + "description": "", + "operationId": "7755b60b50d4ca3d470e9634edada88b", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/supply-demand/detail": { + "get": { + "tags": [ + "小程序-供需" + ], + "summary": "详情", + "operationId": "8807f44957ff9c1a35ee5a579eb9816e", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/supply-demand/save": { + "post": { + "tags": [ + "小程序-供需" + ], + "summary": "更新", + "description": "", + "operationId": "c569f0cddb4ef0c7880bcea7872a8a40", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "需求供应表ID(存在则更新,不存在则新增)", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "title", + "in": "query", + "description": "标题", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "supply_demand_type_id", + "in": "query", + "description": "分类ID", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "content", + "in": "query", + "description": "内容", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "tag", + "in": "query", + "description": "标签", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "wechat", + "in": "query", + "description": "微信号", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "电话", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "email", + "in": "query", + "description": "邮箱", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "description": "审核状态(0:待审核;1:通过;2:拒绝)", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/mobile/supply-demand/destroy": { + "get": { + "tags": [ + "小程序-供需" + ], + "summary": "删除", + "description": "", + "operationId": "a7633209b8e2c6f497e4d4cc25e4efb0", + "parameters": [ + { + "name": "id", + "in": "query", + "description": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/mobile/supply-demand/send-message": { + "get": { + "tags": [ + "小程序-供需" + ], + "summary": "发送消息", + "description": "", + "operationId": "6c8c72c97e564e881bf18555dbf01c5e", + "parameters": [ + { + "name": "supply_demand_id", + "in": "query", + "description": "供需信息id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "content", + "in": "query", + "description": "内容", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "to_user_id", + "in": "query", + "description": "接收人用户id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/mobile/upload-file": { + "post": { + "tags": [ + "小程序-其他" + ], + "summary": "上传文件", + "description": "", + "operationId": "35f4fde3cda084187506b95c8d056e21", + "parameters": [ + { + "name": "file", + "in": "query", + "description": "文件", + "required": true, + "schema": { + "type": "file" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "暂无" + } + } + } + }, + "/api/mobile/user/applet-login": { + "get": { + "tags": [ + "小程序-用户管理" + ], + "summary": "小程序静默登陆", + "operationId": "6637e6acb7458523a306be7c1ed75bd4", + "parameters": [ + { + "name": "code", + "in": "query", + "description": "code", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "pid", + "in": "query", + "description": "上级id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/user/account-login": { + "get": { + "tags": [ + "小程序-用户管理" + ], + "summary": "账号密码登陆", + "operationId": "b2dcb7c5702d3d65045573682c902587", + "parameters": [ + { + "name": "mobile", + "in": "query", + "description": "mobile", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "query", + "description": "password", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/user/update-user": { + "post": { + "tags": [ + "小程序-用户管理" + ], + "summary": "更新用户信息", + "operationId": "10397159c5f07743d3386bb7f1277833", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "认证token", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "openid", + "in": "query", + "description": "用户的openid", + "schema": { + "type": "string" + } + }, + { + "name": "sex", + "in": "query", + "description": "性别男/女", + "schema": { + "type": "string" + } + }, + { + "name": "nickname", + "in": "query", + "description": "昵称", + "schema": { + "type": "string" + } + }, + { + "name": "mobile", + "in": "query", + "description": "手机号", + "schema": { + "type": "string" + } + }, + { + "name": "country", + "in": "query", + "description": "国家", + "schema": { + "type": "string" + } + }, + { + "name": "province", + "in": "query", + "description": "省份", + "schema": { + "type": "string" + } + }, + { + "name": "city", + "in": "query", + "description": "城市", + "schema": { + "type": "string" + } + }, + { + "name": "headimgurl", + "in": "query", + "description": "头像url", + "schema": { + "type": "string" + } + }, + { + "name": "username", + "in": "query", + "description": "用户名", + "schema": { + "type": "string" + } + }, + { + "name": "old_password", + "in": "query", + "description": "旧密码", + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "query", + "description": "密码", + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "名字", + "schema": { + "type": "string" + } + }, + { + "name": "birthday", + "in": "query", + "description": "生日", + "schema": { + "type": "string" + } + }, + { + "name": "email", + "in": "query", + "description": "邮箱", + "schema": { + "type": "string" + } + }, + { + "name": "education", + "in": "query", + "description": "学历", + "schema": { + "type": "integer" + } + }, + { + "name": "school", + "in": "query", + "description": "学校", + "schema": { + "type": "string" + } + }, + { + "name": "speciality", + "in": "query", + "description": "专业", + "schema": { + "type": "string" + } + }, + { + "name": "honour", + "in": "query", + "description": "荣誉", + "schema": { + "type": "string" + } + }, + { + "name": "introduce", + "in": "query", + "description": "介绍", + "schema": { + "type": "string" + } + }, + { + "name": "company_name", + "in": "query", + "description": "公司名称", + "schema": { + "type": "string" + } + }, + { + "name": "company_position", + "in": "query", + "description": "个人职务", + "schema": { + "type": "string" + } + }, + { + "name": "company_has_share", + "in": "query", + "description": "是否有股份", + "schema": { + "type": "string" + } + }, + { + "name": "company_build_date", + "in": "query", + "description": "公司成立日期", + "schema": { + "type": "string" + } + }, + { + "name": "company_area", + "in": "query", + "description": "公司区域", + "schema": { + "type": "string" + } + }, + { + "name": "company_type", + "in": "query", + "description": "公司性质", + "schema": { + "type": "string" + } + }, + { + "name": "company_industry", + "in": "query", + "description": "公司所属行业", + "schema": { + "type": "string" + } + }, + { + "name": "company_business", + "in": "query", + "description": "公司主营业务", + "schema": { + "type": "string" + } + }, + { + "name": "company_fund", + "in": "query", + "description": "公司融资情况", + "schema": { + "type": "string" + } + }, + { + "name": "company_need_fund", + "in": "query", + "description": "公司是否需要融资", + "schema": { + "type": "boolean" + } + }, + { + "name": "sign_from", + "in": "query", + "description": "报名信息来源", + "schema": { + "type": "string" + } + }, + { + "name": "remark", + "in": "query", + "description": "备注", + "schema": { + "type": "string" + } + }, + { + "name": "idcard", + "in": "query", + "description": "身份证号码", + "schema": { + "type": "string" + } + }, + { + "name": "plate", + "in": "query", + "description": "车牌号多个英文逗号分隔", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "人才类型", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/user/get-user-info": { + "get": { + "tags": [ + "小程序-用户管理" + ], + "summary": "获取用户信息", + "operationId": "a8c6f34c09cf8a2007e694e7a7b16450", + "parameters": [ + { + "name": "token", + "in": "query", + "description": "token", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "操作成功" + } + } + } + }, + "/api/mobile/user/mobile": { + "get": { + "tags": [ + "小程序-用户管理" + ], + "summary": "获取微信授权手机号", + "description": "", + "operationId": "14a7843f4ffaafef7278beb04b20fbfe", + "parameters": [ + { + "name": "code", + "in": "query", + "description": "code", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/user/bind-mobile": { + "get": { + "tags": [ + "手机端-用户管理" + ], + "summary": "验证码绑定手机号", + "description": "", + "operationId": "6889ff023b0d44b475a30bad8b8b4609", + "parameters": [ + { + "name": "mobile", + "in": "query", + "description": "手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "code", + "in": "query", + "description": "验证码", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "is_bind", + "in": "query", + "description": "是否绑定手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/user/check-mobile": { + "get": { + "tags": [ + "手机端-用户管理" + ], + "summary": "检测手机号", + "description": "", + "operationId": "6e0ac349cb29f5045cbc0629faa5f754", + "parameters": [ + { + "name": "mobile", + "in": "query", + "description": "手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "code", + "in": "query", + "description": "验证码", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/user/send-sms": { + "get": { + "tags": [ + "手机端-用户管理" + ], + "summary": "短信发送", + "description": "", + "operationId": "8e1407f35b2364f5b101060be968d510", + "parameters": [ + { + "name": "mobile", + "in": "query", + "description": "手机号", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/mobile/user/update-donates": { + "post": { + "tags": [ + "手机端-用户管理" + ], + "summary": "新增校友捐赠", + "description": "", + "operationId": "290838cc1429305bc68b828607266b90", + "parameters": [ + { + "name": "xxx", + "in": "query", + "description": "字段", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "token", + "in": "query", + "description": "token", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + } + } + } + }, + "tags": [ + { + "name": "后台管理", + "description": "后台管理" + }, + { + "name": "地点配置管理", + "description": "地点配置管理" + }, + { + "name": "预约管理", + "description": "预约管理" + }, + { + "name": "地点类型管理", + "description": "地点类型管理" + }, + { + "name": "权限", + "description": "权限" + }, + { + "name": "Banner图管理", + "description": "Banner图管理" + }, + { + "name": "通用接口", + "description": "通用接口" + }, + { + "name": "自定义表单增删改查操作", + "description": "自定义表单增删改查操作" + }, + { + "name": "配置管理", + "description": "配置管理" + }, + { + "name": "预约次数管理", + "description": "预约次数管理" + }, + { + "name": "排课", + "description": "排课" + }, + { + "name": "课程管理", + "description": "课程管理" + }, + { + "name": "课程表单", + "description": "课程表单" + }, + { + "name": "考勤管理", + "description": "考勤管理" + }, + { + "name": "报名管理", + "description": "报名管理" + }, + { + "name": "课程类别", + "description": "课程类别" + }, + { + "name": "自定义表单", + "description": "自定义表单" + }, + { + "name": "自定义表单字段", + "description": "自定义表单字段" + }, + { + "name": "通知管理", + "description": "通知管理" + }, + { + "name": "操作日志", + "description": "操作日志" + }, + { + "name": "其他", + "description": "其他" + }, + { + "name": "数据参数字典", + "description": "数据参数字典" + }, + { + "name": "供需信息管理", + "description": "供需信息管理" + }, + { + "name": "老师管理", + "description": "老师管理" + }, + { + "name": "时间段设置", + "description": "时间段设置" + }, + { + "name": "用户信息", + "description": "用户信息" + }, + { + "name": "小程序-课程", + "description": "小程序-课程" + }, + { + "name": "小程序-其他", + "description": "小程序-其他" + }, + { + "name": "小程序-预约管理", + "description": "小程序-预约管理" + }, + { + "name": "小程序-供需", + "description": "小程序-供需" + }, + { + "name": "小程序-用户管理", + "description": "小程序-用户管理" + }, + { + "name": "手机端-用户管理", + "description": "手机端-用户管理" + } + ] +} \ No newline at end of file From 675c1d1e2766ef171e4b12fa33117bab61fa83a6 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 10:20:10 +0800 Subject: [PATCH 02/42] update --- .../migrations/2025_06_24_111502_alert_course_contents_table.php | 1 - 1 file changed, 1 deletion(-) diff --git a/database/migrations/2025_06_24_111502_alert_course_contents_table.php b/database/migrations/2025_06_24_111502_alert_course_contents_table.php index e95daca..860ef28 100644 --- a/database/migrations/2025_06_24_111502_alert_course_contents_table.php +++ b/database/migrations/2025_06_24_111502_alert_course_contents_table.php @@ -25,7 +25,6 @@ return new class extends Migration $table->json('file_ids')->nullable()->comment('文件id数组'); // 详细地址 $table->string('address_detail')->nullable()->comment('详细地址'); - $table->string('sex')->nullable()->comment('性别'); $table->string('mobile')->nullable()->comment('联系方式'); }); } From 515219af322e89a42391dba90a9b41721b54d7f7 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 10:21:04 +0800 Subject: [PATCH 03/42] update --- .../migrations/2025_06_24_111502_alert_course_contents_table.php | 1 - 1 file changed, 1 deletion(-) diff --git a/database/migrations/2025_06_24_111502_alert_course_contents_table.php b/database/migrations/2025_06_24_111502_alert_course_contents_table.php index 860ef28..97fd29b 100644 --- a/database/migrations/2025_06_24_111502_alert_course_contents_table.php +++ b/database/migrations/2025_06_24_111502_alert_course_contents_table.php @@ -25,7 +25,6 @@ return new class extends Migration $table->json('file_ids')->nullable()->comment('文件id数组'); // 详细地址 $table->string('address_detail')->nullable()->comment('详细地址'); - $table->string('mobile')->nullable()->comment('联系方式'); }); } From c8ae055341cc93121f21888f2d2d76a734c46181 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 10:54:07 +0800 Subject: [PATCH 04/42] update --- app/Console/Commands/UpdateUserNo.php | 37 ++++++++++++--- .../Mobile/SupplyDemandController.php | 2 +- .../Controllers/Mobile/UserController.php | 2 - app/Models/User.php | 45 ------------------- 4 files changed, 33 insertions(+), 53 deletions(-) diff --git a/app/Console/Commands/UpdateUserNo.php b/app/Console/Commands/UpdateUserNo.php index b3ed7d5..2ed7c8e 100755 --- a/app/Console/Commands/UpdateUserNo.php +++ b/app/Console/Commands/UpdateUserNo.php @@ -2,6 +2,8 @@ namespace App\Console\Commands; +use App\Models\Course; +use App\Models\CourseSign; use App\Models\User; use App\Repositories\MeetRepository; use Illuminate\Console\Command; @@ -40,13 +42,38 @@ class UpdateUserNo extends Command */ public function handle() { - $users = User::whereNull('no')->get(); - foreach ($users as $user) { - $no = User::updateNo($user->id); - $this->info($no . '更新成功'); + // 已经开始的课程日期 + $dateList = Course::whereNotNull('start_date') + ->where('start_date', '<=', date('Y-m-d')) + ->orderBy('start_date') + ->groupBy('start_date') + ->pluck('start_date') + ->toArray(); + foreach ($dateList as $date) { + $courses = Course::with(['courseSigns' => function ($query) { + $query->where('status', 1); + }])->where('start_date', $date) + ->orderBy('start_date') + ->get(); + $i = 1; + // 编号前缀 + $prefix = date('Ymd', strtotime($date)); + foreach ($courses as $course) { + foreach ($course->courseSigns as $sign) { + $user = User::find($sign->user_id); + if ($user->no) { + continue; + } + $no = $prefix . str_pad($i, 3, '0', STR_PAD_LEFT); + // 更新用户编号 + $user->no = $no; + $user->save(); + $this->info($no); + $i++; + } + } } return $this->info('更新完成'); } - } diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index f53a407..57f00e5 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -105,7 +105,7 @@ class SupplyDemandController extends CommonController } $detail = SupplyDemand::with([ 'user' => function ($query) { - $query->select('id', 'nickname', 'name', 'headimgurl'); + $query->select('id', 'nickname', 'name', 'headimgurl', 'username'); } ])->find($all['id']); // 增加view_count diff --git a/app/Http/Controllers/Mobile/UserController.php b/app/Http/Controllers/Mobile/UserController.php index c1729a3..610f12f 100755 --- a/app/Http/Controllers/Mobile/UserController.php +++ b/app/Http/Controllers/Mobile/UserController.php @@ -74,8 +74,6 @@ class UserController extends CommonController $score = Config::getValueByKey('share_score'); ScoreLog::add($pid, $score, '分享获得'); } - // 更新编号 - User::updateNo($user->id); } $token = $user->createToken("mobile-token")->plainTextToken; return $this->success(compact('token')); diff --git a/app/Models/User.php b/app/Models/User.php index 570d36d..3eda1ab 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -182,49 +182,4 @@ class User extends Authenticatable implements Auditable return $user->appointment_total - $useTotal >= 0 ? $user->appointment_total - $useTotal : 0; } - /** - * 更新用户编号 - */ - public static function updateNo($userId) - { - // todo::编号可能回重复,还需要详细排查 - $user = self::find($userId); - if (!empty($user->no)) { - return false; - } - // 获取最早一条审核通过的报名数据 - $courseSigns = CourseSign::with('course') - ->where('user_id', $userId) - ->where('status', 1) - ->orderBy('created_at', 'asc') - ->first(); - if (empty($courseSigns)) { - return false; - } - if (empty($courseSigns->course->start_date)) { - return false; - } - // 编号前缀 - $prefix = date('Ymd', strtotime($courseSigns->course->start_date)); - // 获取同一天开始的所有课程 - $course = Course::where('start_date', $courseSigns->course->start_date)->orderBy('created_at', 'asc')->get(); - // 获取同一天开始所有课程的报名信息 - $courseSignsList = CourseSign::whereIn('id', function ($query) use ($course) { - $query->from('course_signs') - ->where('status', 1) - ->whereIn('course_id', $course->pluck('id')) - ->selectRaw('MIN(id)') - ->groupBy('user_id'); - })->orderBy('created_at', 'asc')->get(); - - // 获取当前用户id在$courseSigns中第几位 - $index = $courseSignsList->search(function ($item) use ($user) { - return $item->user_id == $user->id; - }); - $no = $prefix . str_pad($index + 1, 3, '0', STR_PAD_LEFT); - $user->no = $no; - $user->save(); - return $user->no; - } - } From 160f7f2d6d18c4ce9274630ef0e3f0cb77e10798 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 10:57:51 +0800 Subject: [PATCH 05/42] update --- app/Console/Commands/UpdateUserNo.php | 16 +++++++++------- app/Console/Kernel.php | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/Console/Commands/UpdateUserNo.php b/app/Console/Commands/UpdateUserNo.php index 2ed7c8e..2981c2e 100755 --- a/app/Console/Commands/UpdateUserNo.php +++ b/app/Console/Commands/UpdateUserNo.php @@ -42,13 +42,15 @@ class UpdateUserNo extends Command */ public function handle() { - // 已经开始的课程日期 - $dateList = Course::whereNotNull('start_date') - ->where('start_date', '<=', date('Y-m-d')) - ->orderBy('start_date') - ->groupBy('start_date') - ->pluck('start_date') - ->toArray(); + // 已经开始的课程日期(所有历史数据处理) +// $dateList = Course::whereNotNull('start_date') +// ->where('start_date', '<=', date('Y-m-d')) +// ->orderBy('start_date') +// ->groupBy('start_date') +// ->pluck('start_date') +// ->toArray(); + // 当日数据处理(日常定时任务) + $dateList = [date('Y-m-d')]; foreach ($dateList as $date) { $courses = Course::with(['courseSigns' => function ($query) { $query->where('status', 1); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 4d120d6..1be6ee8 100755 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -26,6 +26,8 @@ class Kernel extends ConsoleKernel $schedule->command('send_email')->everyMinute(); // 推送课程人员信息 $schedule->command('push_courses')->dailyAt('23:00'); + // 更新学员编号 + $schedule->command('update_user_no')->dailyAt('00:05'); } /** From a6f8bc8dbc03152f076438f8c11fd011db152633 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 11:01:49 +0800 Subject: [PATCH 06/42] update --- app/Http/Controllers/Mobile/SupplyDemandController.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index 57f00e5..6d15121 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -48,17 +48,16 @@ class SupplyDemandController extends CommonController public function index() { $all = request()->all(); + $status = request('status', 1); $supplyDemands = SupplyDemand::with([ 'user' => function ($query) { $query->select('id', 'nickname', 'name', 'headimgurl', 'username'); } - ])->where(function ($query) use ($all) { + ])->where(function ($query) use ($all, $status) { + $query->where('status', $status); if (isset($all['type'])) { $query->where('type', $all['type']); } - if (isset($all['status'])) { - $query->where('status', $all['status']); - } if (isset($all['keyword'])) { $query->where('content', 'like', '%' . $all['keyword'] . '%'); } From 0310045caa03f7cf96866c39537379c13dba63fd Mon Sep 17 00:00:00 2001 From: weizong song Date: Sat, 9 Aug 2025 11:19:07 +0800 Subject: [PATCH 07/42] up --- .../Commands/GenerateSupplyDemandDemo.php | 30 +++ .../SupplyDemandTestDataGenerator.php | 181 ++++++++++++++++++ database/seeders/SupplyDemandDemoSeeder.php | 19 ++ docs/supply_demand_module_analysis.md | 96 ++++++++++ storage/api-docs/api-docs.json | 0 5 files changed, 326 insertions(+) create mode 100644 app/Console/Commands/GenerateSupplyDemandDemo.php create mode 100644 app/Services/TestData/SupplyDemandTestDataGenerator.php create mode 100644 database/seeders/SupplyDemandDemoSeeder.php create mode 100644 docs/supply_demand_module_analysis.md mode change 100644 => 100755 storage/api-docs/api-docs.json diff --git a/app/Console/Commands/GenerateSupplyDemandDemo.php b/app/Console/Commands/GenerateSupplyDemandDemo.php new file mode 100644 index 0000000..646d8b3 --- /dev/null +++ b/app/Console/Commands/GenerateSupplyDemandDemo.php @@ -0,0 +1,30 @@ +option('count'); + $users = (int)$this->option('users'); + + $this->info("开始生成:供需 {$count} 条,最少用户 {$users} 个..."); + $generator = new SupplyDemandTestDataGenerator(); + $generator->generate($count, $users, function (string $msg) { + $this->line($msg); + }); + + $this->info('生成完成'); + return self::SUCCESS; + } +} + + diff --git a/app/Services/TestData/SupplyDemandTestDataGenerator.php b/app/Services/TestData/SupplyDemandTestDataGenerator.php new file mode 100644 index 0000000..2f00268 --- /dev/null +++ b/app/Services/TestData/SupplyDemandTestDataGenerator.php @@ -0,0 +1,181 @@ +create(); + } + + $allUsers = User::query()->get(['id', 'name', 'nickname', 'username']); + if ($allUsers->count() < 2) { + throw new \RuntimeException('生成对话与消息至少需要2个用户'); + } + + // 2) 生成供需主数据 + for ($i = 0; $i < $supplyDemandCount; $i++) { + $publisher = $allUsers->random(); + + $supplyDemand = new SupplyDemand(); + $supplyDemand->user_id = $publisher->id; + $supplyDemand->title = $faker->sentence(4); + $supplyDemand->type = $faker->randomElement([1, 2]); + $supplyDemand->content = $faker->paragraphs($faker->numberBetween(1, 3), true); + $supplyDemand->tag = implode(',', $faker->randomElements(['采购', '合作', '招聘', '渠道', '推广', '技术', '投资'], $faker->numberBetween(1, 3))); + $supplyDemand->wechat = 'wx_' . $faker->bothify('??####'); + $supplyDemand->mobile = $faker->phoneNumber(); + $supplyDemand->email = $faker->safeEmail(); + $supplyDemand->status = $faker->randomElement([0, 1, 2, 3, 4]); + $supplyDemand->view_count = 0; // 稍后回填 + $supplyDemand->contact_count = 0; // 稍后回填 + $supplyDemand->expire_time = $faker->optional(0.6)->dateTimeBetween('now', '+90 days')?->format('Y-m-d H:i:s'); + // public_way 实际业务需要三态(1/2/3),但列类型为 boolean,这里按 0/1 赋值 + $supplyDemand->public_way = $faker->boolean ? 1 : 0; + $supplyDemand->contact_name = $faker->name(); + $supplyDemand->save(); + + // 3) 附件:0~3 个,并同步回填 file_ids + $uploadIds = []; + $attachmentsCount = $faker->numberBetween(0, 3); + for ($k = 0; $k < $attachmentsCount; $k++) { + $originalName = $faker->lexify('file_????') . '.' . $faker->randomElement(['pdf', 'png', 'jpg', 'docx']); + $extension = pathinfo($originalName, PATHINFO_EXTENSION); + $upload = new Upload(); + $upload->belongs_type = SupplyDemand::class; + $upload->belongs_id = $supplyDemand->id; + $upload->original_name = $originalName; + $upload->folder = 'test/' . date('Ymd'); + $upload->name = $faker->uuid . '.' . $extension; + $upload->extension = $extension; + $upload->size = $faker->numberBetween(5 * 1024, 2 * 1024 * 1024); + $upload->creator_type = 'seeder'; + $upload->creator_id = $publisher->id; + $upload->save(); + $uploadIds[] = $upload->id; + } + if (!empty($uploadIds)) { + $supplyDemand->file_ids = $uploadIds; + $supplyDemand->save(); + } + + // 4) 会话与消息:0~2 个会话,每个会话 1~5 条消息,严格交替 + $dialogueCount = $faker->numberBetween(0, 2); + $totalMessages = 0; + $totalContacts = 0; // 统计对发布者的有效联系次数 + + for ($d = 0; $d < $dialogueCount; $d++) { + // 选择一个不同于发布者的用户作为对话方 + $other = $allUsers->where('id', '!=', $publisher->id)->random(); + + $dialogue = new Dialogue(); + $dialogue->user_id = $faker->randomElement([$publisher->id, $other->id]); // 对话发起方随机 + $dialogue->to_user_id = ($dialogue->user_id === $publisher->id) ? $other->id : $publisher->id; + $dialogue->supply_demand_id = $supplyDemand->id; + $dialogue->last_content = null; + $dialogue->last_datetime = null; + $dialogue->save(); + + $messageCount = $faker->numberBetween(1, 5); + $sender = $faker->randomElement([$publisher->id, $other->id]); + $receiver = ($sender === $publisher->id) ? $other->id : $publisher->id; + + $lastContent = null; + $lastDatetime = null; + for ($m = 0; $m < $messageCount; $m++) { + $content = $faker->realText($faker->numberBetween(20, 80)); + $createdAt = Carbon::now()->subDays($faker->numberBetween(0, 10))->addMinutes($faker->numberBetween(0, 1440)); + + $msg = new Message(); + $msg->dialogue_id = $dialogue->id; + $msg->user_id = $sender; + $msg->to_user_id = $receiver; + $msg->supply_demand_id = $supplyDemand->id; + $msg->content = $content; + $msg->is_read = $faker->boolean ? 1 : 0; + $msg->created_at = $createdAt; + $msg->updated_at = $createdAt; + $msg->save(); + + // 统计“对发布者的联系” + if ($receiver === $publisher->id) { + $totalContacts++; + } + + $lastContent = $content; + $lastDatetime = $createdAt->format('Y-m-d H:i:s'); + + // 严格交替:交换 sender/receiver + [$sender, $receiver] = [$receiver, $sender]; + } + + $dialogue->last_content = $lastContent; + $dialogue->last_datetime = $lastDatetime; + $dialogue->save(); + + $totalMessages += $messageCount; + } + + // 5) 收藏:0~5 个 + $keepCount = $faker->numberBetween(0, 5); + if ($keepCount > 0) { + $keeperPool = $allUsers->where('id', '!=', $publisher->id)->pluck('id')->all(); + $keepers = Arr::random($keeperPool, min($keepCount, count($keeperPool))); + foreach ((array)$keepers as $keeperId) { + SupplyDemandKeep::firstOrCreate([ + 'user_id' => $keeperId, + 'supply_demand_id' => $supplyDemand->id, + ]); + } + } + + // 6) 回填统计:浏览量 >= 消息数,联系次数 = 对发布者的消息次数 + $supplyDemand->contact_count = $totalContacts; + $supplyDemand->view_count = $totalMessages + $faker->numberBetween(0, 20); + $supplyDemand->save(); + + $log(sprintf('供需#%d 已生成:附件%s个,会话%s个,消息%s条,收藏%s个', + $supplyDemand->id, + count($uploadIds), + $dialogueCount, + $totalMessages, + $keepCount + )); + } + }); + } +} + + diff --git a/database/seeders/SupplyDemandDemoSeeder.php b/database/seeders/SupplyDemandDemoSeeder.php new file mode 100644 index 0000000..334ce73 --- /dev/null +++ b/database/seeders/SupplyDemandDemoSeeder.php @@ -0,0 +1,19 @@ +generate(50, 20, function (string $msg) { + $this->command?->info($msg); + }); + } +} + + diff --git a/docs/supply_demand_module_analysis.md b/docs/supply_demand_module_analysis.md new file mode 100644 index 0000000..da55521 --- /dev/null +++ b/docs/supply_demand_module_analysis.md @@ -0,0 +1,96 @@ +### 供需发布模块数据结构与功能分析 + +#### 一、数据结构 + +- **表:`supply_demands`(供需主表)** + - 字段:`id`, `user_id`, `title`, `type`(1=供应,2=需求), `content`, `tag`, `wechat`, `mobile`, `email`, `status`(0待审核/1通过/2拒绝/3退回修改/4永久隐藏), `view_count`, `contact_count`, `expire_time`, `public_way`(布尔,实际业务含义为1/2/3), `file_ids`(JSON), `contact_name`, `timestamps`, `deleted_at` + - 关系: + - `user`: 发布者(`hasOne User(id=user_id)`) + - `keeps`: 收藏(`hasMany SupplyDemandKeep(supply_demand_id=id)`) + - 虚拟属性:`files`(根据 `file_ids` 关联 `Upload` 列表) + +- **表:`supply_demand_keeps`(收藏表)** + - 字段:`id`, `user_id`, `supply_demand_id`, `timestamps`, `deleted_at` + - 关系: + - `user`: 收藏者(`hasOne User(id=user_id)`) + - `supplyDemand`: 被收藏的供需(`hasOne SupplyDemand(id=supply_demand_id)`) + +- **表:`dialogues`(会话表)** + - 字段:`id`, `user_id`, `to_user_id`, `supply_demand_id`, `last_content`, `last_datetime`, `timestamps`, `deleted_at` + - 关系: + - `user`: 会话发起方(`hasOne User(id=user_id)`) + - `toUser`: 会话接收方(`hasOne User(id=to_user_id)`) + - `supplyDemand`: 关联供需(`hasOne SupplyDemand(id=supply_demand_id)`) + +- **表:`messages`(消息表)** + - 字段:`id`, `dialogue_id`, `user_id`, `to_user_id`, `supply_demand_id`, `content`, `is_read`, `timestamps`, `deleted_at` + - 关系: + - `user`/`toUser`: 发送方/接收方(`hasOne User`) + - `dialogue`: 所属会话(`hasOne Dialogue(id=dialogue_id)`) + - `supplyDemand`: 关联供需(`hasOne SupplyDemand(id=supply_demand_id)`) + +- **表:`uploads`(附件表)** + - 字段:`id`, `belongs_type`, `belongs_id`, `original_name`, `folder`, `name`, `extension`, `size`, `creator_type`, `creator_id`, `timestamps`, `deleted_at` + - 用途:`supply_demands.file_ids` 存放附件 `id` 列表,模型通过 `files` 访问器取回 `Upload` 集合 + +说明:`public_way` 迁移中为 boolean,但注释为 1/2/3 三种模式(1直接公开/2私信后公开/3不公开)。当前以 0/1 存储,若需完整三态应在后续迁移中改为 tinyInteger。 + +#### 二、功能说明(`SupplyDemandController`) + +- **列表 `index`**:按类型、状态、关键词、是否只看自己、有效期(有效/失效)筛选,分页排序;关联返回 `user` 基本信息。 +- **详情 `detail`**:按 `id` 查询,返回 `user`,并自增 `view_count`;附带当前用户对该供需的已发私信次数。 +- **保存 `save`**:新增或更新(新增时绑定当前用户并短信通知管理员),使用事务保存,支持 `file_ids`、`expire_time`、`contact_name` 等字段。 +- **删除 `destroy`**:按 `id` 软删除。 +- **发私信 `sendMessage`**: + - 若带 `supply_demand_id` 则自增浏览量; + - 无会话则创建会话; + - 限流:每天发送条数不超过配置 `message_limit`; + - 反骚扰:自己连续发送后需等待对方回复; + - 保存消息并更新会话最后内容与时间。 +- **消息列表 `messageList`**:按 `to_user_id` 定位当前和对方的会话,分页返回消息(含双方用户信息)。 +- **会话列表 `dialogues`**:返回与当前用户相关的会话(发起或接收),含双方用户与关联供需。 +- **收藏相关**: + - `keepIndex`:我的收藏列表; + - `keepSupplyDemand`:收藏,去重创建; + - `unKeepSupplyDemand`:取消收藏。 + +#### 三、核心业务要点 + +- 审核机制:多状态闭环(待审/通过/拒绝/退回/隐藏)。 +- 私信策略:限流 + 反骚扰(需对方回复后再发)。 +- 有效期:支持有效/失效筛选。 +- 公开模式:当前存储为布尔(0/1),业务含义为三态,后续建议迁移调整。 +- 数据统计:浏览数 `view_count`、联系数 `contact_count`(可按消息交互推导)。 +- 附件:`file_ids` JSON + `files` 访问器联表读取。 + +#### 四、测试数据生成目标 + +以 `supply_demands` 为起点,为每条主记录自动生成: +- 合理的 `uploads` 附件(0~3 个),`file_ids` 同步写入; +- 真实的会话 `dialogues`(0~2 个),双方用户随机; +- 合法的消息序列 `messages`(1~5 条),严格交替往来确保不违反“需对方回复”约束; +- 合理的收藏 `supply_demand_keeps`(0~5 条,去重); +- 统计字段:`view_count` ≥ 消息条数,`contact_count` 依据消息往来推导。 + +#### 五、两种生成方式对比 + +- **方式A:数据库填充(Seeder)** + - 优点: + - 一次性执行、可集成到 CI 或初始化流程; + - 可与 `DatabaseSeeder` 串联; + - 便于多环境批量重置数据。 + - 缺点: + - 运行参数(数量、用户规模)固定或需改代码; + - 无交互,临时性需求需改代码或 env。 + +- **方式B:Artisan 命令(Console Command)** + - 优点: + - 支持运行参数(如 `--count`、`--users`),灵活生成规模; + - 可多次按需执行,便于演示或局部补数; + - 缺点: + - 需要单独维护命令逻辑; + - 不会被自动纳入 `db:seed` 的全局流程。 + +推荐:开发/演示期使用命令(B)灵活试验;集成测试或初始化环境使用 Seeder(A)。 + + diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json old mode 100644 new mode 100755 From cd88c69a7ba41f995cff9871507fac4a0f6fc45f Mon Sep 17 00:00:00 2001 From: weizong song Date: Sat, 9 Aug 2025 11:27:11 +0800 Subject: [PATCH 08/42] up --- .../SupplyDemandTestDataGenerator.php | 91 ++++++++++++++++++- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/app/Services/TestData/SupplyDemandTestDataGenerator.php b/app/Services/TestData/SupplyDemandTestDataGenerator.php index 2f00268..b86b433 100644 --- a/app/Services/TestData/SupplyDemandTestDataGenerator.php +++ b/app/Services/TestData/SupplyDemandTestDataGenerator.php @@ -13,6 +13,9 @@ use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; +/** + * 供需模块测试数据生成器 + */ class SupplyDemandTestDataGenerator { /** @@ -51,10 +54,10 @@ class SupplyDemandTestDataGenerator $supplyDemand = new SupplyDemand(); $supplyDemand->user_id = $publisher->id; - $supplyDemand->title = $faker->sentence(4); + $supplyDemand->title = $this->generateTechBusinessTitle($faker); $supplyDemand->type = $faker->randomElement([1, 2]); - $supplyDemand->content = $faker->paragraphs($faker->numberBetween(1, 3), true); - $supplyDemand->tag = implode(',', $faker->randomElements(['采购', '合作', '招聘', '渠道', '推广', '技术', '投资'], $faker->numberBetween(1, 3))); + $supplyDemand->content = $this->generateContentFromTitle($supplyDemand->title, $supplyDemand->type, $faker); + $supplyDemand->tag = implode(',', $this->generateTagsFromTitle($supplyDemand->title, $faker)); $supplyDemand->wechat = 'wx_' . $faker->bothify('??####'); $supplyDemand->mobile = $faker->phoneNumber(); $supplyDemand->email = $faker->safeEmail(); @@ -176,6 +179,88 @@ class SupplyDemandTestDataGenerator } }); } + + /** + * 生成科技/商业取向的标题 + */ + private function generateTechBusinessTitle($faker): string + { + $regions = ['华东', '华南', '华北', '西南', '中原', '长三角', '珠三角']; + $industries = ['制造', '零售', '医药', '教育', '金融', '能源', '物流', '政企']; + $materials = ['光刻胶', '硅片', 'CMP 抛光液', '陶瓷基板']; + $domains = ['电商推荐', '客服质检', '金融风控', '工业检测', '内容审核']; + $countries = ['新加坡', '印度尼西亚', '阿联酋', '沙特', '巴西', '墨西哥']; + + $templates = [ + 'SaaS 渠道分销伙伴招募(' . $faker->randomElement($regions) . ')', + '云计算成本优化服务对接(' . $faker->randomElement($industries) . '行业)', + 'AI 数据标注外包合作(' . $faker->randomElement($domains) . ')', + '跨境电商供应链合作(' . $faker->randomElement($countries) . '仓)', + '半导体材料采购需求(' . $faker->randomElement($materials) . ')', + '新能源充电桩 OEM/ODM 代工合作', + '企业私有化部署 DevOps 顾问服务', + '工业物联网传感器批量采购', + '大模型微调服务(' . $faker->randomElement($domains) . ')', + '移动端 SDK 联合推广与结算', + '本地化运营团队招募(' . $faker->randomElement($regions) . ')', + '出海广告投放合作(' . $faker->randomElement($countries) . ')', + '数据中台建设项目外包', + '企业安全渗透测试服务对接', + ]; + + return $faker->randomElement($templates); + } + + /** + * 基于标题生成结构化内容,围绕标题展开 + * @param int $type 1=供应 2=需求 + */ + private function generateContentFromTitle(string $title, int $type, $faker): string + { + $timeframeWeeks = $faker->numberBetween(2, 12); + $budget = $faker->randomElement(['5万-10万', '10万-30万', '30万-80万', '80万以上', '按效果结算']); + $scale = $faker->randomElement(['小规模试点', '区域级铺开', '全国推广', '跨境协同']); + $partner = $faker->randomElement(['渠道商', 'ISV', '系统集成商', '服务外包商', '硬件厂商', '联合营销伙伴']); + $kpi = $faker->randomElement(['留存率', '转化率', '交付周期', '单点成本', '渠道覆盖']); + + $roleLine = $type === 1 + ? '供给能力:我们可提供成熟方案/产品/产能,支持灵活对接与深度合作。' + : '需求说明:我们需要优质方案/资源/产能,期待高效、稳定的交付能力。'; + + $sections = [ + "【项目标题】{$title}", + '项目背景:' . $faker->realText($faker->numberBetween(40, 80)), + $roleLine, + '合作模式:' . $faker->randomElement(['佣金', '代理', '分销', '联合投放', '项目外包', '里程碑结算']), + "目标指标:重点关注{$kpi},预计{$timeframeWeeks}周达到{$scale}阶段性目标。", + "预算与周期:预算 {$budget},计划周期 {$timeframeWeeks} 周。", + "适配伙伴:优先 {$partner},具备行业交付经验者加分。", + '补充信息:' . $faker->realText($faker->numberBetween(40, 80)), + ]; + + return implode("\n", $sections); + } + + /** + * 根据标题提取/生成标签 + * @return array + */ + private function generateTagsFromTitle(string $title, $faker): array + { + $dictionary = ['AI', 'SaaS', '云计算', '大模型', '供应链', '半导体', '新能源', '跨境电商', '营销', '渠道', 'OEM', 'ODM', '物联网', '安全', '出海', '数据中台', 'DevOps']; + $matched = []; + foreach ($dictionary as $keyword) { + if (mb_stripos($title, $keyword) !== false) { + $matched[] = $keyword; + } + } + $extra = $faker->randomElements($dictionary, $faker->numberBetween(0, 2)); + $tags = array_values(array_unique(array_merge($matched, $extra))); + if (empty($tags)) { + $tags = $faker->randomElements($dictionary, $faker->numberBetween(1, 3)); + } + return $tags; + } } From 7ff7fc89cdcdf7077404701a1e5831dd5439de74 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 11:29:48 +0800 Subject: [PATCH 09/42] update --- app/Console/Commands/UpdateCompany.php | 2 +- .../Controllers/Admin/CourseController.php | 1 + .../Controllers/Admin/OtherController.php | 4 +-- app/Repositories/YuanheRepository.php | 1 - .../2025_08_09_112749_alert_courses_table.php | 32 +++++++++++++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 database/migrations/2025_08_09_112749_alert_courses_table.php diff --git a/app/Console/Commands/UpdateCompany.php b/app/Console/Commands/UpdateCompany.php index fbfb4a9..5366835 100755 --- a/app/Console/Commands/UpdateCompany.php +++ b/app/Console/Commands/UpdateCompany.php @@ -60,7 +60,7 @@ class UpdateCompany extends Command $users = User::where('id', $user_id)->get(); } else { // 批量更新 - $users = User::whereDoesntHave('company')->get(); + $users = User::whereDoesntHave('company')->whereNotNull('company_name')->get(); } $YuanheRepository = new YuanheRepository(); foreach ($users as $user) { diff --git a/app/Http/Controllers/Admin/CourseController.php b/app/Http/Controllers/Admin/CourseController.php index 04b30e3..f771f17 100755 --- a/app/Http/Controllers/Admin/CourseController.php +++ b/app/Http/Controllers/Admin/CourseController.php @@ -191,6 +191,7 @@ class CourseController extends BaseController * @OA\Parameter(name="total", in="query", @OA\Schema(type="integer"), description="开课人数"), * @OA\Parameter(name="class", in="query", @OA\Schema(type="string"), description="所在班级"), * @OA\Parameter(name="price", in="query", @OA\Schema(type="string"), description="价格"), + * @OA\Parameter(name="url", in="query", @OA\Schema(type="string"), description="过期后链接"), * @OA\Parameter(name="supply_wechat_pay", in="query", @OA\Schema(type="string"), description="是否支持微信支付0否1是"), * @OA\Parameter(name="is_arrange", in="query", @OA\Schema(type="integer"), description="是否排课-0否1是"), * @OA\Parameter(name="is_fee", in="query", @OA\Schema(type="integer"), description="是否缴费-0否1是"), diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index dd3736a..fd5791e 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -41,9 +41,9 @@ class OtherController extends CommonController public function home() { // 校友总数 - $schoolmate['schoolmate_total'] = User::where('is_schoolmate', 1)->count(); + $schoolmate['schoolmate_total'] = User::where('is_schoolmate', 1)->groupBy('mobile')->count(); // 2025年校友数 - $schoolmate['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->count(); + $schoolmate['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->groupBy('mobile')->count(); // 上市企业总市值 $company['company_market'] = Company::where('company_market', 1)->sum('market_value'); // 校友企业总融资额 diff --git a/app/Repositories/YuanheRepository.php b/app/Repositories/YuanheRepository.php index e1e46cf..9da24e5 100755 --- a/app/Repositories/YuanheRepository.php +++ b/app/Repositories/YuanheRepository.php @@ -50,7 +50,6 @@ class YuanheRepository $header = $this->getHeader(); try { $result = httpCurl($url, 'POST', $params, $header); - dd($url,json_encode($params),$result); $result = json_decode($result, true); if ($result['code'] == 200) { return $result['data']; diff --git a/database/migrations/2025_08_09_112749_alert_courses_table.php b/database/migrations/2025_08_09_112749_alert_courses_table.php new file mode 100644 index 0000000..50e7c2f --- /dev/null +++ b/database/migrations/2025_08_09_112749_alert_courses_table.php @@ -0,0 +1,32 @@ +string('url')->nullable()->comment('过期后链接'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('courses', function (Blueprint $table) { + // + }); + } +}; From c4dffd116382a111d07616c333b91bf0297e1438 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 13:05:16 +0800 Subject: [PATCH 10/42] update --- app/Http/Controllers/Mobile/OtherController.php | 2 +- app/Http/Controllers/Mobile/UserController.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Mobile/OtherController.php b/app/Http/Controllers/Mobile/OtherController.php index 137b970..4b0b48b 100755 --- a/app/Http/Controllers/Mobile/OtherController.php +++ b/app/Http/Controllers/Mobile/OtherController.php @@ -90,7 +90,7 @@ class OtherController extends CommonController return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $YuanheRepository = new YuanheRepository(); - $result = $YuanheRepository->companyInfo(['enterpriseName' => $all['company_name']]); + $result = $YuanheRepository->companyInfo(['keyword' => $all['company_name']]); if (!$result) { return $this->fail([ResponseCode::ERROR_PARAMETER, '获取失败']); } diff --git a/app/Http/Controllers/Mobile/UserController.php b/app/Http/Controllers/Mobile/UserController.php index 610f12f..e182f5b 100755 --- a/app/Http/Controllers/Mobile/UserController.php +++ b/app/Http/Controllers/Mobile/UserController.php @@ -174,13 +174,13 @@ class UserController extends CommonController if (isset($all['name']) && !empty($all['name'])) { $all['letter'] = strtoupper(Pinyin::abbr(mb_substr($all['name'], 0, 1))[0]); } - $model->fill($all); - $model->save(); // 如果有公司信息,就更新一下公司 - if (isset($all['company_name']) && !empty($all['company_name'])) { + if (!empty($all['company_name'] && $model->company_name != $all['company_name'])) { // 调用命令行更新 Artisan::call("update_company --user_id={$model->id}"); } + $model->fill($all); + $model->save(); // 判断下,如果用户新加入车牌号,并且有未开始或者进行中的预约,则直接预约车牌号 $appointmentModel = Appointment::where('user_id', $this->getUserId()) ->where('status', 1) @@ -229,7 +229,6 @@ class UserController extends CommonController }])->find($this->getUserId()); $doorRepository = new DoorRepository(); - $nowDate = date('Y-m-d H:i:s'); $door_appointments = Appointment::where('user_id', $this->getUserId()) ->where('status', 1) ->orderBy('id', 'desc') @@ -245,6 +244,7 @@ class UserController extends CommonController $query->where('start_date', '<=', $nowDate)->where('end_date', '>=', $nowDate); })->first(); if ($course_signs) { + // todo::上线解开注释 //$course_signs->qrcode = $doorRepository->getEmpQrCodeByCourse($course_signs, $out); $course_signs->qrcode = ''; } From 749b8a7b4c330fae695cfc40a3d77295fa6bfb1e Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 13:18:31 +0800 Subject: [PATCH 11/42] update --- app/Http/Controllers/Mobile/SupplyDemandController.php | 6 ++---- .../migrations/2025_06_23_170000_create_books_table.php | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index 6d15121..b80a0f5 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -236,10 +236,6 @@ class SupplyDemandController extends CommonController if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } - if (isset($all['supply_demand_id']) && !empty($all['supply_demand_id'])) { - // 增加view_count - SupplyDemand::where('id', $all['supply_demand_id'])->increment('view_count'); - } // 判断是否有会话,没有则创建 $dialogue = Dialogue::where(function ($query) use ($all) { $query->where('user_id', $this->getUserId())->where('to_user_id', $all['to_user_id']); @@ -253,6 +249,8 @@ class SupplyDemandController extends CommonController 'to_user_id' => $all['to_user_id'], 'supply_demand_id' => $all['supply_demand_id'] ?? 0 ]); + // 增加联系次数 + SupplyDemand::where('id', $all['supply_demand_id'])->increment('contact_count'); } // 每天限制私信次数限制 $message_limit = Config::getValueByKey('message_limit'); diff --git a/database/migrations/2025_06_23_170000_create_books_table.php b/database/migrations/2025_06_23_170000_create_books_table.php index 41d2cab..175529b 100644 --- a/database/migrations/2025_06_23_170000_create_books_table.php +++ b/database/migrations/2025_06_23_170000_create_books_table.php @@ -16,6 +16,7 @@ return new class extends Migration { $table->comment('图书表'); $table->increments('id'); $table->string('title')->comment('书名'); + $table->string('code')->comment('编码'); $table->string('author')->nullable()->comment('作者'); $table->string('isbn')->nullable()->comment('ISBN'); $table->string('publisher')->nullable()->comment('出版社'); From 3668a650d15a5ef68e1b56655ca1479df87430b9 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 13:20:26 +0800 Subject: [PATCH 12/42] update --- app/Http/Controllers/Admin/BookController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Http/Controllers/Admin/BookController.php b/app/Http/Controllers/Admin/BookController.php index 08ea480..d2acbed 100644 --- a/app/Http/Controllers/Admin/BookController.php +++ b/app/Http/Controllers/Admin/BookController.php @@ -206,6 +206,8 @@ class BookController extends BaseController * @OA\Parameter(name="category", in="query", @OA\Schema(type="string"), required=false, description="分类"), * @OA\Parameter(name="description", in="query", @OA\Schema(type="string"), required=false, description="图书简介"), * @OA\Parameter(name="cover_id", in="query", @OA\Schema(type="integer"), required=false, description="图书封面ID"), + * @OA\Parameter(name="code", in="query", @OA\Schema(type="integer"), required=false, description="编码"), + * @OA\Parameter(name="total", in="query", @OA\Schema(type="integer"), required=false, description="数量"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="integer"), required=false, description="状态0可借阅1已借出2维护中"), * @OA\Response( * response="200", From f41ef94a392c88f97d0ed65e2a425ea9d449ecff Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 13:37:39 +0800 Subject: [PATCH 13/42] update --- app/Http/Controllers/Admin/BookController.php | 1 + database/migrations/2025_06_23_170000_create_books_table.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/Http/Controllers/Admin/BookController.php b/app/Http/Controllers/Admin/BookController.php index d2acbed..39889c7 100644 --- a/app/Http/Controllers/Admin/BookController.php +++ b/app/Http/Controllers/Admin/BookController.php @@ -208,6 +208,7 @@ class BookController extends BaseController * @OA\Parameter(name="cover_id", in="query", @OA\Schema(type="integer"), required=false, description="图书封面ID"), * @OA\Parameter(name="code", in="query", @OA\Schema(type="integer"), required=false, description="编码"), * @OA\Parameter(name="total", in="query", @OA\Schema(type="integer"), required=false, description="数量"), + * @OA\Parameter(name="bookshelf", in="query", @OA\Schema(type="integer"), required=false, description="书架"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="integer"), required=false, description="状态0可借阅1已借出2维护中"), * @OA\Response( * response="200", diff --git a/database/migrations/2025_06_23_170000_create_books_table.php b/database/migrations/2025_06_23_170000_create_books_table.php index 175529b..553f284 100644 --- a/database/migrations/2025_06_23_170000_create_books_table.php +++ b/database/migrations/2025_06_23_170000_create_books_table.php @@ -17,6 +17,8 @@ return new class extends Migration { $table->increments('id'); $table->string('title')->comment('书名'); $table->string('code')->comment('编码'); + // 书架 + $table->string('bookshelf')->comment('书架'); $table->string('author')->nullable()->comment('作者'); $table->string('isbn')->nullable()->comment('ISBN'); $table->string('publisher')->nullable()->comment('出版社'); From d81ccd99eeef5cdac19084239656efdfebd5d8d7 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 13:53:51 +0800 Subject: [PATCH 14/42] update --- .../Mobile/SupplyDemandController.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index b80a0f5..a7ae109 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -15,7 +15,6 @@ use App\Models\Message; use App\Models\SupplyDemand; use App\Models\SupplyDemandKeep; use App\Notifications\BirthdayNotify; -use App\Notifications\SupplyDemandNotify; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Notification; @@ -65,12 +64,13 @@ class SupplyDemandController extends CommonController $query->where('user_id', $this->getUserId()); } if (isset($all['expire_type'])) { + $now = date('Y-m-d'); if ($all['expire_type'] == 1) { - $query->where(function ($q) { - $q->whereNull('expire_time')->orWhere('expire_time', '>', Carbon::now()); + $query->where(function ($q) use ($now) { + $q->whereNull('expire_time')->orWhere('expire_time', '')->orWhere('expire_time', '>', $now); }); } else { - $query->where('expire_time', '<', Carbon::now()); + $query->where('expire_time', '<', $now); } } })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc') @@ -252,6 +252,14 @@ class SupplyDemandController extends CommonController // 增加联系次数 SupplyDemand::where('id', $all['supply_demand_id'])->increment('contact_count'); } + if (isset($all['supply_demand_id'])) { + $now = date('Y-m-d'); + // 过期数据不能私信 + $supplyDemand = SupplyDemand::find($all['supply_demand_id']); + if ($supplyDemand->expire_time > $now) { + return $this->fail([ResponseCode::ERROR_BUSINESS, '该信息已过期,不能私信']); + } + } // 每天限制私信次数限制 $message_limit = Config::getValueByKey('message_limit'); $messageToday = Message::where('user_id', $this->getUserId()) From 73f7ae69428113e3dc2215636800a9202fb388f0 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 13:55:48 +0800 Subject: [PATCH 15/42] update --- app/Http/Controllers/Admin/BookController.php | 1 - database/migrations/2025_06_23_170000_create_books_table.php | 1 - 2 files changed, 2 deletions(-) diff --git a/app/Http/Controllers/Admin/BookController.php b/app/Http/Controllers/Admin/BookController.php index 39889c7..d256f78 100644 --- a/app/Http/Controllers/Admin/BookController.php +++ b/app/Http/Controllers/Admin/BookController.php @@ -206,7 +206,6 @@ class BookController extends BaseController * @OA\Parameter(name="category", in="query", @OA\Schema(type="string"), required=false, description="分类"), * @OA\Parameter(name="description", in="query", @OA\Schema(type="string"), required=false, description="图书简介"), * @OA\Parameter(name="cover_id", in="query", @OA\Schema(type="integer"), required=false, description="图书封面ID"), - * @OA\Parameter(name="code", in="query", @OA\Schema(type="integer"), required=false, description="编码"), * @OA\Parameter(name="total", in="query", @OA\Schema(type="integer"), required=false, description="数量"), * @OA\Parameter(name="bookshelf", in="query", @OA\Schema(type="integer"), required=false, description="书架"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="integer"), required=false, description="状态0可借阅1已借出2维护中"), diff --git a/database/migrations/2025_06_23_170000_create_books_table.php b/database/migrations/2025_06_23_170000_create_books_table.php index 553f284..18f611c 100644 --- a/database/migrations/2025_06_23_170000_create_books_table.php +++ b/database/migrations/2025_06_23_170000_create_books_table.php @@ -16,7 +16,6 @@ return new class extends Migration { $table->comment('图书表'); $table->increments('id'); $table->string('title')->comment('书名'); - $table->string('code')->comment('编码'); // 书架 $table->string('bookshelf')->comment('书架'); $table->string('author')->nullable()->comment('作者'); From ea30b44f103a72457cff59eb922080b8fc0757d1 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:09:26 +0800 Subject: [PATCH 16/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 239 ++++++++++++++++++ .../Mobile/SupplyDemandController.php | 4 +- app/Models/Book.php | 1 + .../2025_06_23_170000_create_books_table.php | 1 + 4 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 app/Console/Commands/UpdateBookIsbnData.php diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php new file mode 100644 index 0000000..d715eaa --- /dev/null +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -0,0 +1,239 @@ +where('isbn', '!=', '') + ->whereNull('cover_id') + ->get(); + + if ($books->isEmpty()) { + $this->info('没有找到未处理封面的书籍'); + return 0; + } + + $this->info("找到 {$books->count()} 本书需要处理"); + + $bar = $this->output->createProgressBar($books->count()); + $bar->start(); + + $successCount = 0; + $failCount = 0; + + foreach ($books as $book) { + try { + $result = $this->processBook($book, $apiKey); + if ($result) { + $successCount++; + $this->line("\n✓ 成功处理书籍: {$book->title} (ISBN: {$book->isbn})"); + } else { + $failCount++; + $this->line("\n✗ 处理失败: {$book->title} (ISBN: {$book->isbn})"); + } + } catch (\Exception $e) { + $failCount++; + $this->line("\n✗ 处理异常: {$book->title} - {$e->getMessage()}"); + } + + $bar->advance(); + + // 添加延迟避免API请求过快 + sleep(1); + } + + $bar->finish(); + + $this->line(''); + $this->info("处理完成!成功: {$successCount}, 失败: {$failCount}"); + + return 0; + } + + /** + * 处理单本书籍 + * + * @param Book $book + * @param string $apiKey + * @return bool + */ + private function processBook(Book $book, string $apiKey): bool + { + // 调用ISBN接口 + $response = Http::timeout(30)->get('https://api.tanshuapi.com/api/isbn/v2/index', [ + 'key' => $apiKey, + 'isbn' => $book->isbn + ]); + + if (!$response->successful()) { + $this->error("API请求失败: HTTP {$response->status()}"); + return false; + } + + $data = $response->json(); + + if (!$data || $data['code'] !== 1) { + $this->error("API返回错误: " . ($data['msg'] ?? '未知错误')); + return false; + } + + $bookData = $data['data']; + + // 更新书籍的other_data字段 + $book->other_data = $bookData; + + // 如果有图片URL,下载图片 + if (!empty($bookData['img'])) { + $coverId = $this->downloadAndSaveImage($bookData['img'], $book); + if ($coverId) { + $book->cover_id = $coverId; + } + } + + $book->save(); + + return true; + } + + /** + * 下载图片并保存到本地 + * + * @param string $imageUrl + * @param Book $book + * @return int|null + */ + private function downloadAndSaveImage(string $imageUrl, Book $book): ?int + { + try { + // 下载图片 + $response = Http::timeout(30)->get($imageUrl); + + if (!$response->successful()) { + $this->error("图片下载失败: {$imageUrl}"); + return null; + } + + $imageContent = $response->body(); + + // 获取文件扩展名 + $extension = $this->getImageExtension($imageUrl, $response->header('Content-Type')); + + // 生成文件名 + $filename = 'book_cover_' . $book->id . '_' . time() . '.' . $extension; + + // 定义存储目录 + $folder = 'uploads/book_covers/' . date('Y/m'); + + // 确保目录存在 + $fullPath = public_path($folder); + if (!file_exists($fullPath)) { + mkdir($fullPath, 0755, true); + } + + // 保存文件 + $filePath = $folder . '/' . $filename; + file_put_contents(public_path($filePath), $imageContent); + + // 获取文件大小 + $fileSize = strlen($imageContent); + + // 创建uploads记录 + $upload = Upload::create([ + 'belongs_type' => 'App\\Models\\Book', + 'belongs_id' => $book->id, + 'original_name' => basename($imageUrl), + 'folder' => $folder, + 'name' => $filename, + 'extension' => $extension, + 'size' => $fileSize, + 'creator_type' => 'console', + 'creator_id' => null, + ]); + + return $upload->id; + + } catch (\Exception $e) { + $this->error("保存图片时出错: {$e->getMessage()}"); + return null; + } + } + + /** + * 获取图片扩展名 + * + * @param string $url + * @param string|null $contentType + * @return string + */ + private function getImageExtension(string $url, ?string $contentType = null): string + { + // 首先尝试从URL获取扩展名 + $pathInfo = pathinfo(parse_url($url, PHP_URL_PATH)); + if (!empty($pathInfo['extension'])) { + return strtolower($pathInfo['extension']); + } + + // 从Content-Type获取扩展名 + if ($contentType) { + $mimeToExt = [ + 'image/jpeg' => 'jpg', + 'image/jpg' => 'jpg', + 'image/png' => 'png', + 'image/gif' => 'gif', + 'image/webp' => 'webp', + 'image/bmp' => 'bmp', + ]; + + $contentType = strtolower(trim(explode(';', $contentType)[0])); + if (isset($mimeToExt[$contentType])) { + return $mimeToExt[$contentType]; + } + } + + // 默认返回jpg + return 'jpg'; + } +} diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index a7ae109..b6a276f 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -53,7 +53,9 @@ class SupplyDemandController extends CommonController $query->select('id', 'nickname', 'name', 'headimgurl', 'username'); } ])->where(function ($query) use ($all, $status) { - $query->where('status', $status); + if($status){ + $query->where('status', $status); + } if (isset($all['type'])) { $query->where('type', $all['type']); } diff --git a/app/Models/Book.php b/app/Models/Book.php index e40fbf0..6ea9e2c 100644 --- a/app/Models/Book.php +++ b/app/Models/Book.php @@ -4,6 +4,7 @@ namespace App\Models; class Book extends SoftDeletesModel { + protected $casts = ['other_data' => 'json']; public function cover() { diff --git a/database/migrations/2025_06_23_170000_create_books_table.php b/database/migrations/2025_06_23_170000_create_books_table.php index 18f611c..587d950 100644 --- a/database/migrations/2025_06_23_170000_create_books_table.php +++ b/database/migrations/2025_06_23_170000_create_books_table.php @@ -26,6 +26,7 @@ return new class extends Migration { $table->mediumText('description')->nullable()->comment('图书简介'); $table->integer('cover_id')->nullable()->comment('图书封面'); $table->tinyInteger('status')->default(0)->comment('状态0可借阅1已借出2维护中'); + $table->json('other_data')->nullable()->comment('其他数据'); $table->timestamps(); $table->softDeletes(); }); From 1522ea9f18f4c1fbadd70517b5153619ae629c60 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:18:07 +0800 Subject: [PATCH 17/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 3 ++- .../book_covers/book_cover_1_1754720250.jpg | Bin 0 -> 57054 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 public/uploads/book_covers/book_cover_1_1754720250.jpg diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php index d715eaa..74875aa 100644 --- a/app/Console/Commands/UpdateBookIsbnData.php +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -49,6 +49,7 @@ class UpdateBookIsbnData extends Command $books = Book::whereNotNull('isbn') ->where('isbn', '!=', '') ->whereNull('cover_id') + ->where('id', 1) ->get(); if ($books->isEmpty()) { @@ -165,7 +166,7 @@ class UpdateBookIsbnData extends Command $filename = 'book_cover_' . $book->id . '_' . time() . '.' . $extension; // 定义存储目录 - $folder = 'uploads/book_covers/' . date('Y/m'); + $folder = 'uploads/book_covers'; // 确保目录存在 $fullPath = public_path($folder); diff --git a/public/uploads/book_covers/book_cover_1_1754720250.jpg b/public/uploads/book_covers/book_cover_1_1754720250.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc65087e18d45ae7f9a797f3f014f390a2c4b114 GIT binary patch literal 57054 zcmbrF1yCHp)~I)JcSwTE;uhQq4vRa%-Q696yL)iAput@dT!L$GcNW(?a&NtR?|W5G z>i>JUroQPuJ*VfK-k!5FXZ|ey*#KZjOMoQ+Kp+5M^7aAz*+TgY78TW3R927x%ZmS_ z0YysI(#{?V0|2nKb8%9Z6e0brsYMDu0e}J^0^k5F0Dz&fvxA(9geu^zfW<{go!^B1 z^1sXNJm5_Q05HQSrASKp@B05Q!ZdbpasdELJDAv-{N*2S9PZ|7`o_?*Zyf4o zY3lyQvu_NtakaI4a$2UfCQdJgxV}1Yt0mb}3*yuml z#nj_%oB)8Ry@RKdrMZO*DUC5LDGLt|H>s4VyN#)f3!|c;v9+O-38|>Pt%ISR=bLN( zan65x0kHnsmh{cYoGd(?oQ$kYZ|473`M);)OX~j)e|`H;i7Tal_zZ|Q_V2oX_x*RB zeE|T#ee-6U_y2(0`Txr@+4?|IhFr`k4Oe`2ZOSynW>Yh-J2@)w^?RsXa44HI}=M6OM5#~OS}J*hyRP+{$mV(@t^bh z4X}$|0XX_h0E|f-0QBh?00tWw0Iier)&l&O-((Th0e^pa8YKJwocC}1*8Y#}|FVIK zd)tL_wlpXGTP>=rN^0!t50)7GJ z04snEz%JkzZ~?dlJOP0~cpxee8~6c80;B}e16hIGKtZ55P!^~R)C3v;&4G46SD+6t z2p9!S1bzkP1IvMRz*b-{a2PlRTmo(a4}lQiBNQ|g3KR|$5fl{^GZZ(JFq90GDwHmi zIg}%m7gR7*EL1vF0n|6BCa7MhQK&hn4X9(N8)yJDGBh4E88jm_H?%0U0<;#i8MG6$ zA9N&iDs%yKHFO*FAoL9M2J{K^0}LDtHVi2YBMcvm6pR{-F^nUOA51jNSC}%GCYT>E zGccPl7cj4|sIY{v^sv0JVA#*F=CJOtp|Gj2C9sXKKVj!!cVTbg;NbA!sNuNaq~J8+ ztl+%iqT#aPYT$a{rr@^WZs6hJKfu$&3&1PD8^XK5hr(yTe}nIapN8LszehkuAVFY7 zkU-EvutNw$NJXeX=t7uA*hhFm#6YA(fy0}+D?Llnah!w(}9qZMNT;|3EOlLb=&(-t!tvjTG%^8gDTiwa8|%LFSJ zs}QRnYa1IHn*v)D+Za0ty9oOy_AU+_4mA!K#|kG3rwV5R=K>cCmmOCf*8?{bw-a{* z4;qgO4~%Dn7l&7mH;?!Dj_956JJWX&@2cNTzq@-+@LuS>>HEm{HSg!%KYk$nApXJn zL&AsV55MtY@agcC@ZIrq@PFc;5a1B-5f~Fh64Vnc6G9Qv5h@dU6BZJV5#A6H6G;*| z5M>bc6P*y_5epGp5hoLO5g(FZlL(Snk|dLKlN^!ak_waBkfxLVAiW?XB$Fa@CCew9 zAbTRGCRZa5B(EX=O@TzgO<_inOwmVi0U`m(fqX!fpk+!#N^VLE$~4MB$~!7*Dh;YI zs%EMK>i5)OYA@Qx$4nol&2GzB!Xv~aZCwAQrQw7=+}=s4&s=rZXh>7nR3=`HEA z>8BWA8F(1%7z!8`7*QC78QmBw88?~mm}Hp(nVOl-m_f{1%n8hc% gKH7XN`nbY^ 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 literal 0 HcmV?d00001 From 71d500664e3dd5dc071de64e54c14c0027661694 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:24:43 +0800 Subject: [PATCH 18/42] update --- app/Http/Controllers/Mobile/SupplyDemandController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index b6a276f..9e398f3 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -53,7 +53,7 @@ class SupplyDemandController extends CommonController $query->select('id', 'nickname', 'name', 'headimgurl', 'username'); } ])->where(function ($query) use ($all, $status) { - if($status){ + if ($status != -1) { $query->where('status', $status); } if (isset($all['type'])) { From 609096a13f01f14d23fdf7608ecd755f036dfcc1 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:27:01 +0800 Subject: [PATCH 19/42] update --- app/Models/SupplyDemand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/SupplyDemand.php b/app/Models/SupplyDemand.php index 8dab203..947a3b2 100755 --- a/app/Models/SupplyDemand.php +++ b/app/Models/SupplyDemand.php @@ -9,6 +9,7 @@ use Illuminate\Support\Facades\Cache; class SupplyDemand extends SoftDeletesModel { + protected $appends = ['files']; protected $casts = ['file_ids' => 'json']; public function getFilesAttribute($value) From 90e9e06e10d8d0f76b5d2652cf35f34f8efe4bd1 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:37:35 +0800 Subject: [PATCH 20/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 120 +++++++++++++----- ...720250.jpg => book_cover_1_1754721429.jpg} | Bin 2 files changed, 90 insertions(+), 30 deletions(-) rename public/uploads/book_covers/{book_cover_1_1754720250.jpg => book_cover_1_1754721429.jpg} (100%) diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php index 74875aa..1be6427 100644 --- a/app/Console/Commands/UpdateBookIsbnData.php +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -58,16 +58,39 @@ class UpdateBookIsbnData extends Command } $this->info("找到 {$books->count()} 本书需要处理"); + $this->info("API限制:每秒最多10次请求,预计耗时约 " . ceil($books->count() / 10) . " 秒"); $bar = $this->output->createProgressBar($books->count()); $bar->start(); $successCount = 0; $failCount = 0; + $requestCount = 0; + $startTime = microtime(true); + $lastResetTime = $startTime; foreach ($books as $book) { try { + // 每秒重置请求计数器 + $currentTime = microtime(true); + if ($currentTime - $lastResetTime >= 1.0) { + $requestCount = 0; + $lastResetTime = $currentTime; + } + + // API频率限制控制:每秒最多10次请求 + if ($requestCount >= 10) { + $waitTime = 1.0 - ($currentTime - $lastResetTime); + if ($waitTime > 0) { + usleep(intval($waitTime * 1000000)); + $requestCount = 0; + $lastResetTime = microtime(true); + } + } + $result = $this->processBook($book, $apiKey); + $requestCount++; + if ($result) { $successCount++; $this->line("\n✓ 成功处理书籍: {$book->title} (ISBN: {$book->isbn})"); @@ -78,18 +101,31 @@ class UpdateBookIsbnData extends Command } catch (\Exception $e) { $failCount++; $this->line("\n✗ 处理异常: {$book->title} - {$e->getMessage()}"); + + // 如果是API相关错误,增加等待时间 + if (strpos($e->getMessage(), 'API') !== false || strpos($e->getMessage(), 'HTTP') !== false) { + $this->line("检测到API错误,等待2秒后继续..."); + sleep(2); + $requestCount = 0; + $lastResetTime = microtime(true); + } } $bar->advance(); - - // 添加延迟避免API请求过快 - sleep(1); } $bar->finish(); + $totalTime = microtime(true) - $startTime; + $avgTimePerBook = $totalTime / $books->count(); + $actualRequestsPerSecond = $books->count() / $totalTime; + $this->line(''); - $this->info("处理完成!成功: {$successCount}, 失败: {$failCount}"); + $this->info("处理完成!"); + $this->info("成功: {$successCount}, 失败: {$failCount}"); + $this->info("总耗时: " . round($totalTime, 2) . " 秒"); + $this->info("平均每本书耗时: " . round($avgTimePerBook, 2) . " 秒"); + $this->info("实际请求频率: " . round($actualRequestsPerSecond, 2) . " 次/秒"); return 0; } @@ -103,40 +139,64 @@ class UpdateBookIsbnData extends Command */ private function processBook(Book $book, string $apiKey): bool { - // 调用ISBN接口 - $response = Http::timeout(30)->get('https://api.tanshuapi.com/api/isbn/v2/index', [ - 'key' => $apiKey, - 'isbn' => $book->isbn - ]); - - if (!$response->successful()) { - $this->error("API请求失败: HTTP {$response->status()}"); - return false; - } + $attempt = 0; + $maxRetries = 3; - $data = $response->json(); + while ($attempt < $maxRetries) { + try { + $attempt++; - if (!$data || $data['code'] !== 1) { - $this->error("API返回错误: " . ($data['msg'] ?? '未知错误')); - return false; - } + // 调用ISBN接口 + $response = Http::timeout(30)->get('https://api.tanshuapi.com/api/isbn/v2/index', [ + 'key' => $apiKey, + 'isbn' => $book->isbn + ]); - $bookData = $data['data']; + if (!$response->successful()) { + throw new \Exception("API请求失败: HTTP {$response->status()}"); + } + + $data = $response->json(); + + if (!$data || $data['code'] !== 1) { + // 如果是API密钥错误或其他不可重试的错误,直接返回失败 + if (isset($data['code']) && in_array($data['code'], [10001, 10002, 10003])) { + $this->error("API返回不可重试错误: " . ($data['msg'] ?? '未知错误')); + return false; + } + throw new \Exception("API返回错误: " . ($data['msg'] ?? '未知错误')); + } + + $bookData = $data['data']; + + // 更新书籍的other_data字段 + $book->other_data = $bookData; - // 更新书籍的other_data字段 - $book->other_data = $bookData; + // 如果有图片URL,下载图片 + if (!empty($bookData['img'])) { + $coverId = $this->downloadAndSaveImage($bookData['img'], $book); + if ($coverId) { + $book->cover_id = $coverId; + } + } + + $book->save(); + return true; + + } catch (\Exception $e) { + if ($attempt >= $maxRetries) { + $this->error("重试 {$maxRetries} 次后仍然失败: {$e->getMessage()}"); + return false; + } - // 如果有图片URL,下载图片 - if (!empty($bookData['img'])) { - $coverId = $this->downloadAndSaveImage($bookData['img'], $book); - if ($coverId) { - $book->cover_id = $coverId; + // 指数退避:第1次重试等待1秒,第2次等待2秒,第3次等待4秒 + $waitTime = pow(2, $attempt - 1); + $this->line("第 {$attempt} 次尝试失败,{$waitTime} 秒后重试: {$e->getMessage()}"); + sleep($waitTime); } } - $book->save(); - - return true; + return false; } /** diff --git a/public/uploads/book_covers/book_cover_1_1754720250.jpg b/public/uploads/book_covers/book_cover_1_1754721429.jpg similarity index 100% rename from public/uploads/book_covers/book_cover_1_1754720250.jpg rename to public/uploads/book_covers/book_cover_1_1754721429.jpg From 652318686dde00eabc63731eb50ce56674acea6a Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:39:20 +0800 Subject: [PATCH 21/42] update --- .../book_covers/book_cover_1_1754721429.jpg | Bin 57054 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/uploads/book_covers/book_cover_1_1754721429.jpg diff --git a/public/uploads/book_covers/book_cover_1_1754721429.jpg b/public/uploads/book_covers/book_cover_1_1754721429.jpg deleted file mode 100644 index cc65087e18d45ae7f9a797f3f014f390a2c4b114..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57054 zcmbrF1yCHp)~I)JcSwTE;uhQq4vRa%-Q696yL)iAput@dT!L$GcNW(?a&NtR?|W5G z>i>JUroQPuJ*VfK-k!5FXZ|ey*#KZjOMoQ+Kp+5M^7aAz*+TgY78TW3R927x%ZmS_ z0YysI(#{?V0|2nKb8%9Z6e0brsYMDu0e}J^0^k5F0Dz&fvxA(9geu^zfW<{go!^B1 z^1sXNJm5_Q05HQSrASKp@B05Q!ZdbpasdELJDAv-{N*2S9PZ|7`o_?*Zyf4o zY3lyQvu_NtakaI4a$2UfCQdJgxV}1Yt0mb}3*yuml z#nj_%oB)8Ry@RKdrMZO*DUC5LDGLt|H>s4VyN#)f3!|c;v9+O-38|>Pt%ISR=bLN( zan65x0kHnsmh{cYoGd(?oQ$kYZ|473`M);)OX~j)e|`H;i7Tal_zZ|Q_V2oX_x*RB zeE|T#ee-6U_y2(0`Txr@+4?|IhFr`k4Oe`2ZOSynW>Yh-J2@)w^?RsXa44HI}=M6OM5#~OS}J*hyRP+{$mV(@t^bh z4X}$|0XX_h0E|f-0QBh?00tWw0Iier)&l&O-((Th0e^pa8YKJwocC}1*8Y#}|FVIK zd)tL_wlpXGTP>=rN^0!t50)7GJ z04snEz%JkzZ~?dlJOP0~cpxee8~6c80;B}e16hIGKtZ55P!^~R)C3v;&4G46SD+6t z2p9!S1bzkP1IvMRz*b-{a2PlRTmo(a4}lQiBNQ|g3KR|$5fl{^GZZ(JFq90GDwHmi zIg}%m7gR7*EL1vF0n|6BCa7MhQK&hn4X9(N8)yJDGBh4E88jm_H?%0U0<;#i8MG6$ zA9N&iDs%yKHFO*FAoL9M2J{K^0}LDtHVi2YBMcvm6pR{-F^nUOA51jNSC}%GCYT>E zGccPl7cj4|sIY{v^sv0JVA#*F=CJOtp|Gj2C9sXKKVj!!cVTbg;NbA!sNuNaq~J8+ ztl+%iqT#aPYT$a{rr@^WZs6hJKfu$&3&1PD8^XK5hr(yTe}nIapN8LszehkuAVFY7 zkU-EvutNw$NJXeX=t7uA*hhFm#6YA(fy0}+D?Llnah!w(}9qZMNT;|3EOlLb=&(-t!tvjTG%^8gDTiwa8|%LFSJ zs}QRnYa1IHn*v)D+Za0ty9oOy_AU+_4mA!K#|kG3rwV5R=K>cCmmOCf*8?{bw-a{* z4;qgO4~%Dn7l&7mH;?!Dj_956JJWX&@2cNTzq@-+@LuS>>HEm{HSg!%KYk$nApXJn zL&AsV55MtY@agcC@ZIrq@PFc;5a1B-5f~Fh64Vnc6G9Qv5h@dU6BZJV5#A6H6G;*| z5M>bc6P*y_5epGp5hoLO5g(FZlL(Snk|dLKlN^!ak_waBkfxLVAiW?XB$Fa@CCew9 zAbTRGCRZa5B(EX=O@TzgO<_inOwmVi0U`m(fqX!fpk+!#N^VLE$~4MB$~!7*Dh;YI zs%EMK>i5)OYA@Qx$4nol&2GzB!Xv~aZCwAQrQw7=+}=s4&s=rZXh>7nR3=`HEA z>8BWA8F(1%7z!8`7*QC78QmBw88?~mm}Hp(nVOl-m_f{1%n8hc% gKH7XN`nbY^ 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 From c2ad64ad6bf741fbaa83abe3c6cef1a63f7a2c3e Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 14:41:17 +0800 Subject: [PATCH 22/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php index 1be6427..244daf0 100644 --- a/app/Console/Commands/UpdateBookIsbnData.php +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -49,7 +49,7 @@ class UpdateBookIsbnData extends Command $books = Book::whereNotNull('isbn') ->where('isbn', '!=', '') ->whereNull('cover_id') - ->where('id', 1) + // ->where('id', 1) ->get(); if ($books->isEmpty()) { From 7afb5fb71dfd4ac08736a1aa6600d4d96098aebb Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 15:17:25 +0800 Subject: [PATCH 23/42] update --- .../Admin/SupplyDemandController.php | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/app/Http/Controllers/Admin/SupplyDemandController.php b/app/Http/Controllers/Admin/SupplyDemandController.php index 29bac40..aeb55d0 100755 --- a/app/Http/Controllers/Admin/SupplyDemandController.php +++ b/app/Http/Controllers/Admin/SupplyDemandController.php @@ -6,6 +6,7 @@ use App\Exports\BaseExport; use App\Helpers\ResponseCode; use App\Models\AppointmentType; use App\Models\CustomForm; +use App\Models\Message; use App\Models\SupplyDemand; use App\Models\SupplyDemandType; use Illuminate\Support\Facades\Validator; @@ -193,6 +194,9 @@ class SupplyDemandController extends BaseController * tags={"供需信息管理"}, * summary="交互统计", * description="", + * @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=true, description="开始日期"), + * @OA\Parameter(name="end_date", in="query", @OA\Schema(type="string"), required=true, description="结束日期"), + * @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", @@ -202,7 +206,121 @@ class SupplyDemandController extends BaseController */ public function chart() { + $now = date('Y-m-d'); + $startDate = request('start_date', $now); + $endDate = request('end_date', $now); + $type = request('type'); + // 计算上期时间段(与当前时间段长度相同) + $daysDiff = (strtotime($endDate) - strtotime($startDate)) / (60 * 60 * 24) + 1; + $prevEndDate = date('Y-m-d', strtotime($startDate) - 1); + $prevStartDate = date('Y-m-d', strtotime($prevEndDate) - $daysDiff + 1); + + // 当期供需发布数 + $supplyDemand = SupplyDemand::where(function ($query) use ($type) { + if ($type) { + $query->where('type', $type); + } + })->whereBetween('created_at', [$startDate, $endDate]) + ->get(); + $supplyDemandCount = $supplyDemand->count(); + + // 上期供需发布数 + $prevSupplyDemandCount = SupplyDemand::where(function ($query) use ($type) { + if ($type) { + $query->where('type', $type); + } + })->whereBetween('created_at', [$prevStartDate, $prevEndDate]) + ->count(); + + // 当期私信数量 + $messageCount = Message::whereIn('supply_demand_id', $supplyDemand->pluck('id'))->count(); + + // 上期私信数量 + $prevSupplyDemand = SupplyDemand::where(function ($query) use ($type) { + if ($type) { + $query->where('type', $type); + } + })->whereBetween('created_at', [$prevStartDate, $prevEndDate]) + ->get(); + $prevMessageCount = Message::whereIn('supply_demand_id', $prevSupplyDemand->pluck('id'))->count(); + + // 当期交互次数(同一个dialogue_id一来一回算一次交互) + $interactionCount = Message::whereBetween('created_at', [$startDate, $endDate]) + ->whereNotNull('dialogue_id') + ->groupBy('dialogue_id') + ->selectRaw('dialogue_id, COUNT(*) as message_count') + ->having('message_count', '>=', 2) + ->count(); + + // 上期交互次数 + $prevInteractionCount = Message::whereBetween('created_at', [$prevStartDate, $prevEndDate]) + ->whereNotNull('dialogue_id') + ->groupBy('dialogue_id') + ->selectRaw('dialogue_id, COUNT(*) as message_count') + ->having('message_count', '>=', 2) + ->count(); + + // 计算增减比率 + $supplyDemandGrowthRate = $this->calculateGrowthRate($supplyDemandCount, $prevSupplyDemandCount); + $messageGrowthRate = $this->calculateGrowthRate($messageCount, $prevMessageCount); + $interactionGrowthRate = $this->calculateGrowthRate($interactionCount, $prevInteractionCount); + + return $this->success([ + 'supply_demand_count' => $supplyDemandCount, + 'prev_supply_demand_count' => $prevSupplyDemandCount, + 'supply_demand_growth_rate' => $supplyDemandGrowthRate, + 'message_count' => $messageCount, + 'prev_message_count' => $prevMessageCount, + 'message_growth_rate' => $messageGrowthRate, + 'interaction_count' => $interactionCount, + 'prev_interaction_count' => $prevInteractionCount, + 'interaction_growth_rate' => $interactionGrowthRate, + ]); + } + + /** + * 计算增长率 + * @param int $current 当前数值 + * @param int $previous 上期数值 + * @return array 包含增长率和增长状态 + */ + private function calculateGrowthRate($current, $previous) + { + if ($previous == 0) { + if ($current > 0) { + return [ + 'rate' => 100, + 'status' => 'increase', + 'display' => '+100%' + ]; + } else { + return [ + 'rate' => 0, + 'status' => 'stable', + 'display' => '0%' + ]; + } + } + + $rate = round(($current - $previous) / $previous * 100, 2); + + if ($rate > 0) { + $status = 'increase'; + $display = '+' . $rate . '%'; + } elseif ($rate < 0) { + $status = 'decrease'; + $display = $rate . '%'; + } else { + $status = 'stable'; + $display = '0%'; + } + + return [ + 'rate' => $rate, + 'status' => $status, + 'display' => $display + ]; } } From 8100bfc593b77a12a1814b9a82303cfb1596a8fc Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 15:20:55 +0800 Subject: [PATCH 24/42] update --- app/Http/Controllers/Admin/OtherController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index fd5791e..1545679 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -61,10 +61,10 @@ class OtherController extends CommonController ]; } // 追加其他领域 - $industryTotal[] = [ - 'industry' => '其他', - 'total' => User::count() - collect($industryTotal)->sum('total') - ]; +// $industryTotal[] = [ +// 'industry' => '其他', +// 'total' => User::count() - collect($industryTotal)->sum('total') +// ]; // 课程统计 $courseTypes = CourseType::where('is_chart', 1)->get(); foreach ($courseTypes as $courseType) { From 10f1db38cb9174acd9c243ab57975613aacef321 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 15:23:30 +0800 Subject: [PATCH 25/42] update --- app/Http/Controllers/Admin/OtherController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index 1545679..ef880f1 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -41,9 +41,9 @@ class OtherController extends CommonController public function home() { // 校友总数 - $schoolmate['schoolmate_total'] = User::where('is_schoolmate', 1)->groupBy('mobile')->count(); + $schoolmate['schoolmate_total'] = User::where('is_schoolmate', 1)->distinct('mobile')->count(); // 2025年校友数 - $schoolmate['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->groupBy('mobile')->count(); + $schoolmate['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->distinct('mobile')->count(); // 上市企业总市值 $company['company_market'] = Company::where('company_market', 1)->sum('market_value'); // 校友企业总融资额 From 1e0d8a6d9eaeb4d47e2eac27fb0c57b001587a06 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 16:08:13 +0800 Subject: [PATCH 26/42] update --- app/Http/Controllers/Admin/OtherController.php | 5 ----- database/migrations/2025_06_23_170000_create_books_table.php | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index ef880f1..2c3b0ed 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -60,11 +60,6 @@ class OtherController extends CommonController 'total' => User::whereIn('company_industry', $level2Names)->count() ]; } - // 追加其他领域 -// $industryTotal[] = [ -// 'industry' => '其他', -// 'total' => User::count() - collect($industryTotal)->sum('total') -// ]; // 课程统计 $courseTypes = CourseType::where('is_chart', 1)->get(); foreach ($courseTypes as $courseType) { diff --git a/database/migrations/2025_06_23_170000_create_books_table.php b/database/migrations/2025_06_23_170000_create_books_table.php index 587d950..9b63fde 100644 --- a/database/migrations/2025_06_23_170000_create_books_table.php +++ b/database/migrations/2025_06_23_170000_create_books_table.php @@ -21,7 +21,7 @@ return new class extends Migration { $table->string('author')->nullable()->comment('作者'); $table->string('isbn')->nullable()->comment('ISBN'); $table->string('publisher')->nullable()->comment('出版社'); - $table->year('publish_year')->nullable()->comment('出版年份'); + $table->string('publish_year')->nullable()->comment('出版年份'); $table->string('category')->nullable()->comment('分类'); $table->mediumText('description')->nullable()->comment('图书简介'); $table->integer('cover_id')->nullable()->comment('图书封面'); From d42da8724ff5ddb743ab072da4d315b3b957a17c Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 16:22:29 +0800 Subject: [PATCH 27/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 47 +++++++++++++++---- app/Http/Controllers/Admin/BookController.php | 29 +++++++++++- app/Models/Book.php | 14 +++++- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php index 244daf0..1336ed4 100644 --- a/app/Console/Commands/UpdateBookIsbnData.php +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -17,14 +17,14 @@ class UpdateBookIsbnData extends Command * * @var string */ - protected $signature = 'book:update-isbn-data'; + protected $signature = 'book:update-isbn-data {--book_id=} '; /** * The console command description. * * @var string */ - protected $description = '从ISBN接口获取书籍数据并下载封面图片'; + protected $description = '从ISBN接口获取书籍数据,更新出版社、作者、出版年份、简介等信息并下载封面图片'; /** * Create a new command instance. @@ -44,16 +44,30 @@ class UpdateBookIsbnData extends Command public function handle() { $apiKey = Config::getValueByKey('book_key'); + $book_id = $this->option('book_id'); // 获取所有有ISBN的书籍 $books = Book::whereNotNull('isbn') - ->where('isbn', '!=', '') - ->whereNull('cover_id') - // ->where('id', 1) - ->get(); + ->where(function ($query) use ($book_id) { + if ($book_id) { + $query->where('id', $book_id); + } + })->where('isbn', '!=', '') + ->where(function ($query) { + // 如果没有封面或者缺少基本信息字段,都需要处理 + $query->whereNull('cover_id') + ->orWhereNull('publisher') + ->orWhereNull('author') + ->orWhereNull('publish_year') + ->orWhereNull('description') + ->orWhere('publisher', '') + ->orWhere('author', '') + ->orWhere('publish_year', '') + ->orWhere('description', ''); + })->get(); if ($books->isEmpty()) { - $this->info('没有找到未处理封面的书籍'); + $this->info('没有找到需要更新数据的书籍'); return 0; } @@ -169,7 +183,24 @@ class UpdateBookIsbnData extends Command $bookData = $data['data']; - // 更新书籍的other_data字段 + // 更新书籍的基本信息字段 + if (!empty($bookData['publisher'])) { + $book->publisher = $bookData['publisher']; + } + + if (!empty($bookData['author'])) { + $book->author = $bookData['author']; + } + + if (!empty($bookData['pubdate'])) { + $book->publish_year = $bookData['pubdate']; + } + + if (!empty($bookData['summary'])) { + $book->description = $bookData['summary']; + } + + // 更新书籍的other_data字段(保存完整的API响应数据) $book->other_data = $bookData; // 如果有图片URL,下载图片 diff --git a/app/Http/Controllers/Admin/BookController.php b/app/Http/Controllers/Admin/BookController.php index d256f78..9409d48 100644 --- a/app/Http/Controllers/Admin/BookController.php +++ b/app/Http/Controllers/Admin/BookController.php @@ -9,6 +9,7 @@ use App\Models\Book; use App\Models\CustomForm; use App\Models\CustomFormField; use App\Models\SupplyDemand; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; use Maatwebsite\Excel\Facades\Excel; @@ -217,7 +218,33 @@ class BookController extends BaseController */ public function save() { - return parent::save(); + $all = \request()->all(); + DB::beginTransaction(); + try { + if (isset($all['id'])) { + $model = $this->model->find($all['id']); + if (empty($model)) { + return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']); + } + } else { + $model = $this->model; + $all['admin_id'] = $this->getUserId(); + $all['department_id'] = $this->getUser()->department_id; + } + $original = $model->getOriginal(); + $model->fill($all); + $model->save(); + DB::commit(); + // 写封面和其他信息 + // 调用命令行更新 + Artisan::call("book:update-isbn-data --book_id={$model->id}"); + // 记录日志 + $this->saveLogs($original, $model); + return $this->success($model); + } catch (\Exception $exception) { + DB::rollBack(); + return $this->fail([$exception->getCode(), $exception->getMessage()]); + } } /** diff --git a/app/Models/Book.php b/app/Models/Book.php index 6ea9e2c..f207a66 100644 --- a/app/Models/Book.php +++ b/app/Models/Book.php @@ -4,11 +4,21 @@ namespace App\Models; class Book extends SoftDeletesModel { - protected $casts = ['other_data' => 'json']; + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'other_data' => 'json' + ]; + + /** + * Get the cover image for the book. + */ public function cover() { return $this->hasOne(Upload::class, 'id', 'cover_id'); } - } From a99b3ede0fba5ba45ae1ab5a0dfaecd6d77ce736 Mon Sep 17 00:00:00 2001 From: weizong song Date: Sat, 9 Aug 2025 16:26:32 +0800 Subject: [PATCH 28/42] up --- .gitignore | 1 + .../Commands/SeedCourseContentEvaluations.php | 58 +++ app/Models/Course.php | 5 + ...urseContentEvaluationTestDataGenerator.php | 405 ++++++++++++++++++ 4 files changed, 469 insertions(+) create mode 100644 app/Console/Commands/SeedCourseContentEvaluations.php create mode 100644 app/Services/TestData/CourseContentEvaluationTestDataGenerator.php diff --git a/.gitignore b/.gitignore index 4cd4b9a..f521362 100755 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ npm-debug.log yarn-error.log /.idea /.vscode +/.snapshots diff --git a/app/Console/Commands/SeedCourseContentEvaluations.php b/app/Console/Commands/SeedCourseContentEvaluations.php new file mode 100644 index 0000000..b96d42e --- /dev/null +++ b/app/Console/Commands/SeedCourseContentEvaluations.php @@ -0,0 +1,58 @@ +option('evaluations'); + $minUsers = (int) $this->option('users'); + + $this->info("开始生成课程内容评价测试数据..."); + $this->info("计划生成 {$evaluationCount} 个评价问卷,确保至少 {$minUsers} 个用户"); + + $generator = new CourseContentEvaluationTestDataGenerator(); + + $startTime = microtime(true); + + try { + $generator->generate($evaluationCount, $minUsers, function (string $message) { + $this->line(" → {$message}"); + }); + + $duration = round(microtime(true) - $startTime, 2); + $this->info("✅ 数据生成完成!耗时 {$duration} 秒"); + + return Command::SUCCESS; + + } catch (\Exception $e) { + $this->error("❌ 数据生成失败:" . $e->getMessage()); + return Command::FAILURE; + } + } +} diff --git a/app/Models/Course.php b/app/Models/Course.php index f7a94db..7fd70be 100755 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -94,6 +94,11 @@ class Course extends SoftDeletesModel return $this->hasOne(Upload::class, 'id', 'qun_image_id'); } + public function courseContents() + { + return $this->hasMany(CourseContent::class, 'course_id', 'id'); + } + /** * 更新课程报名状态 */ diff --git a/app/Services/TestData/CourseContentEvaluationTestDataGenerator.php b/app/Services/TestData/CourseContentEvaluationTestDataGenerator.php new file mode 100644 index 0000000..ac613c8 --- /dev/null +++ b/app/Services/TestData/CourseContentEvaluationTestDataGenerator.php @@ -0,0 +1,405 @@ +create(); + } + + $allUsers = User::all(); + if ($allUsers->count() < 5) { + throw new \RuntimeException('生成评价数据至少需要5个用户'); + } + + // 2) 确保课程和课程内容存在 + $courses = Course::with('courseContents')->get(); + if ($courses->isEmpty()) { + $log("创建示例课程数据"); + $this->createSampleCoursesAndContents($faker); + $courses = Course::with('courseContents')->get(); + } + + $allCourseContents = CourseContent::all(); + if ($allCourseContents->isEmpty()) { + throw new \RuntimeException('无课程内容数据,无法生成评价'); + } + + // 3) 生成评价问卷主数据 + for ($i = 0; $i < $evaluationCount; $i++) { + $courseContent = $allCourseContents->random(); + $course = $courses->where('id', $courseContent->course_id)->first(); + + if (!$course) { + // 如果找不到课程,跳过这个课程内容 + continue; + } + + $evaluation = $this->createEvaluation($courseContent, $course, $faker); + + // 4) 为每个问卷生成问题字段 + $askCount = $faker->numberBetween(5, 15); + $asks = $this->createEvaluationAsks($evaluation, $courseContent, $course, $askCount, $faker); + + // 5) 生成用户提交的表单数据 + $formCount = $faker->numberBetween(10, min(40, $allUsers->count())); + $submittedUsers = $allUsers->random($formCount); + + foreach ($submittedUsers as $user) { + $this->createEvaluationForm($evaluation, $user, $asks, $faker); + } + + $log(sprintf('评价问卷#%d "%s" 已生成:%d个问题字段,%d份用户提交', + $evaluation->id, + $evaluation->title, + $askCount, + $formCount + )); + } + }); + } + + /** + * 创建评价问卷主数据 + */ + private function createEvaluation(CourseContent $courseContent, Course $course, $faker): CourseContentEvaluation + { + $evaluation = new CourseContentEvaluation(); + $evaluation->course_id = $course->id; + $evaluation->course_content_id = $courseContent->id; + $evaluation->title = $this->generateEvaluationTitle($course, $courseContent, $faker); + $evaluation->desc = $this->generateEvaluationDesc($faker); + $evaluation->type_id = $faker->numberBetween(1, 5); // 问卷类型ID + + // 时间设置:开始时间在课程内容时间前后,截止时间在开始时间之后 + $startTime = $faker->dateTimeBetween('-30 days', '+7 days'); + $endTime = $faker->dateTimeBetween($startTime, $startTime->format('Y-m-d H:i:s') . ' +30 days'); + + $evaluation->start_time = $startTime->format('Y-m-d H:i:s'); + $evaluation->end_time = $endTime->format('Y-m-d H:i:s'); + $evaluation->status = $faker->randomElement([0, 1]); // 0未发布, 1已发布 + $evaluation->save(); + + return $evaluation; + } + + /** + * 创建评价问题字段 + */ + private function createEvaluationAsks(CourseContentEvaluation $evaluation, CourseContent $courseContent, Course $course, int $count, $faker): array + { + $asks = []; + $fieldTemplates = $this->getEvaluationFieldTemplates(); + + for ($i = 0; $i < $count; $i++) { + $template = $faker->randomElement($fieldTemplates); + + $ask = new CourseContentEvaluationAsk(); + $ask->admin_id = $faker->numberBetween(1, 10); + $ask->department_id = $faker->numberBetween(1, 5); + $ask->course_id = $course->id; + $ask->course_content_id = $courseContent->id; + $ask->course_content_evaluation_id = $evaluation->id; + $ask->name = $template['name']; + $ask->field = $template['field'] . '_' . ($i + 1); + $ask->edit_input = $template['edit_input']; + $ask->rule = $template['rule']; + $ask->sort = $i + 1; + $ask->help = $template['help']; + $ask->select_item = $template['select_item']; + $ask->need_fill = $template['need_fill']; + $ask->belong_user = $template['belong_user']; + $ask->allow_input = $template['allow_input']; + $ask->save(); + + $asks[] = $ask; + } + + return $asks; + } + + /** + * 创建用户提交的评价表单 + */ + private function createEvaluationForm(CourseContentEvaluation $evaluation, User $user, array $asks, $faker): void + { + $formData = []; + + foreach ($asks as $ask) { + $formData[$ask->field] = $this->generateFieldValue($ask, $faker); + } + + $form = new CourseContentEvaluationForm(); + $form->course_content_evaluation_id = $evaluation->id; + $form->user_id = $user->id; + $form->time_total = $faker->numberBetween(180, 1800); // 3分钟到30分钟 + $form->data = $formData; + $form->created_at = $faker->dateTimeBetween($evaluation->start_time, $evaluation->end_time ?: 'now'); + $form->save(); + } + + /** + * 生成评价标题 + */ + private function generateEvaluationTitle(Course $course, CourseContent $courseContent, $faker): string + { + $templates = [ + '《%s》课程满意度调查', + '%s 教学效果评价', + '%s 学习体验反馈', + '关于 %s 的教学质量评估', + '%s 课程内容评价问卷', + '%s 授课情况调研', + '%s 学员反馈调查' + ]; + + $courseName = $course->title ?? '课程'; + return sprintf($faker->randomElement($templates), $courseName); + } + + /** + * 生成评价描述 + */ + private function generateEvaluationDesc($faker): string + { + $descriptions = [ + '为了提升教学质量,改进课程内容,请您根据实际学习体验,客观填写本次评价问卷。您的宝贵意见将帮助我们持续优化课程设计。', + '此次评价旨在了解您对本课程的学习感受和建议。问卷采用匿名形式,请放心填写真实想法,感谢您的配合!', + '请根据您的实际学习情况,对本次课程的各个方面进行客观评价。您的反馈对我们改进教学方法具有重要意义。', + '为持续提升课程品质,特设立本次学员满意度调查。请您花费几分钟时间,帮助我们了解课程的优点与不足。', + '感谢您参与本次课程学习!为了给后续学员提供更好的学习体验,恳请您如实填写这份评价问卷。' + ]; + + return $faker->randomElement($descriptions); + } + + /** + * 获取评价字段模板 + */ + private function getEvaluationFieldTemplates(): array + { + return [ + [ + 'name' => '课程内容满意度', + 'field' => 'content_satisfaction', + 'edit_input' => 'radio', + 'rule' => 'required', + 'help' => '请选择您对课程内容的满意程度', + 'select_item' => ['非常满意', '满意', '一般', '不满意', '非常不满意'], + 'need_fill' => true, + 'belong_user' => false, + 'allow_input' => false + ], + [ + 'name' => '授课方式评价', + 'field' => 'teaching_method', + 'edit_input' => 'radio', + 'rule' => 'required', + 'help' => '请评价老师的授课方式', + 'select_item' => ['很好', '好', '一般', '较差', '很差'], + 'need_fill' => true, + 'belong_user' => false, + 'allow_input' => false + ], + [ + 'name' => '课程难度评价', + 'field' => 'difficulty_level', + 'edit_input' => 'radio', + 'rule' => 'required', + 'help' => '您认为课程难度如何', + 'select_item' => ['太简单', '偏简单', '适中', '偏难', '太难'], + 'need_fill' => true, + 'belong_user' => false, + 'allow_input' => false + ], + [ + 'name' => '学习收获评价', + 'field' => 'learning_gain', + 'edit_input' => 'checkbox', + 'rule' => '', + 'help' => '您在本次学习中获得了哪些收获(可多选)', + 'select_item' => ['理论知识', '实践技能', '思维方法', '行业认知', '人际交往', '其他'], + 'need_fill' => false, + 'belong_user' => false, + 'allow_input' => true + ], + [ + 'name' => '课程推荐度', + 'field' => 'recommendation', + 'edit_input' => 'radio', + 'rule' => 'required', + 'help' => '您是否愿意向他人推荐此课程', + 'select_item' => ['非常愿意', '愿意', '无所谓', '不愿意', '绝对不会'], + 'need_fill' => true, + 'belong_user' => false, + 'allow_input' => false + ], + [ + 'name' => '整体评分', + 'field' => 'overall_rating', + 'edit_input' => 'select', + 'rule' => 'required', + 'help' => '请为本次课程打分(10分制)', + 'select_item' => ['10分', '9分', '8分', '7分', '6分', '5分', '4分', '3分', '2分', '1分'], + 'need_fill' => true, + 'belong_user' => false, + 'allow_input' => false + ], + [ + 'name' => '意见建议', + 'field' => 'suggestions', + 'edit_input' => 'textarea', + 'rule' => '', + 'help' => '请提出您的宝贵意见和建议', + 'select_item' => null, + 'need_fill' => false, + 'belong_user' => false, + 'allow_input' => true + ], + [ + 'name' => '您的姓名', + 'field' => 'student_name', + 'edit_input' => 'text', + 'rule' => '', + 'help' => '请填写您的真实姓名(可选)', + 'select_item' => null, + 'need_fill' => false, + 'belong_user' => true, + 'allow_input' => false + ], + [ + 'name' => '联系方式', + 'field' => 'contact_info', + 'edit_input' => 'text', + 'rule' => '', + 'help' => '如需回访,请留下联系方式', + 'select_item' => null, + 'need_fill' => false, + 'belong_user' => true, + 'allow_input' => false + ], + [ + 'name' => '课堂互动评价', + 'field' => 'interaction_rating', + 'edit_input' => 'radio', + 'rule' => '', + 'help' => '您对课堂互动环节的评价', + 'select_item' => ['很活跃', '较活跃', '一般', '较沉闷', '很沉闷'], + 'need_fill' => false, + 'belong_user' => false, + 'allow_input' => false + ] + ]; + } + + /** + * 根据字段类型生成对应的值 + */ + private function generateFieldValue(CourseContentEvaluationAsk $ask, $faker) + { + switch ($ask->edit_input) { + case 'radio': + case 'select': + return $faker->randomElement($ask->select_item ?? []); + + case 'checkbox': + $options = $ask->select_item ?? []; + $selected = $faker->randomElements($options, $faker->numberBetween(1, min(3, count($options)))); + return implode(',', $selected); + + case 'textarea': + $suggestions = [ + '希望增加更多实践环节', + '课程进度可以适当放慢', + '案例分析很有帮助,建议增加', + '老师讲解很清晰,受益良多', + '课程资料很丰富,感谢分享', + '希望提供更多课后练习', + '建议增加小组讨论时间', + '整体非常满意,期待后续课程' + ]; + return $faker->optional(0.7)->randomElement($suggestions) ?: ''; + + case 'text': + if ($ask->field === 'student_name') { + return $faker->optional(0.4)->name ?: ''; + } elseif ($ask->field === 'contact_info') { + return $faker->optional(0.3)->phoneNumber ?: ''; + } + return $faker->optional(0.5)->words(3, true) ?: ''; + + default: + return ''; + } + } + + /** + * 创建示例课程和课程内容数据(如果不存在) + */ + private function createSampleCoursesAndContents($faker): void + { + $courseData = [ + ['title' => 'Python 程序设计基础', 'contents' => ['Python 语言概述', '数据类型与变量', '控制结构', '函数与模块', '面向对象编程']], + ['title' => '数据库原理与应用', 'contents' => ['数据库基础概念', 'SQL 语言基础', '数据库设计', '事务处理', '性能优化']], + ['title' => '项目管理实务', 'contents' => ['项目管理概述', '项目计划制定', '风险管理', '团队管理', '项目收尾']], + ['title' => '市场营销学', 'contents' => ['市场营销概论', '消费者行为分析', '产品策略', '价格策略', '推广策略']], + ['title' => 'Web 前端开发', 'contents' => ['HTML 基础', 'CSS 样式设计', 'JavaScript 编程', 'Vue.js 框架', '项目实战']] + ]; + + foreach ($courseData as $data) { + $course = Course::create([ + 'title' => $data['title'], + 'description' => $data['title'] . '课程', + 'status' => 1, + 'created_at' => now(), + 'updated_at' => now() + ]); + + foreach ($data['contents'] as $index => $contentTitle) { + CourseContent::create([ + 'course_id' => $course->id, + 'title' => $contentTitle, + 'description' => $contentTitle . '相关内容', + 'sort' => $index + 1, + 'status' => 1, + 'created_at' => now(), + 'updated_at' => now() + ]); + } + } + } +} \ No newline at end of file From 14237668e0de43e7a08c1a0c51de9d18d1954a90 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 17:29:30 +0800 Subject: [PATCH 29/42] update --- .../Commands/LinkCoursesToCalendar.php | 302 +++++++++++++++++ app/Console/Commands/UpdateCourseUrls.php | 313 ++++++++++++++++++ .../Controllers/Mobile/UserController.php | 2 +- composer.json | 1 + course_url_update_readme.md | 104 ++++++ link_courses_to_calendar_readme.md | 143 ++++++++ 课程台账.xlsx | Bin 0 -> 14754 bytes 7 files changed, 864 insertions(+), 1 deletion(-) create mode 100644 app/Console/Commands/LinkCoursesToCalendar.php create mode 100644 app/Console/Commands/UpdateCourseUrls.php create mode 100644 course_url_update_readme.md create mode 100644 link_courses_to_calendar_readme.md create mode 100644 课程台账.xlsx diff --git a/app/Console/Commands/LinkCoursesToCalendar.php b/app/Console/Commands/LinkCoursesToCalendar.php new file mode 100644 index 0000000..e661984 --- /dev/null +++ b/app/Console/Commands/LinkCoursesToCalendar.php @@ -0,0 +1,302 @@ +info("开始将课程关联到calendars日历表..."); + $this->info("总共需要处理 " . count($this->courseList) . " 个课程"); + + $linkedCount = 0; + $notFoundCourses = []; + $alreadyLinkedCourses = []; + + DB::beginTransaction(); + + try { + foreach ($this->courseList as $courseName) { + $this->info("正在处理课程: {$courseName}"); + + // 查找匹配的课程 + $course = $this->findCourse($courseName); + + if (!$course) { + $this->warn("✗ 未找到匹配的课程: {$courseName}"); + $notFoundCourses[] = $courseName; + continue; + } + + $this->info("✓ 找到匹配课程: {$course->name} (ID: {$course->id})"); + + // 检查是否已经存在日历记录 + $existingCalendar = Calendar::where('course_id', $course->id) + ->where('type', 1) // 类型1为课程 + ->first(); + + if ($existingCalendar) { + $this->warn("⚠ 课程已存在日历记录: {$course->name}"); + $alreadyLinkedCourses[] = $course->name; + continue; + } + + // 创建日历记录 + $calendarData = $this->createCalendarData($course); + $calendar = Calendar::create($calendarData); + + $this->info("✓ 成功创建日历记录 (ID: {$calendar->id}) 关联课程: {$course->name}"); + $linkedCount++; + } + + DB::commit(); + + $this->info("\n" . str_repeat('=', 60)); + $this->info("处理完成!"); + $this->info("成功关联课程数量: {$linkedCount}"); + $this->info("已存在日历记录: " . count($alreadyLinkedCourses)); + $this->info("未找到匹配课程: " . count($notFoundCourses)); + + // 显示未找到的课程 + if (!empty($notFoundCourses)) { + $this->warn("\n未找到匹配的课程列表:"); + foreach ($notFoundCourses as $course) { + $this->warn(" - {$course}"); + } + } + + // 显示已存在日历记录的课程 + if (!empty($alreadyLinkedCourses)) { + $this->warn("\n已存在日历记录的课程列表:"); + foreach ($alreadyLinkedCourses as $course) { + $this->warn(" - {$course}"); + } + } + + } catch (\Exception $e) { + DB::rollback(); + $this->error("处理过程中发生错误: " . $e->getMessage()); + $this->error("已回滚所有更改"); + return; + } + + $this->info("\n所有操作已完成!"); + } + + /** + * 查找匹配的课程 + */ + private function findCourse($courseName) + { + // 1. 精确匹配 + $course = Course::where('name', $courseName) + ->whereNull('deleted_at') + ->first(); + + if ($course) { + return $course; + } + + // 2. 模糊匹配 + $course = Course::where('name', 'like', "%{$courseName}%") + ->whereNull('deleted_at') + ->first(); + + if ($course) { + $this->info("通过模糊匹配找到课程: '{$course->name}'"); + return $course; + } + + // 3. 相似度匹配 + $courses = Course::whereNull('deleted_at') + ->whereNotNull('name') + ->where('name', '!=', '') + ->get(); + + $bestMatch = null; + $highestSimilarity = 0; + + foreach ($courses as $course) { + $similarity = $this->calculateSimilarity($courseName, $course->name); + if ($similarity > $highestSimilarity) { + $highestSimilarity = $similarity; + $bestMatch = $course; + } + } + + if ($bestMatch && $highestSimilarity > 0.3) { // 设置最低相似度阈值 + $this->info("通过相似度匹配找到课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}'"); + return $bestMatch; + } + + return null; + } + + /** + * 创建日历数据 + */ + private function createCalendarData($course) + { + return [ + 'type' => 1, // 类型1为课程 + 'course_id' => $course->id, + 'date' => $course->start_date ?? now()->format('Y-m-d'), + 'title' => $course->name, + 'content' => $course->content ?? '', + 'start_time' => $course->start_date ? $course->start_date . ' 09:00:00' : null, + 'end_time' => $course->end_date ? $course->end_date . ' 17:00:00' : null, + 'url' => $course->url ?? '', + 'created_at' => now(), + 'updated_at' => now(), + ]; + } + + /** + * 计算字符串相似度 + */ + private function calculateSimilarity($str1, $str2) + { + // 移除空格并转换为小写 + $str1 = strtolower(preg_replace('/\s+/', '', $str1)); + $str2 = strtolower(preg_replace('/\s+/', '', $str2)); + + if ($str1 === $str2) { + return 1.0; + } + + if (empty($str1) || empty($str2)) { + return 0.0; + } + + // 使用Levenshtein距离计算相似度 + $maxLen = max(strlen($str1), strlen($str2)); + if ($maxLen == 0) { + return 1.0; + } + + $distance = levenshtein($str1, $str2); + $similarity = 1 - ($distance / $maxLen); + + // 如果其中一个字符串包含另一个,提高相似度 + if (strpos($str1, $str2) !== false || strpos($str2, $str1) !== false) { + $containsSimilarity = min(strlen($str1), strlen($str2)) / $maxLen; + $similarity = max($similarity, $containsSimilarity); + } + + return max(0, $similarity); + } +} diff --git a/app/Console/Commands/UpdateCourseUrls.php b/app/Console/Commands/UpdateCourseUrls.php new file mode 100644 index 0000000..d238d21 --- /dev/null +++ b/app/Console/Commands/UpdateCourseUrls.php @@ -0,0 +1,313 @@ +argument('file'); + $filePath = base_path($fileName); + + if (!file_exists($filePath)) { + $this->error("文件不存在: {$filePath}"); + return; + } + + $this->info("开始处理文件: {$fileName}"); + + try { + // 读取Excel文件 + $spreadsheet = IOFactory::load($filePath); + $sheetCount = $spreadsheet->getSheetCount(); + + $this->info("Excel文件包含 {$sheetCount} 个工作表"); + + $totalUpdated = 0; + + // 处理每个工作表 + for ($sheetIndex = 0; $sheetIndex < $sheetCount; $sheetIndex++) { + $worksheet = $spreadsheet->getSheet($sheetIndex); + $sheetName = $worksheet->getTitle(); + + $this->info("正在处理工作表: {$sheetName}"); + + $updated = $this->processWorksheet($worksheet, $sheetName); + $totalUpdated += $updated; + } + + $this->info("处理完成,总共更新了 {$totalUpdated} 条记录"); + + } catch (\Exception $e) { + $this->error("处理Excel文件时发生错误: " . $e->getMessage()); + return; + } + } + + /** + * 处理单个工作表 + */ + private function processWorksheet($worksheet, $sheetName) + { + $highestRow = $worksheet->getHighestRow(); + $highestColumn = $worksheet->getHighestColumn(); + + $this->info("工作表 {$sheetName} 有 {$highestRow} 行,最高列为 {$highestColumn}"); + + // 读取第一行作为表头 + $headers = []; + $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); + + for ($col = 1; $col <= $highestColumnIndex; $col++) { + $cellValue = $worksheet->getCellByColumnAndRow($col, 1)->getCalculatedValue(); + $headers[$col] = trim($cellValue); + } + + $this->info("表头: " . implode(', ', $headers)); + + // 找到"课程"和"跳转链接"列的位置 + $courseColumn = null; + $linkColumn = null; + + foreach ($headers as $colIndex => $header) { + if (strpos($header, '课程') !== false) { + $courseColumn = $colIndex; + } + if (strpos($header, '跳转链接') !== false) { + $linkColumn = $colIndex; + } + } + + if (!$courseColumn || !$linkColumn) { + $this->warn("工作表 {$sheetName} 中未找到'课程'或'跳转链接'列"); + return 0; + } + + $this->info("找到课程列: {$courseColumn},跳转链接列: {$linkColumn}"); + + $updated = 0; + $failedCourses = []; + + // 处理数据行 + for ($row = 2; $row <= $highestRow; $row++) { + $courseName = trim($worksheet->getCellByColumnAndRow($courseColumn, $row)->getCalculatedValue()); + $jumpLink = trim($worksheet->getCellByColumnAndRow($linkColumn, $row)->getCalculatedValue()); + + if (empty($courseName) || empty($jumpLink)) { + continue; + } + + $this->info("处理行 {$row}: 课程='{$courseName}', 跳转链接='{$jumpLink}'"); + + // 从phome_ecms_news表获取titleurl + $titleUrl = $this->getTitleUrlFromNews($jumpLink); + + if ($titleUrl) { + // 更新courses表 + $updateCount = $this->updateCourseUrl($courseName, $titleUrl); + $updated += $updateCount; + + if ($updateCount > 0) { + $this->info("✓ 成功更新课程 '{$courseName}' 的URL为: {$titleUrl}"); + } else { + $this->warn("✗ 未找到匹配的课程: '{$courseName}'"); + $failedCourses[] = $courseName; + } + } else { + $this->warn("✗ 未找到匹配的新闻标题: '{$jumpLink}'"); + } + } + + // 显示匹配失败的课程 + if (!empty($failedCourses)) { + $this->warn("工作表 {$sheetName} 中匹配失败的课程:"); + foreach ($failedCourses as $failedCourse) { + $this->warn(" - {$failedCourse}"); + } + } + + return $updated; + } + + /** + * 从phome_ecms_news表获取titleurl + */ + private function getTitleUrlFromNews($title) + { + try { + // 直接匹配 + $news = DB::table('phome_ecms_news') + ->where('title', $title) + ->first(); + + if ($news && !empty($news->titleurl)) { + return $news->titleurl; + } + + // 模糊匹配 + $news = DB::table('phome_ecms_news') + ->where('title', 'like', "%{$title}%") + ->first(); + + if ($news && !empty($news->titleurl)) { + $this->info("通过模糊匹配找到: '{$news->title}' -> '{$news->titleurl}'"); + return $news->titleurl; + } + + // 使用相似度匹配 + $allNews = DB::table('phome_ecms_news') + ->whereNotNull('title') + ->whereNotNull('titleurl') + ->where('title', '!=', '') + ->where('titleurl', '!=', '') + ->get(); + + $bestMatch = null; + $highestSimilarity = 0; + + foreach ($allNews as $news) { + $similarity = $this->calculateSimilarity($title, $news->title); + if ($similarity > $highestSimilarity) { + $highestSimilarity = $similarity; + $bestMatch = $news; + } + } + + if ($bestMatch && $highestSimilarity > 0) { + $this->info("通过相似度匹配找到 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->title}' -> '{$bestMatch->titleurl}'"); + return $bestMatch->titleurl; + } + + } catch (\Exception $e) { + $this->error("查询phome_ecms_news表时发生错误: " . $e->getMessage()); + } + + return null; + } + + /** + * 更新courses表的url字段 + */ + private function updateCourseUrl($courseName, $titleUrl) + { + try { + // 直接匹配 + $updateCount = Course::where('name', $courseName) + ->whereNull('deleted_at') + ->update(['url' => $titleUrl]); + + if ($updateCount > 0) { + return $updateCount; + } + + // 模糊匹配 + $updateCount = Course::where('name', 'like', "%{$courseName}%") + ->whereNull('deleted_at') + ->update(['url' => $titleUrl]); + + if ($updateCount > 0) { + $this->info("通过模糊匹配更新了课程"); + return $updateCount; + } + + // 使用相似度匹配 + $courses = Course::whereNull('deleted_at') + ->whereNotNull('name') + ->where('name', '!=', '') + ->get(); + + $bestMatch = null; + $highestSimilarity = 0; + + foreach ($courses as $course) { + $similarity = $this->calculateSimilarity($courseName, $course->name); + if ($similarity > $highestSimilarity) { + $highestSimilarity = $similarity; + $bestMatch = $course; + } + } + + if ($bestMatch && $highestSimilarity > 0) { + $bestMatch->url = $titleUrl; + $bestMatch->save(); + $this->info("通过相似度匹配更新了课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}'"); + return 1; + } + + } catch (\Exception $e) { + $this->error("更新courses表时发生错误: " . $e->getMessage()); + } + + return 0; + } + + /** + * 计算字符串相似度 + */ + private function calculateSimilarity($str1, $str2) + { + // 移除空格并转换为小写 + $str1 = strtolower(preg_replace('/\s+/', '', $str1)); + $str2 = strtolower(preg_replace('/\s+/', '', $str2)); + + if ($str1 === $str2) { + return 1.0; + } + + if (empty($str1) || empty($str2)) { + return 0.0; + } + + // 使用Levenshtein距离计算相似度 + $maxLen = max(strlen($str1), strlen($str2)); + if ($maxLen == 0) { + return 1.0; + } + + $distance = levenshtein($str1, $str2); + $similarity = 1 - ($distance / $maxLen); + + // 如果其中一个字符串包含另一个,提高相似度 + if (strpos($str1, $str2) !== false || strpos($str2, $str1) !== false) { + $containsSimilarity = min(strlen($str1), strlen($str2)) / $maxLen; + $similarity = max($similarity, $containsSimilarity); + } + + return max(0, $similarity); + } +} diff --git a/app/Http/Controllers/Mobile/UserController.php b/app/Http/Controllers/Mobile/UserController.php index e182f5b..ce4ad43 100755 --- a/app/Http/Controllers/Mobile/UserController.php +++ b/app/Http/Controllers/Mobile/UserController.php @@ -175,7 +175,7 @@ class UserController extends CommonController $all['letter'] = strtoupper(Pinyin::abbr(mb_substr($all['name'], 0, 1))[0]); } // 如果有公司信息,就更新一下公司 - if (!empty($all['company_name'] && $model->company_name != $all['company_name'])) { + if (isset($all['company_name']) && !empty($all['company_name']) && $model->company_name != $all['company_name']) { // 调用命令行更新 Artisan::call("update_company --user_id={$model->id}"); } diff --git a/composer.json b/composer.json index 3e505c5..8efdc80 100755 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "overtrue/pinyin": "^5.0", "overtrue/wechat": "~5.0", "owen-it/laravel-auditing": "^13.6", + "phpoffice/phpspreadsheet": "^1.29", "prettus/l5-repository": "^2.9", "rap2hpoutre/fast-excel": "^5.2", "simplesoftwareio/simple-qrcode": "^4.2", diff --git a/course_url_update_readme.md b/course_url_update_readme.md new file mode 100644 index 0000000..fb41718 --- /dev/null +++ b/course_url_update_readme.md @@ -0,0 +1,104 @@ +# 课程URL更新命令使用说明 + +## 功能描述 + +这个Laravel命令 `UpdateCourseUrls` 用于从Excel文件读取课程信息,并自动更新数据库中课程的URL字段。 + +## 主要功能 + +1. **Excel文件解析**: 读取Excel文件中的课程数据和跳转链接信息 +2. **数据匹配**: 从`phome_ecms_news`表中根据跳转链接匹配title字段,获取对应的titleurl +3. **智能匹配**: 支持精确匹配、模糊匹配和相似度匹配三种方式 +4. **批量更新**: 将获取到的titleurl批量更新到`courses`表的url字段 + +## 命令使用方法 + +### 基本用法 +```bash +php artisan update:course-urls +``` + +### 指定Excel文件 +```bash +php artisan update:course-urls "your_excel_file.xlsx" +``` + +## Excel文件格式要求 + +Excel文件需要包含以下列: +- **课程**: 包含课程名称的列 +- **跳转链接**: 包含需要匹配的标题的列 + +文件可以包含多个工作表,命令会自动处理所有工作表。 + +## 匹配逻辑 + +### 1. 新闻标题匹配(从phome_ecms_news表) +- **精确匹配**: 直接匹配title字段 +- **模糊匹配**: 使用LIKE进行部分匹配 +- **相似度匹配**: 使用Levenshtein算法计算字符串相似度,自动选择相似度最高的记录 + +### 2. 课程名称匹配(更新courses表) +- **精确匹配**: 直接匹配name字段 +- **模糊匹配**: 使用LIKE进行部分匹配 +- **相似度匹配**: 使用Levenshtein算法计算字符串相似度,自动选择相似度最高的记录 + +## 特殊处理 + +1. **软删除过滤**: 只处理未被软删除的课程记录 +2. **空值检查**: 自动跳过空的课程名称或跳转链接 +3. **重复更新**: 如果课程已有URL,会被新的URL覆盖 +4. **详细日志**: 提供详细的处理日志,包括匹配方式和相似度信息 +5. **失败统计**: 自动显示匹配失败的课程名称列表 + +## 相似度算法说明 + +相似度计算使用多种策略: +- **Levenshtein距离**: 计算字符编辑距离 +- **包含检查**: 如果一个字符串包含另一个,会提高相似度 +- **预处理**: 移除空格并转换为小写进行比较 + +## 示例输出 + +``` +开始处理文件: 课程台账.xlsx +Excel文件包含 2 个工作表 +正在处理工作表: Sheet1 +工作表 Sheet1 有 10 行,最高列为 C +表头: 序号, 课程, 跳转链接 +找到课程列: 2,跳转链接列: 3 +处理行 2: 课程='Python基础课程', 跳转链接='Python编程入门教程' +通过相似度匹配找到 (相似度: 85.7%): 'Python编程入门教程完整版' -> '/news/python-tutorial-2024' +✓ 成功更新课程 'Python基础课程' 的URL为: /news/python-tutorial-2024 +工作表 Sheet1 中匹配失败的课程: + - 高级数据分析课程 + - 机器学习实战 +处理完成,总共更新了 6 条记录 +``` + +## 注意事项 + +1. 确保Excel文件位于项目根目录或提供正确的文件路径 +2. 确保数据库连接正常,特别是`phome_ecms_news`表的访问权限 +3. 建议在执行前备份`courses`表的数据 +4. 相似度匹配会自动选择最高相似度的记录,无需设置阈值 +5. 命令会显示所有匹配失败的课程名称,便于后续手动处理 + +## 错误处理 + +命令包含完善的错误处理机制: +- 文件不存在检查 +- 数据库连接错误处理 +- Excel格式错误处理 +- 详细的错误日志输出 + +## 数据库表结构要求 + +### phome_ecms_news表 +- `title`: 新闻标题字段 +- `titleurl`: 新闻URL字段 + +### courses表 +- `name`: 课程名称字段 +- `url`: 课程URL字段(会被更新) +- `deleted_at`: 软删除时间戳字段 diff --git a/link_courses_to_calendar_readme.md b/link_courses_to_calendar_readme.md new file mode 100644 index 0000000..e08439f --- /dev/null +++ b/link_courses_to_calendar_readme.md @@ -0,0 +1,143 @@ +# 课程关联日历命令使用说明 + +## 功能描述 + +这个Laravel命令 `LinkCoursesToCalendar` 用于将指定的课程列表自动关联到`calendars`日历表中。 + +## 主要功能 + +1. **批量课程关联**: 一次性处理69个指定的课程 +2. **智能匹配**: 支持精确匹配、模糊匹配和相似度匹配三种策略 +3. **重复检查**: 自动检查并跳过已存在日历记录的课程 +4. **事务保护**: 使用数据库事务确保数据一致性 +5. **详细统计**: 提供完整的处理结果统计 + +## 命令使用方法 + +### 基本用法 +```bash +php artisan link:courses-to-calendar +``` + +## 课程列表 + +命令会处理以下69个课程: + +### 高研班系列 +- 高研班|第四期高级科创人才研修班-第七模块 +- 高研班|第五期高级科创人才研修班-第五模块 +- 高研班|第六期高级科创人才研修班-第三模块 +- 高研班|第五期高级科创人才研修班-毕业模块 +- 高研班|第四期高级科创人才研修班-第八模块 +- ... (共29个高研班课程) + +### 第二课堂系列 +- 第二课堂|走进珂玛科技 +- 第二课堂|走进世华科技 +- 第二课堂|走进姑苏区 +- 第二课堂|走进科沃斯 +- ... (共17个第二课堂课程) + +### 其他培训类 +- 人才培训、初创班、攀峰班、产业加速营、专题培训等 (共23个课程) + +## 匹配策略 + +### 1. 精确匹配 +直接匹配courses表中的name字段 + +### 2. 模糊匹配 +使用LIKE查询进行部分匹配 + +### 3. 相似度匹配 +- 使用Levenshtein算法计算字符串相似度 +- 最低相似度阈值:30% +- 自动选择相似度最高的课程 + +## 日历记录创建 + +为每个匹配的课程创建以下日历记录: + +```php +[ + 'type' => 1, // 类型1为课程 + 'course_id' => $course->id, // 关联的课程ID + 'date' => $course->start_date, // 课程开始日期 + 'title' => $course->name, // 课程标题 + 'content' => $course->content, // 课程内容 + 'start_time' => '09:00:00', // 默认开始时间 + 'end_time' => '17:00:00', // 默认结束时间 + 'url' => $course->url, // 课程链接 +] +``` + +## 输出示例 + +``` +开始将课程关联到calendars日历表... +总共需要处理 69 个课程 +正在处理课程: 第三期:张平院士— 6G通信与AI融合 +✓ 找到匹配课程: 第三期:张平院士— 6G通信与AI融合 (ID: 123) +✓ 成功创建日历记录 (ID: 456) 关联课程: 第三期:张平院士— 6G通信与AI融合 + +正在处理课程: 高研班|第四期高级科创人才研修班-第七模块 +通过模糊匹配找到课程: '第四期高级科创人才研修班-第七模块' +✓ 成功创建日历记录 (ID: 457) 关联课程: 第四期高级科创人才研修班-第七模块 + +============================================================ +处理完成! +成功关联课程数量: 65 +已存在日历记录: 2 +未找到匹配课程: 2 + +未找到匹配的课程列表: + - 某个未找到的课程1 + - 某个未找到的课程2 + +已存在日历记录的课程列表: + - 某个已存在的课程1 + - 某个已存在的课程2 +``` + +## 安全特性 + +1. **数据库事务**: 所有操作在事务中执行,出错时自动回滚 +2. **重复检查**: 防止创建重复的日历记录 +3. **软删除过滤**: 只处理未被软删除的课程 +4. **错误处理**: 完善的异常处理机制 + +## 注意事项 + +1. **备份数据**: 建议执行前备份`calendars`表数据 +2. **权限检查**: 确保数据库连接正常,有足够的读写权限 +3. **课程匹配**: 相似度匹配可能不是100%准确,建议执行后检查结果 +4. **重复执行**: 命令可以安全地重复执行,已存在的记录会被跳过 + +## 错误处理 + +命令包含完善的错误处理机制: +- 数据库连接错误处理 +- 事务回滚保护 +- 详细的错误日志输出 +- 匹配失败统计 + +## 数据库表要求 + +### courses表 +- `id`: 主键 +- `name`: 课程名称 +- `start_date`: 开始日期 +- `end_date`: 结束日期 +- `content`: 课程内容 +- `url`: 课程链接 +- `deleted_at`: 软删除时间戳 + +### calendars表 +- `type`: 类型(1=课程,2=课堂,3=事件) +- `course_id`: 关联的课程ID +- `date`: 日期 +- `title`: 标题 +- `content`: 内容 +- `start_time`: 开始时间 +- `end_time`: 结束时间 +- `url`: 链接 diff --git a/课程台账.xlsx b/课程台账.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3bc5dde1b46d29ae16a036196038ad8770a720db GIT binary patch literal 14754 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 literal 0 HcmV?d00001 From cb860292d50523f47a1c4a9a7194d57e08229616 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 17:40:09 +0800 Subject: [PATCH 30/42] update --- .../Controllers/Mobile/CourseController.php | 33 ++-- course_url_update_readme.md | 104 ------------- link_courses_to_calendar_readme.md | 143 ------------------ 3 files changed, 19 insertions(+), 261 deletions(-) delete mode 100644 course_url_update_readme.md delete mode 100644 link_courses_to_calendar_readme.md diff --git a/app/Http/Controllers/Mobile/CourseController.php b/app/Http/Controllers/Mobile/CourseController.php index cf5ed68..bfa5fec 100755 --- a/app/Http/Controllers/Mobile/CourseController.php +++ b/app/Http/Controllers/Mobile/CourseController.php @@ -859,20 +859,25 @@ class CourseController extends CommonController if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } - $startDate = $all['month'] . '-01'; - $endDate = date('Y-m-t', strtotime($startDate)); - $range = getDates($startDate, $endDate); - $list = []; - foreach ($range as $date) { - // 查询Calendar模型里start_time和end_time在日期内的数据,其中date是年月日,start_time和end_time是时分秒 - $list[] = [ - 'date' => $date, - 'details' => Calendar::with('course', 'courseContent') - ->whereDate('start_time', '<=', $date) - ->whereDate('end_time', '>=', $date) - ->get() - ]; - } +// $startDate = $all['month'] . '-01'; +// $endDate = date('Y-m-t', strtotime($startDate)); + $list = Calendar::with('course', 'courseContent') + ->orderBy('start_time', 'asc') + ->whereDate('start_time', '<=', $all['month']) + ->get(); + +// $range = getDates($startDate, $endDate); +// $list = []; +// foreach ($range as $date) { +// // 查询Calendar模型里start_time和end_time在日期内的数据,其中date是年月日,start_time和end_time是时分秒 +// $list[] = [ +// 'date' => $date, +// 'details' => Calendar::with('course', 'courseContent') +// ->whereDate('start_time', '<=', $date) +// ->whereDate('end_time', '>=', $date) +// ->get() +// ]; +// } return $this->success($list); } diff --git a/course_url_update_readme.md b/course_url_update_readme.md deleted file mode 100644 index fb41718..0000000 --- a/course_url_update_readme.md +++ /dev/null @@ -1,104 +0,0 @@ -# 课程URL更新命令使用说明 - -## 功能描述 - -这个Laravel命令 `UpdateCourseUrls` 用于从Excel文件读取课程信息,并自动更新数据库中课程的URL字段。 - -## 主要功能 - -1. **Excel文件解析**: 读取Excel文件中的课程数据和跳转链接信息 -2. **数据匹配**: 从`phome_ecms_news`表中根据跳转链接匹配title字段,获取对应的titleurl -3. **智能匹配**: 支持精确匹配、模糊匹配和相似度匹配三种方式 -4. **批量更新**: 将获取到的titleurl批量更新到`courses`表的url字段 - -## 命令使用方法 - -### 基本用法 -```bash -php artisan update:course-urls -``` - -### 指定Excel文件 -```bash -php artisan update:course-urls "your_excel_file.xlsx" -``` - -## Excel文件格式要求 - -Excel文件需要包含以下列: -- **课程**: 包含课程名称的列 -- **跳转链接**: 包含需要匹配的标题的列 - -文件可以包含多个工作表,命令会自动处理所有工作表。 - -## 匹配逻辑 - -### 1. 新闻标题匹配(从phome_ecms_news表) -- **精确匹配**: 直接匹配title字段 -- **模糊匹配**: 使用LIKE进行部分匹配 -- **相似度匹配**: 使用Levenshtein算法计算字符串相似度,自动选择相似度最高的记录 - -### 2. 课程名称匹配(更新courses表) -- **精确匹配**: 直接匹配name字段 -- **模糊匹配**: 使用LIKE进行部分匹配 -- **相似度匹配**: 使用Levenshtein算法计算字符串相似度,自动选择相似度最高的记录 - -## 特殊处理 - -1. **软删除过滤**: 只处理未被软删除的课程记录 -2. **空值检查**: 自动跳过空的课程名称或跳转链接 -3. **重复更新**: 如果课程已有URL,会被新的URL覆盖 -4. **详细日志**: 提供详细的处理日志,包括匹配方式和相似度信息 -5. **失败统计**: 自动显示匹配失败的课程名称列表 - -## 相似度算法说明 - -相似度计算使用多种策略: -- **Levenshtein距离**: 计算字符编辑距离 -- **包含检查**: 如果一个字符串包含另一个,会提高相似度 -- **预处理**: 移除空格并转换为小写进行比较 - -## 示例输出 - -``` -开始处理文件: 课程台账.xlsx -Excel文件包含 2 个工作表 -正在处理工作表: Sheet1 -工作表 Sheet1 有 10 行,最高列为 C -表头: 序号, 课程, 跳转链接 -找到课程列: 2,跳转链接列: 3 -处理行 2: 课程='Python基础课程', 跳转链接='Python编程入门教程' -通过相似度匹配找到 (相似度: 85.7%): 'Python编程入门教程完整版' -> '/news/python-tutorial-2024' -✓ 成功更新课程 'Python基础课程' 的URL为: /news/python-tutorial-2024 -工作表 Sheet1 中匹配失败的课程: - - 高级数据分析课程 - - 机器学习实战 -处理完成,总共更新了 6 条记录 -``` - -## 注意事项 - -1. 确保Excel文件位于项目根目录或提供正确的文件路径 -2. 确保数据库连接正常,特别是`phome_ecms_news`表的访问权限 -3. 建议在执行前备份`courses`表的数据 -4. 相似度匹配会自动选择最高相似度的记录,无需设置阈值 -5. 命令会显示所有匹配失败的课程名称,便于后续手动处理 - -## 错误处理 - -命令包含完善的错误处理机制: -- 文件不存在检查 -- 数据库连接错误处理 -- Excel格式错误处理 -- 详细的错误日志输出 - -## 数据库表结构要求 - -### phome_ecms_news表 -- `title`: 新闻标题字段 -- `titleurl`: 新闻URL字段 - -### courses表 -- `name`: 课程名称字段 -- `url`: 课程URL字段(会被更新) -- `deleted_at`: 软删除时间戳字段 diff --git a/link_courses_to_calendar_readme.md b/link_courses_to_calendar_readme.md deleted file mode 100644 index e08439f..0000000 --- a/link_courses_to_calendar_readme.md +++ /dev/null @@ -1,143 +0,0 @@ -# 课程关联日历命令使用说明 - -## 功能描述 - -这个Laravel命令 `LinkCoursesToCalendar` 用于将指定的课程列表自动关联到`calendars`日历表中。 - -## 主要功能 - -1. **批量课程关联**: 一次性处理69个指定的课程 -2. **智能匹配**: 支持精确匹配、模糊匹配和相似度匹配三种策略 -3. **重复检查**: 自动检查并跳过已存在日历记录的课程 -4. **事务保护**: 使用数据库事务确保数据一致性 -5. **详细统计**: 提供完整的处理结果统计 - -## 命令使用方法 - -### 基本用法 -```bash -php artisan link:courses-to-calendar -``` - -## 课程列表 - -命令会处理以下69个课程: - -### 高研班系列 -- 高研班|第四期高级科创人才研修班-第七模块 -- 高研班|第五期高级科创人才研修班-第五模块 -- 高研班|第六期高级科创人才研修班-第三模块 -- 高研班|第五期高级科创人才研修班-毕业模块 -- 高研班|第四期高级科创人才研修班-第八模块 -- ... (共29个高研班课程) - -### 第二课堂系列 -- 第二课堂|走进珂玛科技 -- 第二课堂|走进世华科技 -- 第二课堂|走进姑苏区 -- 第二课堂|走进科沃斯 -- ... (共17个第二课堂课程) - -### 其他培训类 -- 人才培训、初创班、攀峰班、产业加速营、专题培训等 (共23个课程) - -## 匹配策略 - -### 1. 精确匹配 -直接匹配courses表中的name字段 - -### 2. 模糊匹配 -使用LIKE查询进行部分匹配 - -### 3. 相似度匹配 -- 使用Levenshtein算法计算字符串相似度 -- 最低相似度阈值:30% -- 自动选择相似度最高的课程 - -## 日历记录创建 - -为每个匹配的课程创建以下日历记录: - -```php -[ - 'type' => 1, // 类型1为课程 - 'course_id' => $course->id, // 关联的课程ID - 'date' => $course->start_date, // 课程开始日期 - 'title' => $course->name, // 课程标题 - 'content' => $course->content, // 课程内容 - 'start_time' => '09:00:00', // 默认开始时间 - 'end_time' => '17:00:00', // 默认结束时间 - 'url' => $course->url, // 课程链接 -] -``` - -## 输出示例 - -``` -开始将课程关联到calendars日历表... -总共需要处理 69 个课程 -正在处理课程: 第三期:张平院士— 6G通信与AI融合 -✓ 找到匹配课程: 第三期:张平院士— 6G通信与AI融合 (ID: 123) -✓ 成功创建日历记录 (ID: 456) 关联课程: 第三期:张平院士— 6G通信与AI融合 - -正在处理课程: 高研班|第四期高级科创人才研修班-第七模块 -通过模糊匹配找到课程: '第四期高级科创人才研修班-第七模块' -✓ 成功创建日历记录 (ID: 457) 关联课程: 第四期高级科创人才研修班-第七模块 - -============================================================ -处理完成! -成功关联课程数量: 65 -已存在日历记录: 2 -未找到匹配课程: 2 - -未找到匹配的课程列表: - - 某个未找到的课程1 - - 某个未找到的课程2 - -已存在日历记录的课程列表: - - 某个已存在的课程1 - - 某个已存在的课程2 -``` - -## 安全特性 - -1. **数据库事务**: 所有操作在事务中执行,出错时自动回滚 -2. **重复检查**: 防止创建重复的日历记录 -3. **软删除过滤**: 只处理未被软删除的课程 -4. **错误处理**: 完善的异常处理机制 - -## 注意事项 - -1. **备份数据**: 建议执行前备份`calendars`表数据 -2. **权限检查**: 确保数据库连接正常,有足够的读写权限 -3. **课程匹配**: 相似度匹配可能不是100%准确,建议执行后检查结果 -4. **重复执行**: 命令可以安全地重复执行,已存在的记录会被跳过 - -## 错误处理 - -命令包含完善的错误处理机制: -- 数据库连接错误处理 -- 事务回滚保护 -- 详细的错误日志输出 -- 匹配失败统计 - -## 数据库表要求 - -### courses表 -- `id`: 主键 -- `name`: 课程名称 -- `start_date`: 开始日期 -- `end_date`: 结束日期 -- `content`: 课程内容 -- `url`: 课程链接 -- `deleted_at`: 软删除时间戳 - -### calendars表 -- `type`: 类型(1=课程,2=课堂,3=事件) -- `course_id`: 关联的课程ID -- `date`: 日期 -- `title`: 标题 -- `content`: 内容 -- `start_time`: 开始时间 -- `end_time`: 结束时间 -- `url`: 链接 From f3312053220e63aff957063b25065d5913e0e231 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 17:41:50 +0800 Subject: [PATCH 31/42] update --- app/Http/Controllers/Mobile/SupplyDemandController.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Http/Controllers/Mobile/SupplyDemandController.php b/app/Http/Controllers/Mobile/SupplyDemandController.php index 9e398f3..9d6b772 100755 --- a/app/Http/Controllers/Mobile/SupplyDemandController.php +++ b/app/Http/Controllers/Mobile/SupplyDemandController.php @@ -245,6 +245,10 @@ class SupplyDemandController extends CommonController $query->where('user_id', $all['to_user_id'])->where('to_user_id', $this->getUserId()); })->first(); if (empty($dialogue)) { + // 不能给自己发信息 + if ($all['to_user_id'] == $this->getUserId()) { + return $this->error('不能给自己发信息'); + } // 创建一条会话 $dialogue = Dialogue::create([ 'user_id' => $this->getUserId(), From 92b96aaf503f5abd4d427f8b78a051d0ab67e6f0 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 17:43:44 +0800 Subject: [PATCH 32/42] update --- app/Http/Controllers/Mobile/CourseController.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Mobile/CourseController.php b/app/Http/Controllers/Mobile/CourseController.php index bfa5fec..aa8eb28 100755 --- a/app/Http/Controllers/Mobile/CourseController.php +++ b/app/Http/Controllers/Mobile/CourseController.php @@ -839,6 +839,7 @@ class CourseController extends CommonController * path="/api/mobile/course/calendars", * tags={"小程序-课程"}, * summary="日历", + * @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=false, description="类型"), * @OA\Parameter(name="month", in="query", @OA\Schema(type="string"), required=false, description="月份,例如:2025-01"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( @@ -862,8 +863,13 @@ class CourseController extends CommonController // $startDate = $all['month'] . '-01'; // $endDate = date('Y-m-t', strtotime($startDate)); $list = Calendar::with('course', 'courseContent') + ->where(function ($query) use ($all) { + if (isset($all['type'])) { + $query->where('type', $all['type']); + } + }) ->orderBy('start_time', 'asc') - ->whereDate('start_time', '<=', $all['month']) + ->where('start_time', 'like', '%' . $all['month'] . '%') ->get(); // $range = getDates($startDate, $endDate); From 7240c1ece1c27d3af6e43b5cfbf997d8815ca578 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 17:59:53 +0800 Subject: [PATCH 33/42] update --- app/Http/Controllers/Admin/UserController.php | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 6b02290..e921fa7 100755 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -2,12 +2,14 @@ namespace App\Http\Controllers\Admin; +use App\Exports\BaseExport; use App\Exports\CommonExport; use App\Helpers\ResponseCode; use App\Helpers\StarterResponseCode; use App\Models\Course; use App\Models\CourseAppointmentTotal; use App\Models\CourseSign; +use App\Models\CustomForm; use App\Models\CustomFormField; use App\Models\User; use Illuminate\Support\Carbon; @@ -40,7 +42,8 @@ class UserController extends BaseController * @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"), * @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"), - * @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"), + * @OA\Parameter(name="has_course", in="query", @OA\Schema(type="string"), required=false, description="是否有课程0否1是"), + * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", @@ -50,7 +53,87 @@ class UserController extends BaseController */ public function index() { - return parent::index(); + $all = request()->all(); + $list = $this->model->with(underlineToHump($all['show_relation'] ?? [])) + ->with(['courseSigns' => function ($query) use ($all) { + $query->where('status', 1)->with('course.teacher', 'course.typeDetail'); + }])->where(function ($query) use ($all) { + if (isset($all['has_course']) && $all['has_course'] == 1) { + $query->whereHas('courseSigns', function ($q) { + $q->where('status', 1); + }); + } + if (isset($all['filter']) && !empty($all['filter'])) { + foreach ($all['filter'] as $condition) { + $key = $condition['key'] ?? null; + $op = $condition['op'] ?? null; + $value = $condition['value'] ?? null; + if (!isset($key) || !isset($op) || !isset($value)) { + continue; + } + // 等于 + if ($op == 'eq') { + $query->where($key, $value); + } + // 不等于 + if ($op == 'neq') { + $query->where($key, '!=', $value); + } + // 大于 + if ($op == 'gt') { + $query->where($key, '>', $value); + } + // 大于等于 + if ($op == 'egt') { + $query->where($key, '>=', $value); + } + // 小于 + if ($op == 'lt') { + $query->where($key, '<', $value); + } + // 小于等于 + if ($op == 'elt') { + $query->where($key, '<=', $value); + } + // 模糊搜索 + if ($op == 'like') { + $query->where($key, 'like', '%' . $value . '%'); + } + // 否定模糊搜索 + if ($op == 'notlike') { + $query->where($key, 'not like', '%' . $value . '%'); + } + // null搜索 + if ($op == 'null') { + $query->whereNull($key); + } + // notnull搜索 + if ($op == 'notnull') { + $query->whereNotNull($key); + } + // 范围搜索 + if ($op == 'range') { + list($from, $to) = explode(',', $value); + if (empty($from) || empty($to)) { + continue; + } + $query->whereBetween($key, [$from, $to]); + } + } + } + })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); + if (isset($all['is_export']) && !empty($all['is_export'])) { + $list = $list->get()->toArray(); + $export_fields = $all['export_fields'] ?? []; + // 导出文件名字 + $tableName = $this->model->getTable(); + $filename = (new CustomForm())->getTableComment($tableName); + return Excel::download(new BaseExport($export_fields, $list, $tableName), $filename . date('YmdHis') . '.xlsx'); + } else { + // 输出 + $list = $list->paginate($all['page_size'] ?? 20); + } + return $this->success($list); } /** From cea3470364258046b84432b39e96b35c68338f4c Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 18:03:51 +0800 Subject: [PATCH 34/42] update --- app/Http/Controllers/Admin/CalendarsController.php | 2 +- app/Http/Controllers/Mobile/CourseController.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Admin/CalendarsController.php b/app/Http/Controllers/Admin/CalendarsController.php index ac063bb..79b3d33 100644 --- a/app/Http/Controllers/Admin/CalendarsController.php +++ b/app/Http/Controllers/Admin/CalendarsController.php @@ -54,7 +54,7 @@ class CalendarsController extends BaseController if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } - $list = Calendar::with('course', 'courseContent')->where('date', 'like', $all['month'] . '%')->orderBy('date')->get(); + $list = Calendar::with('course', 'courseContent')->where('start_time', 'like', $all['month'] . '%')->orderBy('date')->get(); return $this->success($list); } diff --git a/app/Http/Controllers/Mobile/CourseController.php b/app/Http/Controllers/Mobile/CourseController.php index aa8eb28..27c3ef4 100755 --- a/app/Http/Controllers/Mobile/CourseController.php +++ b/app/Http/Controllers/Mobile/CourseController.php @@ -867,9 +867,8 @@ class CourseController extends CommonController if (isset($all['type'])) { $query->where('type', $all['type']); } - }) + })->where('start_time', 'like', '%' . $all['month'] . '%') ->orderBy('start_time', 'asc') - ->where('start_time', 'like', '%' . $all['month'] . '%') ->get(); // $range = getDates($startDate, $endDate); From bf4b96ba016fd22941fb285aa9cc0b5ccd99fb8b Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 18:44:25 +0800 Subject: [PATCH 35/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php index 1336ed4..0b01239 100644 --- a/app/Console/Commands/UpdateBookIsbnData.php +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -53,6 +53,7 @@ class UpdateBookIsbnData extends Command $query->where('id', $book_id); } })->where('isbn', '!=', '') + ->where('id','>',2843) ->where(function ($query) { // 如果没有封面或者缺少基本信息字段,都需要处理 $query->whereNull('cover_id') From 4a21198c0937afa31386eb8b7c558db7e358d9e1 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 19:33:04 +0800 Subject: [PATCH 36/42] update --- app/Console/Commands/UpdateBookIsbnData.php | 1 - app/Http/Controllers/Admin/UserController.php | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/UpdateBookIsbnData.php b/app/Console/Commands/UpdateBookIsbnData.php index 0b01239..1336ed4 100644 --- a/app/Console/Commands/UpdateBookIsbnData.php +++ b/app/Console/Commands/UpdateBookIsbnData.php @@ -53,7 +53,6 @@ class UpdateBookIsbnData extends Command $query->where('id', $book_id); } })->where('isbn', '!=', '') - ->where('id','>',2843) ->where(function ($query) { // 如果没有封面或者缺少基本信息字段,都需要处理 $query->whereNull('cover_id') diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index e921fa7..cce36f9 100755 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -43,7 +43,7 @@ class UserController extends BaseController * @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"), * @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"), * @OA\Parameter(name="has_course", in="query", @OA\Schema(type="string"), required=false, description="是否有课程0否1是"), - * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), + * @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=true, description="关键词"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", @@ -58,6 +58,11 @@ class UserController extends BaseController ->with(['courseSigns' => function ($query) use ($all) { $query->where('status', 1)->with('course.teacher', 'course.typeDetail'); }])->where(function ($query) use ($all) { + if (isset($all['keyword'])) { + $query->whereHas('courses', function ($q) use ($all) { + $q->where('name', 'like', '%' . $all['keyword'] . '%'); + })->orWhere('name', 'like', '%' . $all['keyword'] . '%'); + } if (isset($all['has_course']) && $all['has_course'] == 1) { $query->whereHas('courseSigns', function ($q) { $q->where('status', 1); From f44be9402da71135590b73a70a8f3bde8b21a8f0 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 19:51:07 +0800 Subject: [PATCH 37/42] update --- app/Models/CourseContent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/CourseContent.php b/app/Models/CourseContent.php index 100fe11..3a8b207 100755 --- a/app/Models/CourseContent.php +++ b/app/Models/CourseContent.php @@ -77,7 +77,7 @@ class CourseContent extends SoftDeletesModel 'secret' => \config('app.applet_secret') ]; $app = Factory::miniProgram($config); - $tmp = $app->app_code->get('/packages/surveyFill/index?course_content_id' . $courseContentId, [ + $tmp = $app->app_code->get('/packages/sign/index?course_content_id' . $courseContentId, [ 'env_version' => "release" // 正式版 // 'env_version' => "trial" // 体验版 ]); From 85805fd13a16ab6a02f5e0a982b2072df7697982 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 19:55:57 +0800 Subject: [PATCH 38/42] update --- app/Http/Controllers/Mobile/CourseController.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/Mobile/CourseController.php b/app/Http/Controllers/Mobile/CourseController.php index 27c3ef4..38369a8 100755 --- a/app/Http/Controllers/Mobile/CourseController.php +++ b/app/Http/Controllers/Mobile/CourseController.php @@ -544,9 +544,7 @@ class CourseController extends CommonController * @OA\Get( * path="/api/mobile/course/content-check-list", * tags={"小程序-课程"}, - * summary="获取签到记录和距离", - * @OA\Parameter(name="longitude", in="query", @OA\Schema(type="string"), required=false, description="longitude"), - * @OA\Parameter(name="latitude", in="query", @OA\Schema(type="string"), required=false, description="latitude"), + * summary="获取签到记录", * @OA\Parameter(name="course_content_id", in="query", @OA\Schema(type="string"), required=false, description="课表id"), * @OA\Response( * response=200, @@ -558,13 +556,9 @@ class CourseController extends CommonController { $all = \request()->all(); $messages = [ - 'longitude.required' => '经度必填', - 'latitude.required' => '纬度必填', 'course_content_id.required' => '课程id必填', ]; $validator = Validator::make($all, [ - 'longitude' => 'required', - 'latitude' => 'required', 'course_content_id' => 'required' ], $messages); if ($validator->fails()) { @@ -572,13 +566,11 @@ class CourseController extends CommonController } // 获取打卡范围,千米 $content_check_range = Config::getValueByKey('content_check_range'); - $courseContent = CourseContent::find($all['course_content_id']); - $distance = getDistance($courseContent->longitude, $courseContent->latitude, $all['longitude'], $all['latitude']); $list = CourseContentCheck::where('course_content_id', $all['course_content_id']) ->where('user_id', $this->getUserId()) ->orderBy('created_at', 'desc') ->get(); - return $this->success(compact('list', 'content_check_range', 'distance')); + return $this->success(compact('list', 'content_check_range')); } /** From 0b6bcdba064294e9abb5ce23c61acd4cfc769a77 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 20:24:39 +0800 Subject: [PATCH 39/42] update --- app/Http/Controllers/Mobile/CourseController.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Mobile/CourseController.php b/app/Http/Controllers/Mobile/CourseController.php index 38369a8..65ab4ce 100755 --- a/app/Http/Controllers/Mobile/CourseController.php +++ b/app/Http/Controllers/Mobile/CourseController.php @@ -484,10 +484,7 @@ class CourseController extends CommonController $content_check_range = Config::getValueByKey('content_check_range'); $courseContent = CourseContent::find($all['course_content_id']); $distance = getDistance($courseContent->longitude, $courseContent->latitude, $all['longitude'], $all['latitude']); - if ($distance > $content_check_range) { - return $this->fail([ResponseCode::ERROR_BUSINESS, '超出打卡范围']); - } - return $this->success('成功'); + return $this->success(compact('distance', 'content_check_range')); } /** @@ -564,13 +561,12 @@ class CourseController extends CommonController if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } - // 获取打卡范围,千米 - $content_check_range = Config::getValueByKey('content_check_range'); + $list = CourseContentCheck::where('course_content_id', $all['course_content_id']) ->where('user_id', $this->getUserId()) ->orderBy('created_at', 'desc') ->get(); - return $this->success(compact('list', 'content_check_range')); + return $this->success(compact('list')); } /** From 72ccf05e8c79028d77c562959061196223f3109b Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 20:33:19 +0800 Subject: [PATCH 40/42] update --- app/Models/Config.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/Models/Config.php b/app/Models/Config.php index 504c143..bf9bb40 100755 --- a/app/Models/Config.php +++ b/app/Models/Config.php @@ -14,9 +14,7 @@ class Config extends SoftDeletesModel */ public static function getValueByKey($key) { - $config = Cache::remember('config_array', 300, function () { - return self::pluck('value', 'key')->toArray(); - }); + $config = self::pluck('value', 'key')->toArray(); if (isset($config[$key])) { return $config[$key]; } From 77df79dfe85e66f2c8c344d92a680201707f6acd Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 20:53:42 +0800 Subject: [PATCH 41/42] update --- app/Http/Controllers/Mobile/CourseController.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/Http/Controllers/Mobile/CourseController.php b/app/Http/Controllers/Mobile/CourseController.php index 65ab4ce..baa9074 100755 --- a/app/Http/Controllers/Mobile/CourseController.php +++ b/app/Http/Controllers/Mobile/CourseController.php @@ -528,6 +528,13 @@ class CourseController extends CommonController if (date('Y-m-d') != $courseContent->date) { return $this->fail([ResponseCode::ERROR_BUSINESS, '不在签到时间']); } + // 不能重复签到 + $courseContentCheck = CourseContentCheck::where('course_content_id', $all['course_content_id']) + ->where('user_id', $this->getUserId()) + ->first(); + if ($courseContentCheck) { + return $this->fail([ResponseCode::ERROR_BUSINESS, '不能重复签到']); + } CourseContentCheck::create([ 'course_content_id' => $all['course_content_id'], 'user_id' => $this->getUserId(), From 487cc56655bec23ccc641001225fb2afc3d3af1d Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Sat, 9 Aug 2025 20:54:39 +0800 Subject: [PATCH 42/42] update --- app/Models/CourseContent.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Models/CourseContent.php b/app/Models/CourseContent.php index 3a8b207..95b0141 100755 --- a/app/Models/CourseContent.php +++ b/app/Models/CourseContent.php @@ -78,8 +78,8 @@ class CourseContent extends SoftDeletesModel ]; $app = Factory::miniProgram($config); $tmp = $app->app_code->get('/packages/sign/index?course_content_id' . $courseContentId, [ - 'env_version' => "release" // 正式版 - // 'env_version' => "trial" // 体验版 + // 'env_version' => "release" // 正式版 + 'env_version' => "trial" // 体验版 ]); $dir = dirname($path); $fileSys->ensureDirectoryExists($dir, 0755, true);