From 6f6a5e2ca16b9cecc07e86a7f7c11af335ae1f65 Mon Sep 17 00:00:00 2001 From: zcx Date: Mon, 27 May 2024 13:06:56 +0800 Subject: [PATCH] first commit --- dms | 1 + views/.DS_Store | Bin 0 -> 6148 bytes views/__init__.py | 2 + views/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 239 bytes views/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 208 bytes views/admin/__init__.py | 14 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 730 bytes .../admin/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 663 bytes views/admin/__pycache__/ad.cpython-312.pyc | Bin 0 -> 3625 bytes views/admin/__pycache__/ad.cpython-38.pyc | Bin 0 -> 2059 bytes .../admin/__pycache__/banner.cpython-312.pyc | Bin 0 -> 3654 bytes views/admin/__pycache__/banner.cpython-38.pyc | Bin 0 -> 2079 bytes .../classification.cpython-312.pyc | Bin 0 -> 4097 bytes .../__pycache__/classification.cpython-38.pyc | Bin 0 -> 2365 bytes .../admin/__pycache__/comment.cpython-312.pyc | Bin 0 -> 3720 bytes .../admin/__pycache__/comment.cpython-38.pyc | Bin 0 -> 2110 bytes .../__pycache__/errorLog.cpython-312.pyc | Bin 0 -> 965 bytes .../admin/__pycache__/errorLog.cpython-38.pyc | Bin 0 -> 687 bytes .../__pycache__/loginLog.cpython-312.pyc | Bin 0 -> 3388 bytes .../admin/__pycache__/loginLog.cpython-38.pyc | Bin 0 -> 1974 bytes .../admin/__pycache__/notice.cpython-312.pyc | Bin 0 -> 3654 bytes views/admin/__pycache__/notice.cpython-38.pyc | Bin 0 -> 2079 bytes views/admin/__pycache__/opLog.cpython-312.pyc | Bin 0 -> 968 bytes views/admin/__pycache__/opLog.cpython-38.pyc | Bin 0 -> 687 bytes views/admin/__pycache__/order.cpython-312.pyc | Bin 0 -> 6912 bytes views/admin/__pycache__/order.cpython-38.pyc | Bin 0 -> 3665 bytes .../__pycache__/overview.cpython-312.pyc | Bin 0 -> 7115 bytes .../admin/__pycache__/overview.cpython-38.pyc | Bin 0 -> 3624 bytes .../admin/__pycache__/record.cpython-312.pyc | Bin 0 -> 2950 bytes views/admin/__pycache__/record.cpython-38.pyc | Bin 0 -> 1685 bytes views/admin/__pycache__/tag.cpython-312.pyc | Bin 0 -> 4015 bytes views/admin/__pycache__/tag.cpython-38.pyc | Bin 0 -> 2248 bytes views/admin/__pycache__/thing.cpython-312.pyc | Bin 0 -> 5611 bytes views/admin/__pycache__/thing.cpython-38.pyc | Bin 0 -> 2913 bytes views/admin/__pycache__/user.cpython-312.pyc | Bin 0 -> 9098 bytes views/admin/__pycache__/user.cpython-38.pyc | Bin 0 -> 4582 bytes views/admin/ad.py | 68 ++++++ views/admin/banner.py | 68 ++++++ views/admin/classification.py | 74 ++++++ views/admin/comment.py | 69 ++++++ views/admin/errorLog.py | 14 ++ views/admin/loginLog.py | 60 +++++ views/admin/notice.py | 68 ++++++ views/admin/opLog.py | 14 ++ views/admin/order.py | 147 ++++++++++++ views/admin/overview.py | 140 ++++++++++++ views/admin/record.py | 53 +++++ views/admin/tag.py | 75 +++++++ views/admin/thing.py | 104 +++++++++ views/admin/user.py | 176 +++++++++++++++ views/index/__init__.py | 8 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 496 bytes .../index/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 447 bytes .../index/__pycache__/address.cpython-312.pyc | Bin 0 -> 4464 bytes .../index/__pycache__/address.cpython-38.pyc | Bin 0 -> 2392 bytes .../classification.cpython-312.pyc | Bin 0 -> 1087 bytes .../__pycache__/classification.cpython-38.pyc | Bin 0 -> 807 bytes .../index/__pycache__/comment.cpython-312.pyc | Bin 0 -> 4518 bytes .../index/__pycache__/comment.cpython-38.pyc | Bin 0 -> 2580 bytes .../index/__pycache__/notice.cpython-312.pyc | Bin 0 -> 958 bytes views/index/__pycache__/notice.cpython-38.pyc | Bin 0 -> 682 bytes views/index/__pycache__/order.cpython-312.pyc | Bin 0 -> 3856 bytes views/index/__pycache__/order.cpython-38.pyc | Bin 0 -> 2176 bytes views/index/__pycache__/tag.cpython-312.pyc | Bin 0 -> 944 bytes views/index/__pycache__/tag.cpython-38.pyc | Bin 0 -> 670 bytes views/index/__pycache__/thing.cpython-312.pyc | Bin 0 -> 11264 bytes views/index/__pycache__/thing.cpython-38.pyc | Bin 0 -> 5309 bytes views/index/__pycache__/user.cpython-312.pyc | Bin 0 -> 7745 bytes views/index/__pycache__/user.cpython-38.pyc | Bin 0 -> 3928 bytes views/index/address.py | 87 +++++++ views/index/classification.py | 21 ++ views/index/comment.py | 87 +++++++ views/index/notice.py | 15 ++ views/index/order.py | 85 +++++++ views/index/tag.py | 15 ++ views/index/thing.py | 212 ++++++++++++++++++ views/index/user.py | 162 +++++++++++++ 77 files changed, 1839 insertions(+) create mode 160000 dms create mode 100644 views/.DS_Store create mode 100644 views/__init__.py create mode 100644 views/__pycache__/__init__.cpython-312.pyc create mode 100644 views/__pycache__/__init__.cpython-38.pyc create mode 100644 views/admin/__init__.py create mode 100644 views/admin/__pycache__/__init__.cpython-312.pyc create mode 100644 views/admin/__pycache__/__init__.cpython-38.pyc create mode 100644 views/admin/__pycache__/ad.cpython-312.pyc create mode 100644 views/admin/__pycache__/ad.cpython-38.pyc create mode 100644 views/admin/__pycache__/banner.cpython-312.pyc create mode 100644 views/admin/__pycache__/banner.cpython-38.pyc create mode 100644 views/admin/__pycache__/classification.cpython-312.pyc create mode 100644 views/admin/__pycache__/classification.cpython-38.pyc create mode 100644 views/admin/__pycache__/comment.cpython-312.pyc create mode 100644 views/admin/__pycache__/comment.cpython-38.pyc create mode 100644 views/admin/__pycache__/errorLog.cpython-312.pyc create mode 100644 views/admin/__pycache__/errorLog.cpython-38.pyc create mode 100644 views/admin/__pycache__/loginLog.cpython-312.pyc create mode 100644 views/admin/__pycache__/loginLog.cpython-38.pyc create mode 100644 views/admin/__pycache__/notice.cpython-312.pyc create mode 100644 views/admin/__pycache__/notice.cpython-38.pyc create mode 100644 views/admin/__pycache__/opLog.cpython-312.pyc create mode 100644 views/admin/__pycache__/opLog.cpython-38.pyc create mode 100644 views/admin/__pycache__/order.cpython-312.pyc create mode 100644 views/admin/__pycache__/order.cpython-38.pyc create mode 100644 views/admin/__pycache__/overview.cpython-312.pyc create mode 100644 views/admin/__pycache__/overview.cpython-38.pyc create mode 100644 views/admin/__pycache__/record.cpython-312.pyc create mode 100644 views/admin/__pycache__/record.cpython-38.pyc create mode 100644 views/admin/__pycache__/tag.cpython-312.pyc create mode 100644 views/admin/__pycache__/tag.cpython-38.pyc create mode 100644 views/admin/__pycache__/thing.cpython-312.pyc create mode 100644 views/admin/__pycache__/thing.cpython-38.pyc create mode 100644 views/admin/__pycache__/user.cpython-312.pyc create mode 100644 views/admin/__pycache__/user.cpython-38.pyc create mode 100644 views/admin/ad.py create mode 100644 views/admin/banner.py create mode 100644 views/admin/classification.py create mode 100644 views/admin/comment.py create mode 100644 views/admin/errorLog.py create mode 100644 views/admin/loginLog.py create mode 100644 views/admin/notice.py create mode 100644 views/admin/opLog.py create mode 100644 views/admin/order.py create mode 100644 views/admin/overview.py create mode 100644 views/admin/record.py create mode 100644 views/admin/tag.py create mode 100644 views/admin/thing.py create mode 100644 views/admin/user.py create mode 100644 views/index/__init__.py create mode 100644 views/index/__pycache__/__init__.cpython-312.pyc create mode 100644 views/index/__pycache__/__init__.cpython-38.pyc create mode 100644 views/index/__pycache__/address.cpython-312.pyc create mode 100644 views/index/__pycache__/address.cpython-38.pyc create mode 100644 views/index/__pycache__/classification.cpython-312.pyc create mode 100644 views/index/__pycache__/classification.cpython-38.pyc create mode 100644 views/index/__pycache__/comment.cpython-312.pyc create mode 100644 views/index/__pycache__/comment.cpython-38.pyc create mode 100644 views/index/__pycache__/notice.cpython-312.pyc create mode 100644 views/index/__pycache__/notice.cpython-38.pyc create mode 100644 views/index/__pycache__/order.cpython-312.pyc create mode 100644 views/index/__pycache__/order.cpython-38.pyc create mode 100644 views/index/__pycache__/tag.cpython-312.pyc create mode 100644 views/index/__pycache__/tag.cpython-38.pyc create mode 100644 views/index/__pycache__/thing.cpython-312.pyc create mode 100644 views/index/__pycache__/thing.cpython-38.pyc create mode 100644 views/index/__pycache__/user.cpython-312.pyc create mode 100644 views/index/__pycache__/user.cpython-38.pyc create mode 100644 views/index/address.py create mode 100644 views/index/classification.py create mode 100644 views/index/comment.py create mode 100644 views/index/notice.py create mode 100644 views/index/order.py create mode 100644 views/index/tag.py create mode 100644 views/index/thing.py create mode 100644 views/index/user.py diff --git a/dms b/dms new file mode 160000 index 0000000..7d3f991 --- /dev/null +++ b/dms @@ -0,0 +1 @@ +Subproject commit 7d3f991a052db79492ad91f51cb582665e2e42d2 diff --git a/views/.DS_Store b/views/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b6cec58a03b766b1341d4367993c031fe8dd3b1f GIT binary patch literal 6148 zcmeH~&ui2`6vyARyP7np5dj=RrQ`w}ajjYCR0{Zm9juEK5s22p=c$u;X4@%S0X|BJRoH zB#Lp$)2&2A*|41rMAVnp@zsF5QO8{zjh2^J8+_%~>bSv2tyZ(aZ?4=Pk8SJn^`$%a zws&5=9=#dwzgJWlESdzvEuj551K{d3Q4w8)>{3iwC{?K^`kQr$D4i*}CSXU-7{K@O3CkO`_B~Ny)aZ z+_?Mb`QYulgAX4+eg5+8yNrSo)J4@U>mTS+A@%mg&2j(d?wIN^#OcIz^O_%onjlZA&CxcAO5HJL0iU6yv`|E8? zN$;&w$g`kf(fqaDNaE8F^GcvnZ)w5OqNTQ_B}*Mk%a&FwbxX>fLF>B|Hz0{>7UeB?4PL1$6R*I; zC3rw`u;u&7_qWe?zNajk5FGEfmAFU=`Rq1-2l~i0F6Yq*B9fXs{xS(n14n@yft!I_ zf!l%Oz@5NJ;BMevV1`T|$ZYh5FOylaPR{RV`}DYJxiR@l$v2mC(I}n!h0+y0i-of0 z&Z!qwa<4$s!}x^f6+MdGOD8Qojr}Dwjntl=#FCXISV5<;0xM~|bceJWDy8qB8Y&CJ zVHN}Rg6VDyyd|Vn_J@_?yoO>=MCab|4q zok>HG+wDp#t&POGh@XTX33pXQt7gR_kSKrJ6-fKCFA27k?kJU3+B&pv2`v)p3!FRl z#Ex+&ec?zxzW1JUf9BlpJNNu26bc}a`9J>t&r zpV7HW6U9QVwWVf-zCfi~p9E^&E3?8koYmT7R^*1Wf=yf+mrw3^NYS=Yw~TGOF1$ZtEu92eFV$Ejh{f(&Ir;i*LVk`Mtj_ zW>1!1c>ApANTVr29nrK7I}*`sO;sGfN$n#k!uXdta_V4$j@p(ZYKGw`DMl!ZADm?T z)0m&Db)Zzyks1BNIJInWB$g9^d#Hxr;-`#8qt_qVvtxgH5|&QJts|-Q-KJ*Qlrw4&e>wiA+*?QBA?79i{VZ4;oiA$@0oBhyge%}blhIpd}dFnwn*qoJ7uyQ<6#&(i@$4AYoq~f1H{GueM0Ng{DD|gSTZXUjV|}|3)Z%Ba ze0}!7r&nJo_qO zwvYgLH`}kZmfdWA+pd5wzwHL`zGKzOm;~z~ycyNSi08ou*#e2IVZL0OKPo%}S#|x50e2iK`w^j-Zn(--GZ+DLwWr4`=zkk1xM}>eBfa%YUCPzjcO1xpOTI zzxm5d2mh@i4XBtjyYZH@GK7t>KjY&~uOuD+!qglHJbL9o)m0 zW_r?g{FJd2vs9_VonCGdG*TfE#~Wm4k4EEZcm*iygHgVY^)FCs(`ZSOd^;|LZplBJ zdo~}>#i#cb28yA(vcf_rl8@zL`2)EF(=2W~KH`nR-7@-8 zj_%$jeyL*6&6zv=3ozHi>sl!um<^}k0+qlDpA$_`n^@s(#h>epP-Aw2e|dv6<)K1a zYG@xpz?Ry+9Bd78Q)~(Rh%KT{tn2vKKo-AF;&DC6pwg-%M>$)#^7`otIn+P{4VVhP zj?YRPdOaKbhjasg>-Y&ZC^WW#mnv2e-_K{ruxVUl%&SM-cZ1!}H|A`zCR_Q7#>b%lF zr}USU0iZyzv-W~~cTK(_c6s#Q80y}I(HA(nYm4~BW(;~*ZF9O9lw0vbOf%_3ijDOV zI+|jd4NPae{$QNhPM2Fm_3>KURkebf@lwPIRqRK!BrzaO@RGy{R>n-I3=OMN2Hsj3 zN>gU)mIdW{U#;ohkJDE1sH^)bDT$Y8?yKzP6gSjok^6MI7jRt}gnh;hx|8h$PmX)* zJSbo;#$Tg{%V_W-y7MBs^&;AS5p7%cBO#EzKigZx?aP9MpTJi|B&=U@o6BKt{B3q? z5wHI*?wswqXLe(M5#PHkwBX-xzX7gpS(2c;ym2kxw$;ASUEaEuZ)?5pvIJfC%YFc% C9s9l6>0f6MLM~++r$_9Y-XL5 zRM)26+!9je~uPB5iSYoBD!BXDfjK(~%Q>Wn=-A*d0+i;EUB-PYw zct)=zwbXC;Mt75uG-w3Ol1x)KJ<-?9kW(Av59-PLax0ikDJS}JgFz6rD8#LintXOan@z}>2VQZ(A z390Q=&1*+QMHG74O=Yo=32-r5SF_`7*(#K_qa@K@20}vf_zGZxSU`J+Q52!As~|sJ zlB#Ifkx<&l^AC@`VZoCaa(Dls19LfK=4*5L3NF!Us)a0{!_Z|3bLmQy=W|4fnu`c{ zlvDYN_L5i?O{8lCzoKYei~DSx1q_}-T{}nKpM4Nkj^_KYzK4SXfn8;=vtWV=F6=cv zYZV;9CO{F~F6%k#797NPW!+*H#u2~_{RUt&&nxGJwV6!<^Ul*K27iA2&!wCF8|V68 z{xvl{ z!Pg*7AZssH&1K9bp&b=1%aFqp6t$BCL0pPS3U$jQAituymhG{C2h78JoWl!fc_0(1 zwrL@gi5F0L9Au~VAY_=8!V#5qjydVHD{UL|(nS#YM^Fd87Swh1`b z`UJD|W2>lk33yLPKF9kyi>NBtl_Xy9B z*o{K-SZw}_7Zqc^cxMc4{VTuUzPf(v##;a9@B0^if@djss|?OxAAI}E!z2uhbx1;e z8wpfe+Mbt%sR|gUVQ?suY9=cVe})NK76d^J&yjeZA}Tq=okF`3AOjUTC0~2V#Ut@} z;+AqOL-``cC^}wA9A~3!0&{+Xj}9sHIfUqafJAC1_esog@K_S}-6N6O3S~Z$iS!kf zw%bN>h|HcxWDE(dv};J{@&6^%wCy1={v*WLu~2u}KIFxXMY9=q;3eGH77zV1z0Dsk zl{|$0Lx{u67^^EPPvY&syC>qLz<%lqnMhP#!KlzK!F`oxRB_Q}1n^K*!0YII10OYk z;vTXA^Vy`q*7#?_9eNjFBWs?3D3vEOSez2Fl|fV>hd{jr2xz^_G^{E5dl<3x3jwMo zT`&C$QAZ@0094D3ptPmfa}!lI*xjWmmypIv;SXqPOEqxl9c9E;M^$CAQTH>IY%;-Y oe%pafLomI-dlT1NO5|I#ceMw_ICg^JjeWtdQdbB9BX^Sg5B)6r_W%F@ literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/banner.cpython-312.pyc b/views/admin/__pycache__/banner.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a2b9b641e1b647077796ab4351e35b7ec2990ab GIT binary patch literal 3654 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 literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/classification.cpython-38.pyc b/views/admin/__pycache__/classification.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4297ea66841cd53411db12ab8b7ed845a0986723 GIT binary patch literal 2365 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 literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/comment.cpython-38.pyc b/views/admin/__pycache__/comment.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..068fed22d00a3d6738086ae642f56340aa402d5e GIT binary patch literal 2110 zcmZ`)TW{P{5cWCtdcDr>=AsfP*Mg8>p+w>hL4{hi72+jSq%E*oY31%YO}w$!W{#7R zDt!t<6;edS9ko(-Q7e%LRH{}`3jC4tN_RhRDXAJvPahC**gKjm z%H9E-b9V-M#ts~L_kF3-q^Bef%LkJ<#w}1C57i+VCuZd_B>_#7g?COu7)0S|3EF<= z@X-#VP>RdOcL|?^_^ACTR;?}~yvSi+#=5+33qD|dXJGY9!XB_QEOS?xa71aHpW#_q zxT3tuyPojY?K$KEzqB$7NTQ`n*+STxKV5sRlgHT3!dM=~u$(yPtpEkFR7EkmczN^6 zkE65ahM!;Du(i`kgw%Gd=Cvb&ENE1;8_R4V5#Z9c<>W+Hb~2^wN=B%(K}JC)g|>qz z(p~~WLi@xDcsLp8%U~Qu!`5YxA1_IjX|D)KX&-SaklC={37mK5twV3NQb^1Zt#k#? z?X}fHlD2T_vV>N=5~OL1_*1QbSZWo!&7>>Zi$ayPk>D}hN>KzB_t`YBGI$bo?HqY; z?tb_=n(x7X90wT^u*P6l#sm{w*z0`G$~cl@3uhhSUo~XFetee(7PD|(NgyTYFB1hs zPq)0rjE552?0}?f5#YD!8%KYB{m-SF!yD&@U;H-uu0Oi=&FHK3TYp{H;7~(1)KP3O z1KT!B!?Wjyf85Mj0;0`ums^LIu5Mnx-0+}G%MIoReF9#4p=vK<_6hB%U|H%?3SlqP zt^`OxH8?y*iykLI!R2B%t#msek=b3Ss|ggA?XfCi>ES)WeGV_8?Y?BDMnNZ=Wd0JB zN1=Io528tljY&Mm%u~+SWWnjT)`1T7eNIZ)|^H6O4ix-v#PZw_! zYQrnPZ(beTy0Jd|`TOC8pWr!~yj?NpuaCa{ehd;rL&1;3ug*_ymN6~O{VqPM{G>J!2w3K3vN+LoLdpSj%)!7uAU{kzakOi-z z?>?%i@7$v*#la(~+IyEO>O7SCNEwopmAY;hDIm)F9zkBvR_a!ewiEwLo9Xlg5&lC& z*r8B&*k0tp4Mn>h_TXgz93GrE@h7lNLMurR5Fo7LPFV>^yi-g}?QO{s)9 zR0{uDGux_xLr>;2w)?8elZ)D)saKN;Ciop6Yzp7hytfa}TZ-h{6ua7kVgf6^xUv3y MkE*{~H*$*Pf51c#CjbBd literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/errorLog.cpython-312.pyc b/views/admin/__pycache__/errorLog.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfa14e2735c4869de5c5eca220e58ab7c759121a GIT binary patch literal 965 zcmZuvO=uHA6rS1LWH)JJv2FyVXoX4}p+P8KL`A_OYJcp{DFnhcGfg+$$*wcomMv{n z5DcEY)mw`oC@JW%p1gVSVr?NXv>-@}y|v`llQT)yC^(1rzV{yUz4yMEuZct)h*Nzs zHhl;I_$h<%s7+8C7hn}2fS>~i%s?oy;wVJTsCBG58i`~gb*wp2qGxmn6o4U$6ktX0 z%7dcML8Spf#t8J3aVVn{nFYF!Ol~H=ly>IQ#PgOb*)J-F-5A_j=X~ zM1xX}&A47av6zqP|5D=eyr_`C^1Q5kc9yjeu}j&oLD~zr;n>X2iH|{(qJdPKjS2G< z{LoLmSb4VcI{96{uxoZz&7Li@r)u_XnSI;lm8vozKKMNPX>_M!=$kQgqyyt(O^||-RE(daV#(YzwFq8t>1-O|yh|q3h{J>MwyBlFBXK1A10CY6^2=+z{919DIv*iBNuF smKNqng%Iw8^gg(}2QKY_tH)8G#LL&pz1y(!Skd4xtf@db(|~op-$Z%tfdBvi literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/errorLog.cpython-38.pyc b/views/admin/__pycache__/errorLog.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c512c50f22f39ec36dd6b3e17b08f1ec9c0c2494 GIT binary patch literal 687 zcmYjOO=}cE5bclo+I1F8Joyv$;2u4MAd0RcNDwz(hJj(S-R{n&dwZ;&O_;Db#e)ce z{DUNd2T%T=zKX&81y5G*nwWwrUiVbLdavevuh%6QXTyoOriA?Thr7Y?@D$UG2G zifEcq>M>JH^Ng=BSAh<*aD@XE={SoikyL~edO}4c;!os+W{F5fq~EzlF4CtiDeI~@ zsN^Byd(Ym!ekW~h=2rSoLjVJB%mne~4IW9TN>v?6aQxM9cZ`B>!wU^DpJUoBEK4#& zx%&(rH+04>_$9dr1iPfiv6w#8+ViBM65!yn5$qq!waMXFE%%o^4 zEq75ypv!p+e&!;@a&`Xg_m8hvpU-}MIq!29jE#_vYddj)D4VjMxJb)pY6Jw>?P9Yx zljFuZUMl4h142Tv*Mip!UOf08fkZLLj|*v=tRw%ez`Cxzb^e{e1~&fLezBF;U{;)Y z-Qu8mVW+0fvGqVguG_M%bH7}hmqJ(b{Dy8&w=PkYZ3V!Z literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/loginLog.cpython-312.pyc b/views/admin/__pycache__/loginLog.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31bd7e40b0c52b08aaab3234ebc2272f53025046 GIT binary patch literal 3388 zcmbW3Z)_Ar6u@V8_ip$8^=P?LT9KYorDwD#L{x&tR{UR!So~lmxvbr#>~;6{oZV7u z3RYv{)x;G4w*E=11|khLKqRsLiwPh6;+NK5a=3xSM6SZORxlxa(KoZVcjx6$<0SWX zX5O25H#5KYW`2xBf(T0frCocEiwONn8(tBLl}lHkGKmzVU>zB_4;x$`hiRMBc|+(E zSe@5>hQH6x>VhsBQlG@?K0ROr`+}_Q*F#3QFN_g~RIG>t_!xG5DAKFwSkYZyglPj6 z+F*sYu38IiP8BMwLuKpIoY8+B6|OOA)kq{!cai?D1m{R{MoaG3)M00hJY?@v)3(+x z+nSk9_Up1`sa66zYdRG}OYb%Z)pRG=cov`ubw2s%Q>v9Q)0PTNsoNaT(jcH7)vO(= zVX~o5TPlIB22b6q5>3{%7ggf$4?noOzqns)t9&4N_+9z|#3UL;Dc1dWq2R%Ggve7i z=k=$&bM-pln}V~iF5cdy0@WG>C-0ry0c?jn{U}!WS>agG(*e$ocpAm0_(!=^o!2gZ zXT@W54N!W~2uesjgaY|u;5OYHNZOjA?uP9U3^_eQ=)6N=5KA8)xp4f`rR<@?>mSeX zj?ix^s>2)BfFmffEhi+$Z>aV@Qz3L&j%YrYQu}So;bmQSB$FsANj^71=(>oXid7&I zydx6z`61P^od7szr(-!mIFRBASoDv^ z7$b5fvxl-{?U5-VdprjnnGr|QHOo!{U8ETt(A~6lffz%-h;^?WeEHy1<4@xHv$1vg zSldFZEgx%Nh_x@qZpp{CEX1~)cziK-e>QNoapTdzoRDk0Hyb<~ZJEZ?2j?F9e&<&^ zbJ6a3se4&OQtKs{6gk3^JA1Fe(H!U}kzHa8h$>M-$GT;<6txHNC{9rdtBOYsX$Sp3 zkcE+5VoTu^9;|Em6Uu~C*aK0(PSL)Xk~4$ZL6$iwWIrr?^R>$fp)6jcOJfMRs>0!u z7fv0S;RpqjL_s8cE*6vsN7Ah1euzHB5iA+bk+PEDNFz0F0%1|_@ik0azHVk+u72y-V`s$ryx6iJw&cWhXQYOS=y)_IHP<+@^Px3U zozwT_LYwD>&7=h;s~!Afu%<~AxJLM=iopfLOGUvDzQv7$@GYf-6kT6csWpBS&+?`4 zuL$x{4uGj0;+{8tluy-HxqxN`Fno$`URCk*01OQeRuoAIz-+br1uK9l+Y3r)*6*#m z7i~ZlE0?@k%ilIg3xD$`D8BOee(o7aSi|TA{uwlk6X70*)0B&ULVK^i6Bdh4nLsUEUA$O z80>_1n5xxd+7G?}8N^LxEU8g?Nt}usKqLeg*_&y{8Y&pP^xPqvdH4=xAa|Y&PDI}NxEm5hpwv@h3S>;T`lNzOT6n| z{`7VXvUZ^Kut2HIZXU!WVwb{%1_$6>1h&@=tWt=8w_>T4*A&5#z3D4i za5j5+QC*5&YE>mg*{Ld{8~_Nbpyi*!2(T@$2g0OsJ%D}LFNLV86tORlhj&_ed=>V= z9>)0)O@K?^zVqARuM2aB3KL&0O-?U;@$S;wZ=C<`BL=*~Yl?Lh-wMIu*OX*ZOOuT- zrW^u=?DWO=54#}%u+w;Sd8U7szzYUBJ}aYZmGt}fYB~_>_!U)Gp^^Zr1n;tbD;*(% z)1*v@cX6{sP41vGQn3ks)>|N0mX?|h4d=wxB4wSqXxF^dwJi7m|GLJB!STTfbKIO# z7wg)x{F#Qv$;6w9sR!Qf$cksBRe5Rcg0wa-wJu1l)5G&p>!P$NFKu0rw&tX}At1s{ zF040b4Lze!}m-nFQBB)Rt|eaWz^kR=qh-7|>YV(bvEO54HDkgncGwt*#O+WHIxL^a00p@#}+ z`#E&eIdsE0bk{j_`-&fN!R(#cjf=Qpg%j`-_!5t})yu59Qb(0rv+av`^$I8AEmRj< srnQw=S@kn+ns44TzxMV;e8&nGcFi`swgNO))?dpuRB5{+K$9)xFTWt$4FCWD literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/loginLog.cpython-38.pyc b/views/admin/__pycache__/loginLog.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..839d8e2ecefea6b7c37854f2304bc52c76ce3c2d GIT binary patch literal 1974 zcmZvdTZfw ztmKEwQs<_Ek6S9*Q~_dZ=Npci#=!fBj~;4fDz$SqvlV=(+tQ0^*2K^=QZ9lq56$iAX0sI&#F5Th$l(a)(zFJLSJ?!sG4&|g#ykGb{DXWs+&g?xO(&6 zt!o=x5qUKVQ!f?hh?)r^-8uth2;=DxyQhWLxq65OKTL*@73LANjNeu=%q7LOEmgP1 z0{kYpdJ4V=ghj!u2-%2 zjk_RoD_u2#8BFbHD)n5NANvT(DFkb!OZ?RnWS)endj<4^UTZ71S+_#a3FRrpRKGIU6R=b74<+f)EQ)U`STtf+S3QKdtV0FM^WOC7&c z?r}h51e-Zqi7Is}NYtsVMA1xTnrSCd_AD*tu2<(Q>t!mD;cs93dG*fV_Qkf2m!~Aovn)Jq6>q0jqJ2O0TkM zOWeli>XT-_!m-mjt-?f}P1Vw@knL23d8)Lc>Q|Hiv)>*pvvlZNvwQL@suVL?#23S^ zh^4YZY19f|f)g^<#c_C`aAi^@k=FR%nB8q!9A>f@v3v6AqTmU>tx`n_v5VicVO!|7 h#)HH7-f}EorL}9)+61p*+x7_6yE?Dqfw literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/notice.cpython-312.pyc b/views/admin/__pycache__/notice.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..308b802c6c518defe4ade4a16f2144bb1a27c568 GIT binary patch literal 3654 zcmcguZ)_CD6`$GN+g;yZ?uapVi+zb5U{N_zN|J&Qm4UQsnwm7Gs^XxYHr@gDynA<@ zUE?@9D3vPpTq!arZS5wJa;b|Qpi75B5J?%i=8{^=nAAtTt4tj`&|DU1kin>PZcI3l`j!H`UOM0VQ&qr(i21l_i1gv{_r7$Xi5tVt*EMOc}M zCjSy$^qOcS;#xZzR_Jp?X!NyU!+UjB^h;-j+RTc5>8x;@SsNxJO7u26ufjR9n%C2( zbTZ*=QpfF+Bx~!Vs;%d;=}|+qEMh6x*)*t`diH2;jARGF$M*nBXz=OpKSQj1E^86! zibFXtvQ|vD4ihuyPW-V&C=6}zjKhTLs-eF~sKbBniKC5Ji=qm-yNN!z+fj>3Hirkb6kZ0YeZsHNB6 zymjdhOT}}wU%x)bJHlvABMxs`CmcajZB>yS(IocCoJQG~Ia2QV3>md8hgS{5k#kfd zH2wS}WuHbxrZ#|5ct@h-XXC`O9VzPu$8v%Yk9r6!cG6@rdG7~@_Z`bm!t&X)buyRV zX{we@XuBbpdMZ)F6#dni zU!0lk{6y-#p4dE-I-ja01{M#?2^ zE}gmZRE5 z(lKt=!I>AmDs@r`QXj?gQbZ-7TzdS;(N|M zc}e^>h-JhU8Gw}5 zGGA)UALX8fd^>?&;GabkScweLEij+E zUTS6+NgrhDA?6XtQ$1@tBB3-#Ek*FSvyGWVFQIxwVwi(G?Nezy4{rjYDHvsIS$_q! zK9!aQA+YaS0e=*))q6_i0sZ#h5B=mwF;k89Ek^q)a&iqBKfl|F!ij3AcQMraZ-fK;>U{rpCARky zdG9h0L-(vWe90^O4@u}_DS2oI|FMEWx2N#X|AE3jaM#QAKyf$)6DST=iJfT!-^?n3 zJ%6SPT!Z2n_T??omXNa6(SZFh0@^h8WvFYB`=U+o3$)>N&ANxb0jv>qEuGf06pF7V zmeh)++rPiyu|x^B@PR7e>jbR4p*Pb)JgysnUPsi3L7=e%ycFJp{v&LL1e>N+O8xT0 zeL(1=Y-6S#ho5y0)c=Bf03aXjoF1DRo6b$;W=T0ZP~@*AI%kyg%Iu++Q&42c(dp<^ zv?^~|l(&?AvLJ6M%R8&`o<(_2MScuO5bkO`C7<7wz5;sL{l7BUa}cAeIC*e@zuJ#M z4=Hh{n?eniK2BAWOyuZTN+Y8=s@gz$%1RN+2<~*dRaJ@=;;w2`=04DFYH=@n4!N(W z8-jcCe%NQ+AP49H@MOrhu7CpWV*DxkZVm0ffgZkr`fi}dZ=lqQh`3WG!V{P6uH;kSo_y#-6vQn1`Q&{W#EYECF5_Xrj z%c8t)&LIc*h0ZKgaD`Rxr54B_lg%uQC#Tx7m8skeq9}I~5E7cFRsa*l06II2qVUbU z4DzETsj_;xqd`%*i#QBFebazPG3@U2(dkACiC(dhuHZJErdmkS28J$6Xv8Z)nl^|Y z)d+}$MzPpbx{^ClsIn%~H-alE+TY+Vt1*wkW2ooW@ptBS!^_cpAKtfdkRiZp3??!r znBc-(=W|BJ5p)6;LGH4iwPC;!e3v#1W?&ov&Csub*7KZVo?n^WB2e!_r#eV+f-L z5^J4+vyBfiTR$+ea+iR2go7DvcFkS|f&UcW?hyEjaJwe@M<~Oy5!AgkHeAUYQc#_R z{dh)rg2Vw7IS<9wzj$HZ^K|jf7~1+*f4hBc~HPL5sp5sNpFRPg6uGg|L(5wggB(`BuT# zA#&M8fw~-(swC4~ZLsCoa3X*#2e@WG?d`OPFha58$>MlEs+}NRLHp31)hX>o{ zqJOTp_1)!y3*UVJb$A|Q^O8!Va3}co=`hN$x7tER5|tM)$~OyuU!)mj+_V`0JWv_% zGCE(yM~$Pnhpfk3HmR}I{#k!tz8|ouHBUnj%QFcqP6^pcAjptMp#A~`biQ9Vt||JX zXtDiU0jj9HTKE@&j)*V`sGjRyVT-Z-Yq;N1BwweqtAi+N*bRm^_6E01ox$_8oFMrhZA}FO literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/opLog.cpython-312.pyc b/views/admin/__pycache__/opLog.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbbb02eb97c7deef04cf57c483d3358aaef015b8 GIT binary patch literal 968 zcmZuv!AlfT7=LeOc4k~%Wr{TtG?9(k!|o*_iYS6264O%iuq-U&zNhXuvopOnDl2LQ zK})AP*-Z(8Vud=|sXw3&nu73HArK{R%HBNn-t3NB&^!FT-}imI-+bTi&G%R=3i#Q1 z_IRQS0oW5sc;p7D4Rf*#5J1od4$MF(xMWL?oRI@A+lmv(L;|kZs-tBz2qb_ZicG=^ z*A)k;FF~bFK}IiWN&Qe{Nyv25E97Pic#iYdJC7a=W9qp@ig_9t@&?>VPC5cIf=R)& z3-g#T`To7pd_y`=jc^nr*M4wV1`EIn%Krj_)0Y7tPkbq?TS~~9(bAecWZ~#mOIT?} zB%Lk^klY0pq2C&I7a&sBB9+GX79~Fxc94p+1<7g;^JZMrD-H8UKnWyU28kGGUQZF6 z^9v3>L_8hkt|*RKED@nS)5hUo<-_mK?+?mv_Fu0gWv1j^gqiHnNv0svH2hX`= zI*oANC8qBZO2m>Z7EGL;GK1)Af2t#K<^K4 CU+r)J literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/opLog.cpython-38.pyc b/views/admin/__pycache__/opLog.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a49b9cbd3a33b904b26fd2efb0755c2d6223a48d GIT binary patch literal 687 zcmYjPOKTKC5bnpkb~B6kIGCTX2luW>@D)XnC~mwA14C!K-JQ+!_E0v$s*$qVO`f=o!~oxTiEsY{<8;p z4W<>$>jh4k6?S6k99#Dkwzys^KbVM_tQ557vvl>Q@d%Y&ZG3a}^xwT* gE$hd$Yg~idUN?D&pU*3`;ip*tccv^wV<}JQKh~VI`Tzg` literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/order.cpython-312.pyc b/views/admin/__pycache__/order.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a6412928c0de8fe9659d63b57f7f043d05eeb0d GIT binary patch literal 6912 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 SU0v5q-j&l`p`og7+`j;9@q^j` literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/order.cpython-38.pyc b/views/admin/__pycache__/order.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b734c1e0ceb59b820a6bd0ccd88456701c85aa67 GIT binary patch literal 3665 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 K+XhT4@%|r5Y+4ln literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/overview.cpython-38.pyc b/views/admin/__pycache__/overview.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbbb4a81e1cd213ee456baec6ef328ddf4258ac0 GIT binary patch literal 3624 zcmbssO^+N$wX1ukr)Q>Tc6N4WckKjdK8!OEjp7Jngg?lx?L-m51ji<*wP@7ts@d(` z{&IEAnz4GNNJbVy3YY_@Sn>`Mhg`^kWB3`I>WXY*P8{HZgv5K*y|cUa5(P1%e)Zm~ z_o`pLs`t@1Tdjr$zXw-0Xm?4|{({8eUj>La;K}|BfNGS4np=#-C5qNvU5$oosIlT! zVAR8EWV$9PWNU5>ct&VNb+@i~m9P;t-DYIFwxX+HD{8xKg`44A)NwlsuZ8nb*X>3N z?t-GNa53t+J%!i9rD)k*CK_wf#s;}Zn9Y`Pq)lr7T)PLDyYj+Zi?++T6O_EC_2-_! z&a`WNBI|xS9{R~R7C*NuO%{v5_i%3LhhCPk3^b}^ z5rl{|SKod6I?K`|&KT%cZ)^tfhOGXOQ^sMsMFU?9M@;yeUKj#nX_ZDnd?VRr@hU97 zzqB;ox_ZMWXkGbRfw2Y8Wq7jh=$e*mTW}=X`U9PROOP$Hr%$zAB8;udUUjPNnLz1C zZPkReSD(VMd`J}65Dk#Q`3hoNHEPgGIae(?)fvYuIp&O0qqSX&TDx`8+_R_JubtgS z-q>s9^(i5mXy=W4WVb2i@+OSd``TIUN7{AmCmLwkwEnrY>?2w&+W1^rtwUPPna0X7 z*0m2w+Mg*ocObc;?RLPE9q`+HK7U2~>HXa@k?d8jK=|kf^2uQf}%h$LKm#9zNj?bAV z*iZx!8xA)FljIECNi!3k7-y2aF3CBLm+Oz>JecQzSk zPN8)1^qJGn22aMRb8E6Me*S;afBpZ|KX;t|Z%X@D2Lb~Uw(zR6HV}ab*{hBU`&SO8 z`i_?s%%l5Ub+(cqhHa}goHZwjodd0lYXfl1Z0iRTPT?hRhkB7iS>~U2?tWC7^qd(b z`JxTQOG_Kpirf>7%2c#(jLJweE}qmy*ymxp%Jq*k$_axg5YAaJ?#C3~S@1B=labFpChUhK1Q#w|r54XYK37nRKY zWeeu~;YABp_sEh3Z?52RFWw$fPk3_Wxzjk9Y3u}9Ae7WUF&3XZ`u$%&`Q4LWJb3)e zM;{xq;wO|zBg!^p1y}0#q!}@>nNVo~&CtWrh?6_q0%ciCZf!wuX3~Jo@OfmJqaYNF za}$Zi1{1?5iNV3V4h(K65r53Hgv%QH8S}>=jLm>FLKe#=D7+88zT!HXfZ&S=zJ$O*a1wy5Ww*m2$n)2LaxJ8A zll&!=cp1T$5qt%~R{_YnI(M)><2|6=T96hR(6nfL8AU3AU=e=>(2q5K9)^Eixbofg zlqbqD>*)lX7Z0<|BwdFLw!`>(G=Y7sV_DDEJ*>g&39ykKq!Z;td{_1X0L`#TgS7P} zfL;7oDx?BLE0j?66#s7f<-z2bfL{fxs7QlqD24mSIKw;OZ0VRZ} zvH}G~H127+DVk9FY+9KTTD_+O)yl1{HgsF&OWN!?n3?;mnSEW*tSxG4Jt%!sO_e$e z;Nn!9>a_l_14Xq*8?>3%sXZ%St)hI5yRhxYzrFwX(XXEVVfysJ{ilEY^y#OM?pDtX z&J14TIQtB`BrVXOjpgX9yZR}&-*Ic%B)jHC%x%JXXVAtWApkcg>{h~C}$>k(U-5PM-Nj!*@h(!sXxDBY5^almrN*VW| zbu38}jCjY3l`(D-GgW2z*T71C3P68}_hFD$8hT=s@JP1HD_q(vZIAn#aOr(9=8UhR zB3=eLSIYTdQ4lf?#e9-MY=D&+_NZ=qC*Wf2g~P%~jy{rADA+M|o7e=GhRW(FOgtg0 zA`xCFE4UYFhKcWmOm-kaP&V?$p(r^Om6I$8>yg6hijQcKCmQ@5+W0*LZy-=6uOWtZ z^D780A-IYFBU#090WJUud1I2j9gmU_i0s<{G^2oE1J?HzI*CPS|LXI+3-j6-$_k39Q2fSKEftz&BH=r&*- Mz-$BO?3)Px1DDMLF#rGn literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/record.cpython-312.pyc b/views/admin/__pycache__/record.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f462834333b724656c3400dbf1f504d453b8fac GIT binary patch literal 2950 zcmbW3Z)j6j6u|F&?cI`m=Wjp7+yu4VW3@_xo zlY8zx_uucFd;h4c^bjaB=RY_VbQAIy{;>;RP!=aZ86hfBX^g~aJEf>|F)q%x^QO+n zgt)8SW$HrA9T(e0N;slX)zwAEspUs?e@4a&F54y3DwbHK5^KdX)`}9V=NYS~#Om$$ z%Dy=qN2Z3PBqQN75v>n&Z}ZW2k7;@`(W7hd*L_UuOfVI+RhHJKv4|3je4;UffBWF^ z&cd|K8M{E@b}U{4F+$QLYF0ljRNB3j5OyHN+4WJu)|_utbaY#@w`G8)D(t#6Rk;a% zyx?nqOL=XJDyXhB7xmfyo$rKuyl`l3q@T!QE5pH#!y1LS($mk-Sugf`bm{8j>pwio ze3k#=(im?Doe5Pl__*F>2&$4&WYKWPwbbc^%5dd|nD{8Fb*6NKS7I>+oDha9W0fFe z-VmAgaj&MQP{BRb4Ub;jOdV$w3<6bkVf}O>xjnAvDUFq@g3f2a67N@% z$qqa{y+cvsk)96AeJI&)NU?~X3d8BLT5yk>rni6?B!7zj&(D2&ZnXBE*l<7a>PYD8 z&`h9lD$qC`*qjmX*KW#o-Dt_x?#g)XSJh={_T245za6=ABv*BKQaU^@5^4P+_#uXH z^hn!t7`P4g5t1tM0W=g(9Q#^jq6q!~P17juEAO^{jn*=sw z`+iJcPUotd1`o}O)iYwua8^EW z2VqSk0807LjoP^m`rAc?0JJv_0uxtdmMHSSqLk~OrVzdbNFaQ1tIU$-U=Du!pYwH& zX@F1jQQVvrr34s0iaWca*meL0Ps%K+q*j2pa^rbQfN|Ojsu$8o0kAf*k(8`lvb{Rr zM#5G-H6A1B`L+?x_@XjhnjFzIBC(9Ce@$ylTmQunDy z48Stnsut5g*@VszKAE?;gtrCU#4vJLVa&c&&7{h>u*aNcB@vefGmiseW48J|i_vNliIvCqU|Z z#YwJDmc;+T8V1gV=DKE?{4NLg`}n(F3bIx98EY9l5yGdK64&|?tUILQTR}-Bn9eZ! z8kOdKA3Ck{s4b{)fP@y@g!5$H%xsyafdx*W@6$z|aI5D{b-|Cu notdrEboBx!(l^jnGmqLrO{vLOG=a9zP->D2rUec(bAtZ?3{_h3 literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/record.cpython-38.pyc b/views/admin/__pycache__/record.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af8e0f33d0110b15e59e6350b41c9daa563dfeb3 GIT binary patch literal 1685 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 X+s0~J7_RSrn5|H0yUxPU`nZ1rV}n+M literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/tag.cpython-38.pyc b/views/admin/__pycache__/tag.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28ecff2247b4f769b9dcc4e4ccb1f5ff4b561e34 GIT binary patch literal 2248 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 literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/thing.cpython-38.pyc b/views/admin/__pycache__/thing.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfad03fef9705a336ce2e35c22ad5830425d9423 GIT binary patch literal 2913 zcmZ`*TW=)A74E9OOwZM0uWhniBmzoclEqP!K*B|c6}v*b7!-Sx(6Kb?ovO8a+&w+1 zE-!dBeu<+9Az7@rBaj$Ji-aH0f`SAg2@m{?eu@-kvi<@4!b|d<>hWz^deo;+ol{fY z{e9m#)fejZiiP9q`BjnBE$crtIDR-7JcTp+H;k|Zi>-tOEa3rXH0H6LIDun)J9ZN< z@Qm-orNj?>Lbx;UT4nSBj2u(}{`ovW|lu^|^+Si5|SO-8mE@yWiWPT(s%flryBxf54`S_sPEWI5E{s7EGj6}%1i5V z^Tkw&oON#)_#y+rD@R1~+jSEW|Id64vCS9Wxk zdzYeEgB>4FB~|<4rXu|FS)-Lhy4$*7JB(vhro7u%QBUV(6K`i&wu-Rw$ef00mGY93 zf83CnRt*YHk!ivNp7~FfH%{InuRu2wt?XIq$C&!8sQ{=}LbSFVbsgYiWN4 zQ!h)kl5B?k{t9V5TM0?XD`xG5{$}pSQKs7{1%fHN7slch)-XSZ%`*pH%~+q+c$3$d zdJuC?D3KZnp=FeK8P1h^NsB`!nBb&9&AWD&L18wO!hdJ=790yPXT72pnMFVC4!waT zoL#gWT@tQvgtx;z>jkLd_oQrJl%Q;-%LBemYAXp}l%cf>)O4Vp>Y_S@yYK%Ghnj|W zlh7Pp|ND(kcfa{!XY}zqqxV1BCsFKibq6l$2V_WbMk;EKym^>bwTRwD0eUrcH%wkT zm&$B0)#qOVXo_AtFURR>TPl^Rg48={vf-HM-E-9a6quo@t^r;Bhyp}gVIH8ACnQ82 z-v>XVxt7g=`wVLW`x)@zGxc+t=RE)1(#bBs5kBk!7ctO4Yn!QAZO{kedH~PnyMI9QTO?8f5{nPl( zPxjw<_r~?>$EJ<0eR|`w4_g&Q+gE|^A+Wh0W$nx8m?C$w5E}m>=H#9sA~VdW1w>lB z!2h>wKki8w+M*VyUyoGDjkM7zt@Jy5(Z4Tv)zy_Ij-1Dm?2`U|d=31{e{P`@v#hBNfuZq0C3A2z^Q z?U1wjgfnzj;!OR53~^&hMYYJIQc*u4^Gh;RAV;O39>&nHGJfx~@mrrvSeZJ;iYcIz zrJ^39MTqi30gsUPD>6is`ZXD`hO;4fXvkW~4Wii7W$BB9j`4dFh z2pqPgJ_ffX>I@(@L}AM_g#p4qk#@UY7X%PtL!SUg%OcX;ZW*Lq{9e-VU2|)Z908u& zk;uMfXRw!fk!ZK0UV%BmJyHE||J`dvahy>7A-=hr_2a16noLJh_u$XeJz|N?i7;>3 zh2kHFACz#%cBs@X*s3Ry`~%Koy65OL74-Wix{k>&w(bZ{E9^_{ODaqxcH{L0Av>uG zb*eH&eMb?>xodV8!)9>W_zUzsWz5k>m7*pU)QkLD*b^~omA1j4R>Tr)$#G_O)uQ9l z{u$g=B>Pe&5k9NZ-olY<6c|hwGmbXJtZ2VRdkYBkE0T$MxnqDB*_kHnKY?f1 gh~<;?ZW+aCyQAMM&Zh0N${fxHHHcc%*m<)52N?dfy8r+H literal 0 HcmV?d00001 diff --git a/views/admin/__pycache__/user.cpython-312.pyc b/views/admin/__pycache__/user.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eeca8512dcd8f2a4d0c637a18e28a75fdcb61e7a GIT binary patch literal 9098 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 E0F2Hl>i_@% literal 0 HcmV?d00001 diff --git a/views/admin/ad.py b/views/admin/ad.py new file mode 100644 index 0000000..92a2ad5 --- /dev/null +++ b/views/admin/ad.py @@ -0,0 +1,68 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Ad +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import AdSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + ads = Ad.objects.all().order_by('-create_time') + serializer = AdSerializer(ads, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + serializer = AdSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + ad = Ad.objects.get(pk=pk) + except Ad.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = AdSerializer(ad, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Ad.objects.filter(id__in=ids_arr).delete() + except Ad.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/banner.py b/views/admin/banner.py new file mode 100644 index 0000000..a280cbc --- /dev/null +++ b/views/admin/banner.py @@ -0,0 +1,68 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Banner +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import BannerSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + banners = Banner.objects.all().order_by('-create_time') + serializer = BannerSerializer(banners, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + serializer = BannerSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + banner = Banner.objects.get(pk=pk) + except Banner.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = BannerSerializer(banner, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Banner.objects.filter(id__in=ids_arr).delete() + except Banner.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/classification.py b/views/admin/classification.py new file mode 100644 index 0000000..24e7758 --- /dev/null +++ b/views/admin/classification.py @@ -0,0 +1,74 @@ +# Create your views here. +from django.db import connection +from django.db.models import Q +from rest_framework.decorators import api_view, authentication_classes + +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Classification +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import ClassificationSerializer +from myapp.utils import dict_fetchall + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + classifications = Classification.objects.all().order_by('-create_time') + serializer = ClassificationSerializer(classifications, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + classification = Classification.objects.filter(title=request.data['title']) + if len(classification) > 0: + return APIResponse(code=1, msg='该名称已存在') + + serializer = ClassificationSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + print(pk) + classification = Classification.objects.get(pk=pk) + except Classification.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = ClassificationSerializer(classification, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + # 删除自身和自身的子孩子 + Classification.objects.filter(Q(id__in=ids_arr)).delete() + except Classification.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/comment.py b/views/admin/comment.py new file mode 100644 index 0000000..c9628e5 --- /dev/null +++ b/views/admin/comment.py @@ -0,0 +1,69 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Comment +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import CommentSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + comments = Comment.objects.select_related("thing").all().order_by('-comment_time') + # print(comments) + serializer = CommentSerializer(comments, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + serializer = CommentSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + comments = Comment.objects.get(pk=pk) + except Comment.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = CommentSerializer(comments, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Comment.objects.filter(id__in=ids_arr).delete() + except Comment.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/errorLog.py b/views/admin/errorLog.py new file mode 100644 index 0000000..369d9a9 --- /dev/null +++ b/views/admin/errorLog.py @@ -0,0 +1,14 @@ +# Create your views here. +from rest_framework.decorators import api_view + +from myapp.handler import APIResponse +from myapp.models import ErrorLog +from myapp.serializers import ErrorLogSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + errorLogs = ErrorLog.objects.all().order_by('-log_time') + serializer = ErrorLogSerializer(errorLogs, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) diff --git a/views/admin/loginLog.py b/views/admin/loginLog.py new file mode 100644 index 0000000..3747dff --- /dev/null +++ b/views/admin/loginLog.py @@ -0,0 +1,60 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import LoginLog +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import LoginLogSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + loginLogs = LoginLog.objects.all().order_by('-log_time') + serializer = LoginLogSerializer(loginLogs, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +def create(request): + + serializer = LoginLogSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + try: + pk = request.GET.get('id', -1) + loginLogs = LoginLog.objects.get(pk=pk) + except LoginLog.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = LoginLogSerializer(loginLogs, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + LoginLog.objects.filter(id__in=ids_arr).delete() + except LoginLog.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/notice.py b/views/admin/notice.py new file mode 100644 index 0000000..402b3c1 --- /dev/null +++ b/views/admin/notice.py @@ -0,0 +1,68 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Notice +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import NoticeSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + notices = Notice.objects.all().order_by('-create_time') + serializer = NoticeSerializer(notices, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + serializer = NoticeSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + notice = Notice.objects.get(pk=pk) + except Notice.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = NoticeSerializer(notice, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Notice.objects.filter(id__in=ids_arr).delete() + except Notice.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/opLog.py b/views/admin/opLog.py new file mode 100644 index 0000000..9feec40 --- /dev/null +++ b/views/admin/opLog.py @@ -0,0 +1,14 @@ +# Create your views here. +from rest_framework.decorators import api_view + +from myapp.handler import APIResponse +from myapp.models import OpLog +from myapp.serializers import OpLogSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + opLogs = OpLog.objects.all().order_by('-re_time')[:100] + serializer = OpLogSerializer(opLogs, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) diff --git a/views/admin/order.py b/views/admin/order.py new file mode 100644 index 0000000..2b81ac4 --- /dev/null +++ b/views/admin/order.py @@ -0,0 +1,147 @@ +# Create your views here. +import datetime + +from rest_framework.decorators import api_view, authentication_classes + +from myapp import utils +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Order, Thing +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import OrderSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + orders = Order.objects.all().order_by('-order_time') + serializer = OrderSerializer(orders, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + """ + 创建订单 + """ + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + data = request.data.copy() + if data['user'] is None or data['thing'] is None or data['count'] is None: + return APIResponse(code=1, msg='参数错误') + + thing = Thing.objects.get(pk=data['thing']) + count = data['count'] + if thing.repertory < int(count): + return APIResponse(code=1, msg='库存不足') + + create_time = datetime.datetime.now() + data['create_time'] = create_time + data['order_number'] = str(utils.get_timestamp()) + data['status'] = '1' + serializer = OrderSerializer(data=data) + if serializer.is_valid(): + serializer.save() + # 减库存(支付后) + # thing.repertory = thing.repertory - int(count) + # thing.save() + + return APIResponse(code=0, msg='创建成功', data=serializer.data) + else: + print(serializer.errors) + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + order = Order.objects.get(pk=pk) + except Order.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = OrderSerializer(order, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def cancel_order(request): + """ + 取消 + """ + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + order = Order.objects.get(pk=pk) + except Order.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + data = { + 'status': 7 + } + serializer = OrderSerializer(order, data=data) + if serializer.is_valid(): + serializer.save() + + return APIResponse(code=0, msg='取消成功', data=serializer.data) + else: + print(serializer.errors) + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delay(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + order = Order.objects.get(pk=pk) + except Order.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + if order.delayed: + return APIResponse(code=1, msg='已超最大延期次数') + else: + data = { + "delayed": True, + "expect_time": order.expect_time + datetime.timedelta(days=30) + } + serializer = OrderSerializer(order, data=data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='延期成功', data=serializer.data) + else: + print(serializer.errors) + return APIResponse(code=1, msg='延期失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Order.objects.filter(id__in=ids_arr).delete() + except Order.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/overview.py b/views/admin/overview.py new file mode 100644 index 0000000..459a1f0 --- /dev/null +++ b/views/admin/overview.py @@ -0,0 +1,140 @@ +# Create your views here. +import datetime +import locale +import platform +import random +import time +from multiprocessing import cpu_count + +import psutil +from django.db import connection +from rest_framework.decorators import api_view, authentication_classes + +from myapp import utils +from myapp.handler import APIResponse + +from myapp.models import Thing, Order +from myapp.utils import dict_fetchall +from myapp.auth.authentication import AdminTokenAuthtication + + +@api_view(['GET']) +@authentication_classes([AdminTokenAuthtication]) +def count(request): + if request.method == 'GET': + now = datetime.datetime.now() + thing_count = Thing.objects.all().count() + # print(utils.get_monday()) + thing_week_count = Thing.objects.filter(create_time__gte=utils.get_monday()).count() + order_all_pay_count = Order.objects.count() + order_not_pay_count = Order.objects.filter(status='1').count() + order_payed_count = Order.objects.filter(status='2').count() + order_cancel_count = Order.objects.filter(status='7').count() + + + # 未付人数(sql语句) + order_not_pay_p_count = 0 + sql_str = "select user_id from b_order where status='1' group by user_id;" + with connection.cursor() as cursor: + cursor.execute(sql_str) + sql_data = dict_fetchall(cursor) + order_not_pay_p_count = len(sql_data) + + # 已付人数(sql语句) + order_payed_p_count = 0 + sql_str = "select user_id from b_order where status='2' group by user_id;" + with connection.cursor() as cursor: + cursor.execute(sql_str) + sql_data = dict_fetchall(cursor) + order_payed_p_count = len(sql_data) + + # 取消人数(sql语句) + order_cancel_p_count = 0 + sql_str = "select user_id from b_order where status='7' group by user_id;" + with connection.cursor() as cursor: + cursor.execute(sql_str) + sql_data = dict_fetchall(cursor) + order_cancel_p_count = len(sql_data) + + # 统计排名(sql语句) + sql_str = "select A.thing_id, B.title, count(A.thing_id) as count from b_order A join b_thing B on " \ + "A.thing_id=B.id group by A.thing_id order by count desc; " + with connection.cursor() as cursor: + cursor.execute(sql_str) + order_rank_data = dict_fetchall(cursor) + + # 统计分类比例(sql语句) + sql_str = "select B.title, count(B.title) as count from b_thing A join B_classification B on " \ + "A.classification_id = B.id group by B.title order by count desc limit 5; " + with connection.cursor() as cursor: + cursor.execute(sql_str) + classification_rank_data = dict_fetchall(cursor) + + # 统计最近一周访问量(sql语句) + visit_data = [] + week_days = utils.getWeekDays() + for day in week_days: + sql_str = "select re_ip, count(re_ip) as count from b_op_log where re_time like '" + day + "%' group by re_ip" + with connection.cursor() as cursor: + cursor.execute(sql_str) + ip_data = dict_fetchall(cursor) + uv = len(ip_data) + pv = 0 + for item in ip_data: + pv = pv + item['count'] + visit_data.append({ + "day": day, + "uv": uv + random.randint(1, 20), + "pv": pv + random.randint(20, 100) + }) + + data = { + 'thing_count': thing_count, + 'thing_week_count': thing_week_count, + 'order_not_pay_p_count': order_not_pay_p_count, + 'order_payed_p_count': order_payed_p_count, + 'order_cancel_p_count': order_cancel_p_count, + 'order_all_pay_count': order_all_pay_count, + 'order_not_pay_count': order_not_pay_count, + 'order_payed_count': order_payed_count, + 'order_cancel_count': order_cancel_count, + 'order_rank_data': order_rank_data, + 'classification_rank_data': classification_rank_data, + 'visit_data': visit_data + } + return APIResponse(code=0, msg='查询成功', data=data) + + +@api_view(['GET']) +@authentication_classes([AdminTokenAuthtication]) +def sysInfo(request): + if request.method == 'GET': + pyVersion = platform.python_version() + osBuild = platform.architecture() + node = platform.node() + pf = platform.platform() + processor = platform.processor() + pyComp = platform.python_compiler() + osName = platform.system() + memory = psutil.virtual_memory() + + data = { + 'sysName': '商城管理系统', + 'versionName': '1.1.0', + 'osName': osName, + 'pyVersion': pyVersion, + 'osBuild': osBuild, + 'node': node, + 'pf': pf, + 'processor': processor, + 'cpuCount': cpu_count(), + 'pyComp': pyComp, + 'cpuLoad': round((psutil.cpu_percent(1)), 2), + 'memory': round((float(memory.total) / 1024 / 1024 / 1024), 2), + 'usedMemory': round((float(memory.used) / 1024 / 1024 / 1024), 2), + 'percentMemory': round((float(memory.used) / float(memory.total) * 100), 2), + 'sysLan': locale.getdefaultlocale(), + 'sysZone': time.strftime('%Z', time.localtime()) + } + + return APIResponse(code=0, msg='查询成功', data=data) diff --git a/views/admin/record.py b/views/admin/record.py new file mode 100644 index 0000000..35a6df8 --- /dev/null +++ b/views/admin/record.py @@ -0,0 +1,53 @@ +# Create your views here. +from rest_framework.decorators import api_view + +from myapp.handler import APIResponse +from myapp.models import Record +from myapp.serializers import RecordSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + records = Record.objects.all() + serializer = RecordSerializer(records, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +def create(request): + + serializer = RecordSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +def update(request): + try: + pk = request.GET.get('id', -1) + records = Record.objects.get(pk=pk) + except Record.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = RecordSerializer(records, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +def delete(request): + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Record.objects.filter(id__in=ids_arr).delete() + except Record.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/tag.py b/views/admin/tag.py new file mode 100644 index 0000000..80fb7c8 --- /dev/null +++ b/views/admin/tag.py @@ -0,0 +1,75 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp import utils +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Tag +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import TagSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + tags = Tag.objects.all().order_by('-create_time') + serializer = TagSerializer(tags, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + tags = Tag.objects.filter(title=request.data['title']) + if len(tags) > 0: + return APIResponse(code=1, msg='该名称已存在') + + serializer = TagSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + else: + utils.log_error(request, '参数错误') + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + tags = Tag.objects.get(pk=pk) + except Tag.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = TagSerializer(tags, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + utils.log_error(request, '参数错误') + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Tag.objects.filter(id__in=ids_arr).delete() + except Tag.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/thing.py b/views/admin/thing.py new file mode 100644 index 0000000..1eb31a8 --- /dev/null +++ b/views/admin/thing.py @@ -0,0 +1,104 @@ +# Create your views here. +from rest_framework.decorators import api_view, authentication_classes + +from myapp import utils +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import Classification, Thing, Tag +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import ThingSerializer, UpdateThingSerializer + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + keyword = request.GET.get("keyword", None) + c = request.GET.get("c", None) + tag = request.GET.get("tag", None) + if keyword: + things = Thing.objects.filter(title__contains=keyword).order_by('-create_time') + elif c: + classification = Classification.objects.get(pk=c) + things = classification.classification_thing.all() + elif tag: + tag = Tag.objects.get(id=tag) + print(tag) + things = tag.thing_set.all() + else: + things = Thing.objects.all().order_by('-create_time') + + serializer = ThingSerializer(things, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['GET']) +def detail(request): + + try: + pk = request.GET.get('id', -1) + thing = Thing.objects.get(pk=pk) + except Thing.DoesNotExist: + utils.log_error(request, '对象不存在') + return APIResponse(code=1, msg='对象不存在') + + if request.method == 'GET': + serializer = ThingSerializer(thing) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + serializer = ThingSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + else: + print(serializer.errors) + utils.log_error(request, '参数错误') + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + thing = Thing.objects.get(pk=pk) + except Thing.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + serializer = UpdateThingSerializer(thing, data=request.data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='查询成功', data=serializer.data) + else: + print(serializer.errors) + utils.log_error(request, '参数错误') + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + Thing.objects.filter(id__in=ids_arr).delete() + except Thing.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + return APIResponse(code=0, msg='删除成功') diff --git a/views/admin/user.py b/views/admin/user.py new file mode 100644 index 0000000..e04b073 --- /dev/null +++ b/views/admin/user.py @@ -0,0 +1,176 @@ +# Create your views here. +import datetime + +from rest_framework.decorators import api_view, authentication_classes + +from myapp import utils +from myapp.auth.authentication import AdminTokenAuthtication +from myapp.handler import APIResponse +from myapp.models import User +from myapp.permission.permission import isDemoAdminUser +from myapp.serializers import UserSerializer, LoginLogSerializer +from myapp.utils import md5value + + +def make_login_log(request): + try: + username = request.data['username'] + data = { + "username": username, + "ip": utils.get_ip(request), + "ua": utils.get_ua(request) + } + serializer = LoginLogSerializer(data=data) + if serializer.is_valid(): + serializer.save() + else: + print(serializer.errors) + except Exception as e: + print(e) + + +@api_view(['POST']) +def admin_login(request): + username = request.data['username'] + password = utils.md5value(request.data['password']) + + users = User.objects.filter(username=username, password=password, role__in=['1', '3']) + if len(users) > 0: + user = users[0] + data = { + 'username': username, + 'password': password, + 'admin_token': md5value(username) # 生成令牌 + } + serializer = UserSerializer(user, data=data) + if serializer.is_valid(): + serializer.save() + make_login_log(request) + return APIResponse(code=0, msg='登录成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='用户名或密码错误') + + +@api_view(['GET']) +def info(request): + if request.method == 'GET': + pk = request.GET.get('id', -1) + user = User.objects.get(pk=pk) + serializer = UserSerializer(user) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['GET']) +def list_api(request): + if request.method == 'GET': + keyword = request.GET.get("keyword", '') + users = User.objects.filter(username__contains=keyword).order_by('-create_time') + serializer = UserSerializer(users, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def create(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + print(request.data) + if not request.data.get('username', None) or not request.data.get('password', None): + return APIResponse(code=1, msg='用户名或密码不能为空') + users = User.objects.filter(username=request.data['username']) + if len(users) > 0: + return APIResponse(code=1, msg='该用户名已存在') + + data = request.data.copy() + data.update({'password': utils.md5value(request.data['password'])}) + serializer = UserSerializer(data=data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def update(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + user = User.objects.get(pk=pk) + except User.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + data = request.data.copy() + if 'username' in data.keys(): + del data['username'] + if 'password' in data.keys(): + del data['password'] + serializer = UserSerializer(user, data=data) + print(serializer.is_valid()) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def updatePwd(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + pk = request.GET.get('id', -1) + user = User.objects.get(pk=pk) + except User.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + password = request.data.get('password', None) + newPassword1 = request.data.get('newPassword1', None) + newPassword2 = request.data.get('newPassword2', None) + + if not password or not newPassword1 or not newPassword2: + return APIResponse(code=1, msg='不能为空') + + if user.password != utils.md5value(password): + return APIResponse(code=1, msg='原密码不正确') + + if newPassword1 != newPassword2: + return APIResponse(code=1, msg='两次密码不一致') + + data = request.data.copy() + data.update({'password': utils.md5value(newPassword1)}) + serializer = UserSerializer(user, data=data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([AdminTokenAuthtication]) +def delete(request): + if isDemoAdminUser(request): + return APIResponse(code=1, msg='演示帐号无法操作') + + try: + ids = request.GET.get('ids') + ids_arr = ids.split(',') + User.objects.filter(id__in=ids_arr).delete() + except User.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + return APIResponse(code=0, msg='删除成功') diff --git a/views/index/__init__.py b/views/index/__init__.py new file mode 100644 index 0000000..a48d28d --- /dev/null +++ b/views/index/__init__.py @@ -0,0 +1,8 @@ +from myapp.views.index.classification import * +from myapp.views.index.tag import * +from myapp.views.index.user import * +from myapp.views.index.thing import * +from myapp.views.index.comment import * +from myapp.views.index.order import * +from myapp.views.index.notice import * +from myapp.views.index.address import * diff --git a/views/index/__pycache__/__init__.cpython-312.pyc b/views/index/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..309bef522bd40a370495ae14de12e6708ae78baf GIT binary patch literal 496 zcmX@j%ge<81lQ{W)0`O@7#@Q-Fu(+5d=3FJrZc24q%h_%tYu<^uo&SiCOC^3&SHVH zSm7)-IEx*`s$|k+ehIQdlkpa#mY*iaErs05#DW67vdq--V!h0~l++5n@(n zYW1-iM3#U-gl*o1)2E(6Md z?TP`1L<~42V&da7^D;}~Ar=p;VWHh^RsLN(sv>&Lnx^I_!9H5;woLZgjT?~Ukr2zsRjkJ=h?mfwiHCFgm29h4^* zc|UgAwB#y35Ox@piTh@(mmqeT&lnrEQ2W%llwO7KiF^qTr}VQ}-caZ5s}eC#H^$By r7CP%FJawZyo%HGCo=)y5W7_D*SmVZRwHT~i_v#kD28B~d72aLHD42ws literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/address.cpython-312.pyc b/views/index/__pycache__/address.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..102add9204cf23af24208b8c4314fc2f1899cecb GIT binary patch literal 4464 zcmb_fU2Gf25#IYD?qX5mYf$6FYLW)Mc0kx`r( zVB+im%g{C}b8&uv*Xx{Yi`xh6dYzYrxHur{b(`#n*9_F?b-V10y9QhgVv)pP;R16L zJkx^3pP`#Z6%Dv`t;5nno0aTV8`oIY9W=k8C5Sz!)kOeqDB+L;Xyf~D3TInG~1{em1)J-pBR#cJHgJhf=*}W+0(B` z%1B~Zk)SDbVoW4OH!oHDBod9t(KjTbai?DHA1rN~zGF6!96XQr>c^BsF}-`ez|7D- zgvd3}vg9*XyRj$k&$yW zx|MU$VJuxaSDGO-GNy@gR8hka{-hZupeL`4gP1_~1kcZ}zIiph^;03R1&L6sUGV2fJ{ogP8yK?@nkA9T*_oq%T zH}0QpUwom^cp`OXxh|0DoIU0UT6CSJiQB#W?mE#&MW0&&MU1H`ydR;a1BC z#kNXZ^r0k2TE77%*?G}KT~$o-^A1zbpbAu?*cNkVtT*7U#7N_Ol8@2o-cU@MCi_6Y zb%PR`rXJ?9z7%i^*45^7SKxe`=`H3rYt}o7u*clZb-r!bYq3io3U28E^h(Mgp#-D} zSUMjWmDQ7ku2n~UC5%Y}^b!wpUKEcON35paUH#)7gChuKuFokxSEsJs|JALB zzr6lnVL^9ln618d`@skA2i;^R^+CVFfH)-s(n!U25I|NVz%P=)0dzV|j4I(va4%qu zS0Vscx^vc~=oLDQ(nB+8qULsk{zwQK zbTP``K}?`WBH9+1k*DQi!`@uO-pr+0HQ(^UMDLQbcB*5tqv+g`bM8o=%yi|Q!HKRV z&(B@?MycjHstvRuEacfp=Er>6!_;$_;3$8g=!FPD#%#z?M3fptS_JZ)-l2}Uz z7sSSr+r=|~?)|X0;O)+e-7BJ-D$_zHP!L;JoDJ#D%<+P=Ez7r&Z^M^Wzf8Mzns7WD zQLtvHjWep5J)v0n!i336r5a(tHOZA>L{k5qbB6`@gvzobPWKk;TXOX+vu)Y>mVA9Ejpy;^SaS4eTofx$nS%f&dlZMm(P14A3l+t~Iq`5o zJo*G8ew%e!eep#28i7WCFRpcN?+l`kgUv6wxW70VkUc@4)(HQUYWO^f#HGs#G8Dqn zV1h){1W^e67(y=$&88>(Mk3Lu*F*HDRu|TvEulxLxefir$S{^6-=KS?xs1Lz{1VBE z@i*f$x+;E03}R^pdp*Z6=z(tE9MW%OJq>v(c7T^rSvpQ$0u{|Kl|>K$D2DkAom@rR z?xLf2(Vn}g`7Zj-njNtII+#x8F^AZ?M|yS5PnAbf`|?cPKbURV#{F6U rfjo0?jjd;%r*?;^sDH#mb1k%)ZNqw7Xs)$wX6vZ5UE`stf7$;4N2!a< literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/address.cpython-38.pyc b/views/index/__pycache__/address.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f28e65ff357934a5fe8f51ef098af1de1ceb6988 GIT binary patch literal 2392 zcmZvd-)|d55XW!#e)w#k9Vb*N;b&ET8nr=)w}KFbwx|*^6)6HNOYYUXP0l|1%s zBIkwjP$4Y(0Entcbx|%4@9xd_GjpF6 z3ONI>OGg*Q5L^1>qz`if8Z3Zgjn zO+De85~Z=PB&HXP^2|1#-6-?K^}9j+Y#`4ivwkmLlASnc_;C<*>W$D>N~$tT>|Pv% z)R;aQwPfco&U-iu2lIzd9RF0RZq!i{yP3m6fK+<=xVa!9@WWt5LSlY&^kjq4-s6jc zY2*DN-s%*ZzR|>xwm8(V#fDsPVXpC2)@QyOpcb0)p-1E?EUcJ7x@$2TrOQUbEuA7O~h=fecwpvUq;m7{Ao;X9Z_2T#L z47M)(b??sIf7b7=b10z$rqPshiPM(xQY6x|n2R!o3_6lbbh;@Uu}YjXK^SAi+z5n( z`srnG>E8|++MsMD8IWJ~q>6!fO|pI(c&U;cZa$9qx&hCl_rW_y4%NC4>9uR!W!$<` zS4&a1hEvZGFowB1NM@68V$1BMcibH z1Z|hNfvTUyBom3Hd=!-OD#?b?VqF46P`2S29H~x?RjoIoPK?Q}-%+0%os6@MA^b z-Ihk-K504H_+#tV8Uiu8@$=}H-%=Wgn>41R^f7pe`Y)52)R8N?FvEt-4{5*5cjyCS)iv-{xs00=sOcaeNcoNd~vA`v8w+54?@ekMT|` zCI-)AIX0`qr+t<3bTWtE%D8?8{I)z7L2F*fMg)EwfdY*}25^qg+b)5lty z$rl@_)Fy@0zvOpBh^bG9t$OKL8$VW|O20GH>Cogup;Bh3lIvVfIigqC^;+~P0bLo~ hcX72|DBq(~s(om%3g8RspXsukN0q_btL+@w{{T1vL%{$5 literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/classification.cpython-312.pyc b/views/index/__pycache__/classification.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..084594a4fec6f946e5ba43ea633bb50aecf01eeb GIT binary patch literal 1087 zcmZuvO=uHA6rR~lvYUTYs&x;VOKEdx=%Mx?Vi7A+sjdAvg+SQuOqxyiC(dkIQ`)K^ z7(98aw-!NAQt+xLd-CGN+CpGyK#&%_wdB^5Gn=fj;yb+g-rKkD=X>u(QS)avRc;jOFCX=IC|^B z_zb3H+oG76iQ9%ssb0`EwG-TX)-#KVt{VCZCM-IRbj`^Zu%i`K!*IpBcjmNCFJ2o# zrupox&rEHARlw)}R}fqr0D#OmjJ39u0zT@#C8>*jYe?~f+|SMlZ2OBi4AH5s}9aPx{2o)839wZs)VPm z#F#qTeDm}D>!aGs!xx)r(G6%e!meo21vh|HM@`Fa$iz<3MkK_dUCEv=u?10AGe|AH8$Ej56baw1|u3TkhtUN8+_LQkw@}Ot%t-Uk0-!oo|93+)3xV8S_ z-lwULQ~Sw@ukysP1mvqNmK02;<8Bz0RBOS`pn1Xvb1xG{K)yg!6EE9jF@vyX6VUxHm0D%O#44ys_KO){ax#+p^X6R1OHK z5_b-5kvMSTKllV+5f%IbC&t+dT1PXQnT+1dd-m(WAVF|GeV?#0KYA6fQZ-~TZK`6g;`1yc6jA7Egmy za)wSr7M$TjYg2n&yc!@zb~hjkahG-A;)*#KpLOT4aQKsZS6m6}t_3tLIP2}^{M z)^qL0&QfsaCtrSj`+WZX6_60=gHI6ywR#f&YL-ms|zzx zO%APlT<3C5nHVDhSF{B3>}bkxjUEGlCQxT-!N8qXaC3BHa~tZzfSJ{-6no6>q) zjo4VjQ$y~qh6Rf)O(ow~dS}FVsWi1p8||;c4cfV*39Xsnx}}$;%bEn4gjs5GV_Eu7 s%d~Q2{bhY-E9i^>uwA5Oe97JNli~*eI1~J#-^;9kOK}>2`H#f-FK+4H6#xJL literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/comment.cpython-312.pyc b/views/index/__pycache__/comment.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d09e6b06476507f03e5b499ffeea983ccc6a0e71 GIT binary patch literal 4518 zcmeHLO>7&-6`tKCcb6hXij-_xaw-wA9eeFq4jd~^4A(Io8>xRHyS7>+j8cN(tfiH> zBs;sZtw8?i4^TQtY7;$BMFK=E54;_F{Z{K_KW@hJmKdV2rwzeP`<%{1wJ?KX0@ARQM92MrFmqRFrFv45{ z>0E@<`3SEI5rLyJKH<=v5hvq?gs4jqiSdqvth*vE#yb-&x;x@#yqNIlt&vv7O9`*; zi}*OiBbCGQ5O)n$q652rjIP-%inM)2+tQ%*Gp)Nm7oG*xS%1c!x^>NGVD&8ATDOX{ ze?{wU&~}Xbl(q+ScZy)iv9uOFqp4@DwXrdCSWTK*JZ5UCWHg?L8HQ?DZRRjZnPx(* zN)*oWzA}C?W~u`f4M^68v92WtQln}z41TI!K;sUdIDAqy(y64O!lU$3O4nf-V11f# zP}Ngx=64L0fXH9bo>GYxOK5MY#1dXUG!U=6SN2MsKn3_ce4E|t1R7!Dl>~F6TM#0j zfRB`UH<1Y;^%U&kIQ&i{}MXtS&bqSGoG% z5y0;1fu$;%Mp{?v5Srj-<(l5tL@!je=N+cMs-JLR*KA8|w@$OYs=;pTnQ)GDRG;gA zXIrn)w+-VIYOwcW-)vje(FEms_{T?W>QP znyxOpwcZO}%m|hv zp2Dgn=*E!cz%euSfZ}6}&aJFHf8*WzKl<(bjhkQ0+??UbI?#|#ATw@D)Kzmhh3&lx zL#jz!ps=LWnuZcE*B zfzI5v?6%yF?2ajAdY~BCnUUt&f;o5Ao%3aVQ_}RhV%yG)^RMo}oUdb2zU>Rmbtzft z^RCTTrTJiY?qc?0IoMYS_WgRO7~EG59x4P6{qf~|@K7;0P!7IP2)>d3o>~l^&U|aW zbL;f;H#U|!U(6i2)80K5p5FKSmOuDz`AY34@}3j(RFvPgztkSid%}x7NbY$E+eQBm zc={F^$NzA^i(`Py!keu%KxlelK~2_DE=b9GAY;_l_R<)+ z>lj2DCWzYT{MOYQsfp8YHw$X0qB z$BE;o{!JD98|ZV$tX0V7m20-vn?P;jn$~SLXSig*f1?!_sn=o{=Q2`<|Kbv>MBTGCFzMdIdH{y*;kS~@A$f= zxTy;_j{NTUr^idaV|n@5yxf`@DSLYg-ky>ins=|A3{UMVxp(FrJK5DY&xGBq^>Lx* z&Cf`sV8hO81OG<=V7_`0=lREPS0?z`TFcR_VQGL*tsTJ(W}fYHUQL z4M0+#@4(Lb{5by_v?yoMIpH;QmQ!5)mY`u{nR^=YkEr2jR7-xrCHjlps_w5J_PFXSD{hvw_KG{bQl95`Sd6QBiRGTUWLAUKb^k+?$rwV z_lfY)_f?wX7hh-zKuJ;Jroe%zR1|6 zr&cP%b!C{dmCt3i6uI`laQ>_N@_{Fd+=eAy=ANZKHd4~D=zzziwbYMoTGMwdQp=Sp Nmp!#(i3g6I>|gknzL)?2 literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/comment.cpython-38.pyc b/views/index/__pycache__/comment.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5538c6a43ce33b33f89dc16b67050653658e85b GIT binary patch literal 2580 zcmdT`OK%iM5T5RN?$b}407`_&a}}_ZhzNut6!TEz0}jF_kJU=6VY{(sJ&#TIEU;*u zL!1MOv=PTdiG&@2gbxuy%7GB&mcPKIuVIP#0bG1aRnOX9qa^ptYHF*is$XA!RXvwV zrMv;pZtP+-E`LB&tQXSo~6j)JP#=ug- z7;bV~$ClX$dLVjy+s8)Pn2w&@>#!|E}H4vr^BTH=qruv(X-%hqDJf$L0hO$53v% z6vT_OOxcNGuy{xC25fe#bhMFeyPgIS-zpppgJl3TX~(Iub)O0mV=%(P22obz#~p!N zeqIFe^!DA&`#(Lsd8_};?F~~|jf8P!MsiVE%uoGi7}%ZwF_`fSG@7CeD;FauMo}P1AWCtK;Hin%P`r-f4HS4rnRp8{HKKuzI>1?-zK6j0 zUwFTRovaHV&+pA$3g(^MJq?W%vzIW^Bap9yN2<*tUK;%21A5tJ9m`c+^h zQTn?vAuBXP?w?R{8iGUO9D`mGCo{|<(9i<{=BaoW+IuKyf&ueS z7qS{CH;!N_TLU&&9|M|QAkM}a7=*p6T zw)X7%I~kspoGu^Y73igG*$RWKiilUiAP%9`VNga=u8L<9F6WZ;+;zxOjb+8mzQ*{AjksMGZ;!jCvs+-b%eiSSe4w7|R+$VY+SI@SHU=uYDo!Svp%USRgBVgKIG z27$M;DrNnb{FsH1HMo&#F|$Q*dxbK)cMfKz78g+Fj xz#5~oO0z=XHiwYW1x(j2?*o{$9r9DSOL-W?BwPwRKhq=miR|@Au>cype*>pMe{KK( literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/notice.cpython-312.pyc b/views/index/__pycache__/notice.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6268d17ff38c42ca1c0297ef8043e54796f83408 GIT binary patch literal 958 zcmZuvK}^&@6rE|iZCO~*>KZjhIDonb%E^PqXiP9hMNr_h*<@382I$gm>r4Sl05vgj z<4I3=gP3?QOCm=-dGq2$goI=QiP1px2H6`YXWFf+iF0`W{XdyE|G$~fnM@k+we{%! z_;(1v50NBGZjkygCrbbU1RdbQJcNQvj^xUDIpVUTxT$<9;)e7Pm5G$WFd zF&ALan$+hZl2?^lEfH)5xERifbdMlRien*B`6dy55FyHiG=d*YV;V5661@avY5M00sOYq-tLyMi|K)-o za`{S;PI`W?YtaCc|CRXR8NTC&mhTtDo6~|_LHJ=ImN)&7>5ffJ2ZCmXk7ZsoY+h;!&^X3@Ia1pIMlE3W77`4O3v_9{9kHv p*q0%MyTIH9Jv*Rt2bc#ckkZwQ)$<$BIFJ;07uIDU9gAtC_Zt+t>=pn3 literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/notice.cpython-38.pyc b/views/index/__pycache__/notice.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..944b340b4c61e8ef5b8589899603cb42a8f24f2e GIT binary patch literal 682 zcmYjOO>fgc5Z(3qE5VV<$AzDe137Yt5CTC#Tq;D$#j<3%-X(GB^_tmDORDr#4hX4I z|3O7EtQTmqc^MZoA<_VN24LZINP4{AC!=vuDKZun#U2;?XIap(PX-??8wQN6CW{L}5g3 zDk*kRhcAm}4Q}l!!E$x}_4oHLSD(&)eLf#E>z9fP%cP!LpBJVW$2OG0EEESHr){M6 zmZCJ;vZAhStbhy1_txNKgVPW0KOj*A;{8f!W22_KfVM+@ZT%a8J2>`t`h1$TpgP8^ zUE`W2*9+BVIC>x;lk1{wGj~~?RSg#(vYu?xu5Dab+T?io0W#?r3-N|@izXEAA>J7e z?0rB1`8z12I8?Ad;i6Pf7zG+U9I>O0f3heVUJK~tr%C@N@eH-@J>Tx1{>#_BUALz5 caiiRIyzwLad{v9bZi{vYNxTGwB`l`@0JyofVE_OC literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/order.cpython-312.pyc b/views/index/__pycache__/order.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..965ea2a8211605ad4db56231f5ff52665179ee55 GIT binary patch literal 3856 zcmb7HZ){W76~FJF{bE1Ie$M{{lY~IQO+zH;?N^I+ZkZ za3~$anvRJycsiOK0kxNnPv|%rjz`afMtI}!V5G7M?E5940{kAI0qG3Nq8JmeB^o!n z10no7(DG|FbQGgL)-{dSgqs!Haqc42C+4vwwLZ(u zI_wLup`M?0R`uT6Je$*GTRSe8sx8e5THUOx8nb9N*c#2PDOoYrXpd|Ctmh`(b7&{f z7z)-O#q?8%BV*|JO>OBv(1<%lkMe{WHZul6aF!y~Lhmz}EEI~Ql4dxXG|s#Gm~F_6 zCiFpSnFuGxFx~x(0%Y;iFCX3dd@*-<;lodF2tn1PR5WhF6_TyRPL5%k*4Rl&3y`2hoLK)wMmJ1McOTO& zBo1b65Elerxr7G2FI}`fJ#uLOaC!{ZPKJ!rsdQf=Y`_v5iD3E}&?Lsf>GUv78Dlt_ z)bw-1%>T~x7?I;q!wf-2;Vs~wMqqpdWCH!eS^vR>OBb#*-E(f9S6gQ~raNXjr#thl z*LRiFojJ#Rb6{q4dUPf=oysR}A1^ic=iCp~=9$2Bpsa2ws#{9x*0S1LRC{kX7u4R8 z+Fw==7S)4=cZLh$oqIB%~sE@b%_y?pDMSngQ_Z)UthyUwR)mP^4uHyRvh^mtt*pgbZLZeabM5G0zKhP++`uW!Q-^I0 zh~lyB#-*$j3)q@kZ~MbLK;K!D+nlZE(5kbk*SuhDo2=?*eKq7TyKM#7(mTJd*^#aB zENbfNy$$-0VhUwMGU<~+q(~~0G?(ZL!LVat>ixx!ZZG}jlSj91-QY3ZL);AH21oex zsAcl)uNQuQ<>8%QJ^JPk#2vwU*wh&m5ye7^WF~PEaD)3kaahoGgJXbEL#Tz^)rCKP zYatY-cxgFi(uFU+di3>|K|h;9!7DvxVNM;5rJWLbwMiY;(>gX&c#H_qq)BAJHk~3O z5t6C1L;zI6^zsuA;2Vn%f=Q$qh!HtzgwDVdsS(i#pV5hw#?*&H$2f(JpaXBF>(G0H zU!Y_=B`;CZ1;n7w6a%y_OwWWktX;tLw$LkPcws{)(6Wq_hN%OS2g>eEMfawXd-KGh zd8a$~`lW2a*>T0pzwya

y{g@y^fgdJ6pm74(?%?kUK79xCe8z~n$#2^5t;zA-=Y zS)iZ+YkkJ_CFJlvucS9S5oQWgttebod?}(pRX0Hy`oK(O+ppSs^i3CrI7l=}gYpk(EAFYrWSKxJ8U zfuL5QSoy5b&(z}~%j`9<*h8)E0)ebnL}~xLr*Z1N$@iv0lc6hv`CTQ?3pxJ2uW80J z?J4`Zi@xss@q(|rI2gZBND5|EL3e{{7(8ehLPHT8BBAKcr5+ta8io{ zs?wt;iX}@xJsLNxv!tL-R7<|9Vzf$4`o=L##q^;A`DmhpJf|ZZM!1EkOll-JgG_G literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/order.cpython-38.pyc b/views/index/__pycache__/order.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5caf9df45267621e9030d6fff95c056eae8adc73 GIT binary patch literal 2176 zcmZvd-ESL35WsKuK76*%juTL!qCiy2hXq6+@mUo_p%v;&T9F{YvSeMn+vJ@4FuUut zj+__5LxmJk@lk<_R2u;z4=AmuDkyLK87tnvQSvYFQfBtjHc(Ew+1Z`B-PxVr&b?cy zlq`5Io?K)XLHiRs`yU57Z@?>m0KqIqVyl5IjY&cqG_e~t!M+_kiQ90E?!;bFXcUa@ z#(q+46pil1rKH>_CqW}H{X$$xs*NhKIA#7KStqQ>N*`P6q%i>_WgOu)FBnU}Drf;) z?H*f|P3+kw8JV-{wOxqSnypjqhux^P67h5TK-g1DJXKLUR8f|;+Hoi)mvy4uo{C~r zCg-zdo*oCk+g>nOK7QuZJ6v|NRC1WmJuMg)+MQpD(nT;&nEo6WQ5Z+7V6opmIo~F@ z{@&w4i|=9ifdp(D_(4)%kI74@2b-V##-Ufk|vcd)# z7MMRGYqs(SHXhdoU2{~Cm02)wIwe-wu;(Bha0t~|ftl4_PjYdJ?cRb%mop51PKBx` zwFU7zXsyGcN;B4KwX;-(Q7Tu<&l=yBiV{ALo=KSY1@5dDfY`qB{m$06+ZQg5Ke@7L zYp0ztuI)rFYKMg?te3TyaJ7`NJPLb}D^b9B3fV%3x0Td(7{}T>8^sEa&CeHG=!+sa z2@l2nAnL9z2>xM@OC`!USOK9u<1KXwg5Nv%O-noiroUf3akSYLnOUOQ?L!1qg^7{vLFuy}GvLK^`k%N$pWna#KPWS0{u8X6JGRQb&n9f<4^Nzdc3AtXQpo8a{ zJ)j*=6$bV?S++!KzVY|I@jL#o2&*{*2fT~NELBqFVK9Qr0{zl4iz z?yx$t#P85fj4Wcod~k&ZE^t{xepC(g$#r5Z4x7wZGE_~?iU~XiSK$TFZaeFxYWEHm z<4-@@{_^VX7hmseZEaF91+L;g5Sv8P?y>=AeDm}1Phb7@%f`-)pLMw{c&NC6Ob0mw zX)jp-BFOXF%c0yP28FxqjW1jt|8_HHPfWt}`NU>){N1&k>)+R>%qNItx1ZDGV=ND# zH~>Ny1@Cg9GSSy|lq&55wH#U3cAA~jHt;5}_UQ_cYvO}olCHs1`;ly|z=dbpk>Lv0 zZdc$O9v31LvhIn8a2@1V97gdNilQ;#iO8UFF%9_L6_)mIVEz01ayk{Kwkh1 z`lJRgw!T|~zIX+^?x`}kLsMlw17&qO=a2z+SX~tD*c~LoMy}qo(!&nqz2hvG#G3>d zfLyz`N%X7_pn|+_F{m{W)*7fiSZ%P@44h#B*f|faZ`g5J2?%pKMHU!#N}!hwJ2+ou zkDV%1q>0s9X&Rn(n6|^%sG3Gh;7t=xpg01ehkT8-JYc zF!fSz_0}Q?l@z?{$(t81)fNgv3xc%httGdfoJq1q!8v^Id+#ydzW42XNhT9Oob822 zqZ<%_A2NxK+9b6>L6!jq7&^d(SqLRp9K}_$YMrZ&=EkzII@g@It7mlx6hI)36=7BA z%7f$2LA60a)(CaW_$4z7as&Bxe$pmWg16s#cz=*E-zzgBQgs*=MM#P;M5v7%dzw(L z-n}ziXv)?VV*=&4wa)^U!7M1%%l`s~;}-#-gMkv&OIpNQv81)M3INb0kCNw`1(zs|+=?9gfLP)3N@dRN3*8)^zJi-3>&*Yftbo%Jt?dv%|6x!uH z8}s}g7qNiQ|CPk$Nzrjb?v@?Fl4aa6dUc3XE657&c)+gX8_^x-p zn143^I`vIIvtxEG%`DC=Ei5iIwDqNla z@Zi(H$AK-gcf;sC(1CHbCImsh)y7Xzu~vSRB9}~gbUcGe!J{bfD5G*So~)0V8AE04 z5L!2dcQk6QFxO!XCyzBsfBDidQEu=K(32w269SHm8{*o8LvGS;k;-?=G6D`%2;m;c k?1A&UpnDfwI*bD)QMp>VunD^k6%F>mnhKQT4O-Xx4b?&CC;$Ke literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/tag.cpython-38.pyc b/views/index/__pycache__/tag.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa973043d8a6bd07ed6602af54db7049963a6d28 GIT binary patch literal 670 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 EAKW}1Y5)KL literal 0 HcmV?d00001 diff --git a/views/index/__pycache__/thing.cpython-38.pyc b/views/index/__pycache__/thing.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcc5428cbe32b15c8539d800888cb01b727b94ac GIT binary patch literal 5309 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 -1: + ids = [c] + + things = Thing.objects.filter(classification_id__in=ids).order_by(order) + + elif tag: + tag = Tag.objects.get(id=tag) + print(tag) + things = tag.thing_set.all().order_by(order) + else: + things = Thing.objects.all().defer('wish').order_by(order) + + serializer = ListThingSerializer(things, many=True) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['GET']) +def detail(request): + try: + pk = request.GET.get('id', -1) + thing = Thing.objects.get(pk=pk) + except Thing.DoesNotExist: + utils.log_error(request, '对象不存在') + return APIResponse(code=1, msg='对象不存在') + + if request.method == 'GET': + serializer = ThingSerializer(thing) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +def increaseWishCount(request): + try: + pk = request.GET.get('id', -1) + thing = Thing.objects.get(pk=pk) + # wish_count加1 + thing.wish_count = thing.wish_count + 1 + thing.save() + except Thing.DoesNotExist: + utils.log_error(request, '对象不存在') + return APIResponse(code=1, msg='对象不存在') + + serializer = ThingSerializer(thing) + return APIResponse(code=0, msg='操作成功', data=serializer.data) + +@api_view(['POST']) +def increaseRecommendCount(request): + try: + pk = request.GET.get('id', -1) + thing = Thing.objects.get(pk=pk) + # recommend_count加1 + thing.recommend_count = thing.recommend_count + 1 + thing.save() + except Thing.DoesNotExist: + utils.log_error(request, '对象不存在') + return APIResponse(code=1, msg='对象不存在') + + serializer = ThingSerializer(thing) + return APIResponse(code=0, msg='操作成功', data=serializer.data) + +@api_view(['POST']) +def addWishUser(request): + try: + username = request.GET.get('username', None) + thingId = request.GET.get('thingId', None) + + if username and thingId: + user = User.objects.get(username=username) + thing = Thing.objects.get(pk=thingId) + + if user not in thing.wish.all(): + thing.wish.add(user) + thing.wish_count += 1 + thing.save() + + except Thing.DoesNotExist: + utils.log_error(request, '操作失败') + return APIResponse(code=1, msg='操作失败') + + serializer = ThingSerializer(thing) + return APIResponse(code=0, msg='操作成功', data=serializer.data) + +@api_view(['POST']) +def removeWishUser(request): + try: + username = request.GET.get('username', None) + thingId = request.GET.get('thingId', None) + + if username and thingId: + user = User.objects.get(username=username) + thing = Thing.objects.get(pk=thingId) + + if user in thing.wish.all(): + thing.wish.remove(user) + thing.wish_count -= 1 + thing.save() + + except Thing.DoesNotExist: + utils.log_error(request, '操作失败') + return APIResponse(code=1, msg='操作失败') + + return APIResponse(code=0, msg='操作成功') + +@api_view(['GET']) +def getWishThingList(request): + try: + username = request.GET.get('username', None) + if username: + user = User.objects.get(username=username) + things = user.wish_things.all() + serializer = ListThingSerializer(things, many=True) + return APIResponse(code=0, msg='操作成功', data=serializer.data) + else: + return APIResponse(code=1, msg='username不能为空') + + except Exception as e: + utils.log_error(request, '操作失败' + str(e)) + return APIResponse(code=1, msg='获取心愿单失败') + + +@api_view(['POST']) +def addCollectUser(request): + try: + username = request.GET.get('username', None) + thingId = request.GET.get('thingId', None) + + if username and thingId: + user = User.objects.get(username=username) + thing = Thing.objects.get(pk=thingId) + + if user not in thing.collect.all(): + thing.collect.add(user) + thing.collect_count += 1 + thing.save() + + except Thing.DoesNotExist: + utils.log_error(request, '操作失败') + return APIResponse(code=1, msg='操作失败') + + serializer = DetailThingSerializer(thing) + return APIResponse(code=0, msg='操作成功', data=serializer.data) + + +@api_view(['POST']) +def removeCollectUser(request): + try: + username = request.GET.get('username', None) + thingId = request.GET.get('thingId', None) + + if username and thingId: + user = User.objects.get(username=username) + thing = Thing.objects.get(pk=thingId) + + if user in thing.collect.all(): + thing.collect.remove(user) + thing.collect_count -= 1 + thing.save() + + except Thing.DoesNotExist: + utils.log_error(request, '操作失败') + return APIResponse(code=1, msg='操作失败') + + return APIResponse(code=0, msg='操作成功') + + +@api_view(['GET']) +def getCollectThingList(request): + try: + username = request.GET.get('username', None) + if username: + user = User.objects.get(username=username) + things = user.collect_things.all() + serializer = ListThingSerializer(things, many=True) + return APIResponse(code=0, msg='操作成功', data=serializer.data) + else: + return APIResponse(code=1, msg='username不能为空') + + except Exception as e: + utils.log_error(request, '操作失败' + str(e)) + return APIResponse(code=1, msg='获取收藏失败') + + diff --git a/views/index/user.py b/views/index/user.py new file mode 100644 index 0000000..031c918 --- /dev/null +++ b/views/index/user.py @@ -0,0 +1,162 @@ +# Create your views here. +import datetime + +from rest_framework.decorators import api_view, authentication_classes + +from myapp import utils +from myapp.auth.authentication import TokenAuthtication +from myapp.handler import APIResponse +from myapp.models import User +from myapp.serializers import UserSerializer, LoginLogSerializer +from myapp.utils import md5value + + +def make_login_log(request): + try: + username = request.data['username'] + data = { + "username": username, + "ip": utils.get_ip(request), + "ua": utils.get_ua(request) + } + serializer = LoginLogSerializer(data=data) + if serializer.is_valid(): + serializer.save() + else: + print(serializer.errors) + except Exception as e: + print(e) + + +@api_view(['POST']) +def login(request): + username = request.data['username'] + password = utils.md5value(request.data['password']) + + users = User.objects.filter(username=username, password=password) + if len(users) > 0: + user = users[0] + + if user.role in ['1', '3']: + return APIResponse(code=1, msg='该帐号为后台管理员帐号') + + data = { + 'username': username, + 'password': password, + 'token': md5value(username) # 生成令牌 + } + serializer = UserSerializer(user, data=data) + if serializer.is_valid(): + serializer.save() + make_login_log(request) + return APIResponse(code=0, msg='登录成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='用户名或密码错误') + + +@api_view(['POST']) +def register(request): + print(request.data) + username = request.data.get('username', None) + password = request.data.get('password', None) + repassword = request.data.get('repassword', None) + if not username or not password or not repassword: + return APIResponse(code=1, msg='用户名或密码不能为空') + if password != repassword: + return APIResponse(code=1, msg='密码不一致') + users = User.objects.filter(username=username) + if len(users) > 0: + return APIResponse(code=1, msg='该用户名已存在') + + data = { + 'username': username, + 'password': password, + 'role': 2, # 角色2 + 'status': 0, + } + data.update({'password': utils.md5value(request.data['password'])}) + serializer = UserSerializer(data=data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='创建成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='创建失败') + + +@api_view(['GET']) +def info(request): + if request.method == 'GET': + pk = request.GET.get('id', -1) + user = User.objects.get(pk=pk) + serializer = UserSerializer(user) + return APIResponse(code=0, msg='查询成功', data=serializer.data) + + +@api_view(['POST']) +@authentication_classes([TokenAuthtication]) +def update(request): + try: + pk = request.GET.get('id', -1) + user = User.objects.get(pk=pk) + except User.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + data = request.data.copy() + if 'username' in data.keys(): + del data['username'] + if 'password' in data.keys(): + del data['password'] + if 'role' in data.keys(): + del data['role'] + serializer = UserSerializer(user, data=data) + print(serializer.is_valid()) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='更新失败') + + +@api_view(['POST']) +@authentication_classes([TokenAuthtication]) +def updatePwd(request): + + try: + pk = request.GET.get('id', -1) + user = User.objects.get(pk=pk) + except User.DoesNotExist: + return APIResponse(code=1, msg='对象不存在') + + print(user.role) + if user.role != '2': + return APIResponse(code=1, msg='参数非法') + + password = request.data.get('password', None) + newPassword1 = request.data.get('newPassword1', None) + newPassword2 = request.data.get('newPassword2', None) + + if not password or not newPassword1 or not newPassword2: + return APIResponse(code=1, msg='不能为空') + + if user.password != utils.md5value(password): + return APIResponse(code=1, msg='原密码不正确') + + if newPassword1 != newPassword2: + return APIResponse(code=1, msg='两次密码不一致') + + data = request.data.copy() + data.update({'password': utils.md5value(newPassword1)}) + serializer = UserSerializer(user, data=data) + if serializer.is_valid(): + serializer.save() + return APIResponse(code=0, msg='更新成功', data=serializer.data) + else: + print(serializer.errors) + + return APIResponse(code=1, msg='更新失败') \ No newline at end of file