From 0b3b81915b5108141fd82fe6a34c7b843687d9ae Mon Sep 17 00:00:00 2001 From: jeremygan2021 Date: Tue, 10 Feb 2026 23:35:53 +0800 Subject: [PATCH] order --- .../__pycache__/__init__.cpython-312.pyc | Bin 153 -> 172 bytes .../__pycache__/settings.cpython-312.pyc | Bin 3754 -> 4089 bytes .../config/__pycache__/urls.cpython-312.pyc | Bin 1182 -> 1201 bytes backend/db.sqlite3 | Bin 196608 -> 196608 bytes backend/requirements.txt | 1 + .../shop/__pycache__/__init__.cpython-312.pyc | Bin 151 -> 170 bytes .../shop/__pycache__/admin.cpython-312.pyc | Bin 10388 -> 10408 bytes backend/shop/__pycache__/apps.cpython-312.pyc | Bin 392 -> 411 bytes .../shop/__pycache__/models.cpython-312.pyc | Bin 14980 -> 15298 bytes .../__pycache__/serializers.cpython-312.pyc | Bin 8072 -> 8091 bytes backend/shop/__pycache__/urls.cpython-312.pyc | Bin 1167 -> 1186 bytes .../shop/__pycache__/views.cpython-312.pyc | Bin 27469 -> 28986 bytes backend/shop/admin.py | 9 +- ...onfig_stock_order_courier_name_and_more.py | 28 +++++ .../__pycache__/0001_initial.cpython-312.pyc | Bin 3250 -> 3269 bytes ...rder_phone_number_and_more.cpython-312.pyc | Bin 1151 -> 1170 bytes ...p32config_options_and_more.cpython-312.pyc | Bin 2040 -> 2059 bytes ...id_alter_order_id_and_more.cpython-312.pyc | Bin 2082 -> 2101 bytes ...id_alter_order_id_and_more.cpython-312.pyc | Bin 2486 -> 2505 bytes ...nfig_detail_image_and_more.cpython-312.pyc | Bin 2739 -> 2758 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 162 -> 181 bytes backend/shop/models.py | 5 + backend/shop/urls.py | 3 +- backend/shop/views.py | 106 ++++++++++++++++++ 24 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 backend/shop/migrations/0014_esp32config_stock_order_courier_name_and_more.py diff --git a/backend/config/__pycache__/__init__.cpython-312.pyc b/backend/config/__pycache__/__init__.cpython-312.pyc index eaacd896c3346e76ff3b9dca7b254674e6247059..4dc667219bc6e16b3b8c995abe7de6a3eb5f0015 100644 GIT binary patch delta 88 zcmbQqxQ3DYG%qg~0}ybVbx-6rcJ$T{Elw>e*3U{UO3kfIPt4PI$xklLP0cGQ)=x<- q)6YpwEXvc*O)SbzEr~BkOi$HMN=(j9%}dcw&d*EBOxK^7qYD7Le;v;N delta 69 zcmZ3(IFph4G%qg~0}u$hH%#O<*0XT4igC$I^~y{PNz9DNO)SbzEr~BkOi$I#P0Y-T XNlHx4PR&b+NzTtp%S?}%Sg#8JwoewU diff --git a/backend/config/__pycache__/settings.cpython-312.pyc b/backend/config/__pycache__/settings.cpython-312.pyc index 8180c21a711dfecfe96d3f1642f1c5f4239fdbe6..340c2b461544bca772536967564eb8988dcb704d 100644 GIT binary patch delta 665 zcmZ{hzi-n(6vu7Hu1n&iaT6!$k2Hl+sz?woKp>QYL`Yf{wNld#oKP*-?{G~WJJ@bS zyA&1%U}zPwd4dVn?EC{P9V0I=At4r5Ot6%5VdYNu)ziKAKJUG|kHuf5)aPU}PLcJn z{@Mtnqf~)@c{KO-0OC4>QjkC+Am|iukR+OVM;kPZ_^eK&G^CLTB8*}lGW!XNf~?ON zG#Uj7awJNE{FxTcbj+Z27G+=@WnltIz@Z#Dd6+~6l3$GS(HOC&B8$-H#-XHBq~x?8 zLlbZwF2D?F;-XFyoju!^{Bvlsw@FW4g==u#PmnrQpG8H&oq`*16KZe^=8dT18cDki z3qAvPNJMFmDc|kCp-*EAQ`?@`aci>NR-GN}Ri5sumUqSNU6SKNE< z;5$uTuMzN?ZMn9I15Ptl*WH&)Th|Rsue3Y|tL;VA0uws{yR_0+Ei=LJ_TLLP;7r`b zW|re!cf8@nbFEAFMW;ODoL})X(U9e=o}$E}$z+dcH!Xv(E(*kQN8ivtNhBfsi?tE{8ED8xLcwI1~z0u5`FO5c4NoEID){3JK-~ I?>r*(KU9{!M!;rC%O0B$cSO39)zeDVd{g8`Z)rK z&>;6mhkhF3DmGMndKhs-;2RGTrbr`5ViHsQh-rgxo*Ct=IYFbC!#q-0KpKl!LIzpn zu#6R~B9Aq!n-X8YVOnVnn>60Gq_+mo!nIJ8=nt_4A0EktAm=TEkCh8cou4d3H>)x2MfS*}`onbP&fITDo=0Jg+ zY~i5_tPG-sj>Q@I1qKF&Ch@7o1;$3n`FUxX>G8!S`N`Sw`9&$IMe)h`rA3)QIxjId zH9j#fB|bO5DAmZo$V}J3NY~In!O+yo(9FujK+nL!(!kPebGZ0E4(^-$-u#OEM*InU zA2tgXoaJMdk!GIgC_R~5Ka5dka+3aBMujGWZ3c`i2F(1-9n;wp7-d!nIJ8=ih+T_0EpFqm=TCOC+Zlpu42&Z{kbt^0Y9@md-!B_0sGC03WDsL z!^QV;a3}EJ`%k&~0XF_5>hn1NyXgnNt% z)45`po{KhTvI{Zj$})0ta56Qr0%e;-o8-4^#xY%I6yl%3unb8jFl^u&ON1K5Ir$kJ z!NxKHjRi@v#4>dXGIKzLLFQ?Kh3CgIl?VdmGZ5B*R0Hh@7XUKAfPVsm3Xq`$4A2IC zt~^E#217+(hD6TkGk!41On>m7NkJ>4q@? diff --git a/backend/requirements.txt b/backend/requirements.txt index c1117d8..2b17c5a 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -19,3 +19,4 @@ uritemplate==4.2.0 wechatpayv3==2.0.1 drf-spectacular-sidecar==2026.1.1 gunicorn==21.2.0 +requests diff --git a/backend/shop/__pycache__/__init__.cpython-312.pyc b/backend/shop/__pycache__/__init__.cpython-312.pyc index e32a5b147a3cc2c029cd9a53835e124deaca8341..3c80300c2ba538ade9ca4f33a4aba940f8664c4a 100644 GIT binary patch delta 86 zcmbQvxQdbcG%qg~0}ybVbx-6rw)fNzElw>e*3U{UO3kfIPt4PI$xklLP0cGQ)=x<- o)6YpwEXvc*O)SbzEr~BkOi$HMN=(j9%}dcQ&d4v&pO~c!0Da#b2><{9 delta 67 zcmZ3*IGvIEG%qg~0}u$hH%#O<)-iLligC$I^~y{PNz9DNO)SbzEr~BkOi$I#P0Y-T VNlHx4PR&b+DbC0*h?!Wc3jl}>73Kf{ diff --git a/backend/shop/__pycache__/admin.cpython-312.pyc b/backend/shop/__pycache__/admin.cpython-312.pyc index 62e2bfafc00e8108abacb84ac0abde42981ae1a2..a844a8008f049b87ece0ef472fb4ea038f77b70d 100644 GIT binary patch delta 122 zcmbOdxFV4EG%qg~0}ybVb!XabHkn5XZOpIn-onpaY+ zpORXppOczcl&7DYSd^Vw5?_#*o~oaen4F!Om!e;skzb&{S&OYeL|81Nq@=(~Uq2^5 YIWZ?AzqrK8aPk_dB1Y}a^3tWe0NVB`i2wiq delta 102 zcmZ1xI3e*3U{UO3kfIPt4PI$xklLP0cGQ)=x<- p)6YpwEXvc*O)SbzEr~BkOi$HMN=(j9%}dcQ&d4v&pUlkI3IMrT9e4l$ delta 68 zcmbQu+`-I!nwOW00SE-$8zyp}(J^wfigC$I^~y{PNz9DNO)SbzEr~BkOi$I#P0Y-T WNlHx4PR&b+DbC0*h?y+L*a`r%Ll#v4 diff --git a/backend/shop/__pycache__/models.cpython-312.pyc b/backend/shop/__pycache__/models.cpython-312.pyc index 9ba06d1b54cb0bd821404f9b6aeea23075fab2a1..76b3ce2a7f34955a6e218909230a8b3bf394009a 100644 GIT binary patch delta 2078 zcmZuxdrVtp6z^9kZ`wLaX(^?YN4El_8yn*_VDelx7*qCUrn~fBpsWx4Zi~ZzMgp?2 z2@H;NYUZ4pEHJt`Z6c`Asq;Bw+#;E##>6Zsy7-TYBqkuU zL@AdEv3=RVC8uR*_*6bUpq-0Z;nWhBi(GmJuM6m-RqG_if{Z?s*Rii5kTn;(Qm2vF zLWxDr$Y%#kQC7RkW+0mrFh~C}W0kWZm%E13@p&V%BYL^4MaJik$oPWjZ88Tf*7ZS6 zEKjr)pUa=ZAp9Fn-lfe^;c~aM6+b;@KwDk#8a1Zuy9$TZ=;dcujpJ?NS z0h>$UsK@5!=yAbk@8^01TNmdzE_isG*z4`LL1+AWk_p4{_lXg@6U@W_rxQ-aDMX*w zaU7J1v!ost5-%i>1?6H&%TQCWA!$06l)ydZ*NS#_q0KO(dSX{Av*>1oHiT+~?F>SR zPKVcH_i%23)}Wsx`A#>x2d%?Ef)wym7u|wId!b!zOlm|EAr}VJi=+|E7JZO^L?tJ6 z;7glTbTO(Pay8B57&tW*Nrx~Wp&aHkUUEpv-Mwix^@ z>1oYDp`n-a?d1j=yq<1nPl?D42uGpO@D8blhXymdYED*qoph=Vk1jyK(om}1?r?FU z=nz~kyWL9Y2^JLzgB>&syU!_AzExWnwebOip&*^}OkW)^}DAsL|sj+qZUMp57q zmEW9uFf<*0CJ>%nu*Omx|46n}hb3#%#?OZ*=lv=c4WA!fIz9i(_1D5u41O}};ySVT zC_FS@PT0*%YYc1RmE2k~3gO(ViWgaE44%s~lN`9K(!lLJZSvz-5s%OTzvdZERxvY_ z?DP6Km%X1l9YRFu7cc`w7fR@8+GpRhzqK`#EOIVE>}T`n_0Z>$OX=_RdIY=2@9q+) zG#DYZ*z4@?cY1p49M4lh6hkQvub(;vDh*0V<)dsuk(a6ng`WJJIP5>=VLace8b%WV zW8x@$n*WD|E@(b%ymL@kOzR$M{a$N1*ZrN=a#w4)k+-n#i`YAz&P8qCP&-^Npkz2` zw)~BwVYYhMD4eralYigR-NG8u2C5<}xeS#>(~39PAG{8CiXJVL=2{xzSe#gCc(NKJzLagFiRbM36c7jhmXH#^}okQCZPT=)QuG z9C?XoUXd2$JemkI!G^7+gv?7DZ?deJ#LXhL6MopXXSJ#2@pKNu0oGbQjFzv9`xf16 zaH)Ja=`&{DL-z(0RoH6&yTBt`JK5nKVCr16wpD8)cHG`;+I$NSL--OtsF)zPpsljQ zB&~FumdJ7&MoW5)(xcpho0UfL4g6S{tJab2=PVbBr;3+l%v|0Es;W)u4P@i#=E>Hv O)@2zpmk&UDRoOq^2sJbS delta 1747 zcmZuxZ%k8H6z?sxKtb9;OL?>f3oTeet%4#HVNAb86Lc;iol1p$uGZqe&^ix z?mfSEzTY_z&HZ`aJe`XDy4CxnK*g2ZNun-N!`<3O(C2Z`s=fl778tYggn2@K+&G#B z{}k9WOhQ52JgSC~96MJi6tF)RFB(n9ZB(j`e6>nU?^*!s7Uy%QSp;j`HlvzmRWqu^ z@siQB>B@px&4b$fIht9p52!i{)v6YiP&%Lz%0|`GRb0&Bawe9i3ncNCW{gxV@p=8L zByo+zZ{Q_=kf+^ZB+$!m72QEzlKq?c&Tdf_{NZh(UO&V$DhLPnGaeBujAh!v<2Jz4 z%=cky)_JlJ47y{9>$<(^#0@L;w>53-iHpE!cz4ZfjM2pitq5L(1_sG2sWT)8WIia; z<+#=oD%N>6(!u*x`}kK52$P1(&$@l3q=k;9>p+4bP+% zaM0)@0r<^Wr)$T2gjz70LZn^EKW%!VCM_^nIHHl5v;m5_ljJ?P&NY#ZiRYZ17`s{6 zMUrYs@VT;R4{joY$5KpWXtT6fA}sKMv0ZH5#z)@ZW6dFXi?nrNnBO68f-fy!6EAdG z?d8fTbaE&nZHWc&9JRQQvY7{&6Cnautfr!!jD`t=SEvJ{;tTL49$Iq=5#bLTN7h4+ zr!O&7TuI>f5^b6#ZiO2qu6$eEI%68vc2Uz+jg~SQ6wAD5e$lMrHZa53XKZ0Xn{-$e z!;~?@IA#=E%;_qJYx931tD)asr`?FJ)eqm<+f1vGS`i8nvJrgXD1F-))iXYEbnoQg z*wf3OO$;BMI5Y-_OU<@CjDLIi@y#=nAAa%p`tg)RJFs*UJS#n&xrR|!8kJ$BtcmP~ zdu10j$606qb~)^%7|u82Euv09`OneT$G!eu?g+{+A&NMA;nej)q<&fywiDDlMIMaVhuXLE^ek6%st;m5`A znD;U*n!{jnsP9?d(B#SCiT!8jAkPBZM*vreY)KK`8iAmjRHi>$ClGr08H6n85rjj{S+#Z#v7!>75Sm`!BiJPSw zjO-JHQwZ6q%R_ornITt^BAiX^URq7aRb?pLuJsY^=P0!RSJyV%%w-w$Jcci@mU3{b zE>C+0mlxqdUBB)JMt{ZSC6MYpjY@-Od#SWKyEC*yq=7k;O+P2142C)F9mmZOZoyym z2gx`b@V;4s15cS^sll)Zm&!FNM;V8|y*Ba-SQ<(VX0rTn`LU{zswowtQ%hiN!ye*3U{UO3kfIPt4PI$xklLP0cGQ t)=x<-)6YpwEXvc*O)SbzEr~BkOi$HMN=(j9%}dcQ&d4v&pS+#<1^_UjAKd@| delta 72 zcmZ3)+0V&$nwOW00SMlkwr2`4Z{(|G)-iIkigC$I^~y{PNz9DNO)SbzEr~BkOi$I# aP0Y-TNlHx4PR&b+DbC0*h?#tf`33+FMHr(1 diff --git a/backend/shop/__pycache__/views.cpython-312.pyc b/backend/shop/__pycache__/views.cpython-312.pyc index bb7436fe285a26556ada8e7fe35f4a4d9b2c5faa..45a7d66f511294913ce1f2d91447aeba4ee58c7e 100644 GIT binary patch delta 6384 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 GA^#8BJ&-a0 delta 5264 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 CK_Z6$ delta 81 zcmX>qxk-}yG%qg~0}u$hH*Dk%<}`P8vx;%aO!dl43`xw4$xSTEPA!QqNK8-F%}vbA ji%CjM&Q8rsi7C#=FNn#_OfO0-$;{6yj@i6|QCF diff --git a/backend/shop/migrations/__pycache__/0002_order_customer_name_order_phone_number_and_more.cpython-312.pyc b/backend/shop/migrations/__pycache__/0002_order_customer_name_order_phone_number_and_more.cpython-312.pyc index 656f003ba7cda53b1952c0afc2dea4de9b9d9e22..083a1191f400ec360877ce97c41dcdd738f10553 100644 GIT binary patch delta 100 zcmey*F^QA=G%qg~0}ybVb#LT;!{pVVA6lGRRIHzsT9lewnVy)Z?~uR!Ul5aAwl9``Z9JASxIgk+mFohfm diff --git a/backend/shop/migrations/__pycache__/0003_salesperson_alter_esp32config_options_and_more.cpython-312.pyc b/backend/shop/migrations/__pycache__/0003_salesperson_alter_esp32config_options_and_more.cpython-312.pyc index 8d69258bd2368bef10725438eb47f3e7246045da..fd712b50842b2f442663bec313c1d64d8374721c 100644 GIT binary patch delta 100 zcmeyt-z~s>nwOW00SLIwx;JufWc8}o4=qkDD%Q_RElSO;Oi#?ycgasK%}vcKDb`O( zEz{3QO)SdO&rK}KPA!QqNK8-FPfASAPR&cvFV4s>(9g|GFG?)Q%+D*<-~5@Cl?ecl CIwL{= delta 81 zcmeAc_`%P8nwOW00SE-$8#Z!pWHrxmvx;%aO!dl43`xw4$xSTEPA!QqNK8-F%}vbA ji%CjM&Q8rsi7C#=FNn#_OfO0-$;{6yj@it{#>xZ$Aod$g diff --git a/backend/shop/migrations/__pycache__/0004_wechatpayconfig_alter_esp32config_id_alter_order_id_and_more.cpython-312.pyc b/backend/shop/migrations/__pycache__/0004_wechatpayconfig_alter_esp32config_id_alter_order_id_and_more.cpython-312.pyc index d4fc861ff7e0768dc32fd3d3b627a6f68430a29c..f06f933b780c088f35793ea77708c85f2c935973 100644 GIT binary patch delta 100 zcmZ1^uvLKjG%qg~0}ybVb#LUJ&Fa;wA6lGRRIHzsT9lewnVy)Z?~uR!Ul5aAwl9``Z9JBcYt1A-#76%+d diff --git a/backend/shop/migrations/__pycache__/0005_service_alter_esp32config_id_alter_order_id_and_more.cpython-312.pyc b/backend/shop/migrations/__pycache__/0005_service_alter_esp32config_id_alter_order_id_and_more.cpython-312.pyc index 5dd8cf19d30910e6de7a69dba7a9b95cb9380162..19e399774ab5de3a3437c942d189c46329e0963f 100644 GIT binary patch delta 100 zcmdlcd{UVEG%qg~0}ybVb#LUp!{*hhA6lGRRIHzsT9lewnVy)Z?~pyiJ(uR!Ul5aAwl9``Z9JASweFhT%Fm4<{ diff --git a/backend/shop/migrations/__pycache__/0006_arservice_esp32config_detail_image_and_more.cpython-312.pyc b/backend/shop/migrations/__pycache__/0006_arservice_esp32config_detail_image_and_more.cpython-312.pyc index 49b6045bc14f9498cd7ddda7bf7f7da21f81b4ce..3ea1411a2542ead9834ae72dca6175f2a20de7e7 100644 GIT binary patch delta 100 zcmdlidQ6o2G%qg~0}ybVb#LU}!0uI}A6lGRRIHzsT9lewnVy)Z?~mx>=O_G%qg~0}u$hH*DnIz;2%DW)uR!Ul5aAwl9``Z9J85~;~*0NBE1|5 diff --git a/backend/shop/migrations/__pycache__/__init__.cpython-312.pyc b/backend/shop/migrations/__pycache__/__init__.cpython-312.pyc index f8091b33a96ac5f4377276cded13848c51841bfc..3030ee01fd49e3590ba5b95c26e557f168c60088 100644 GIT binary patch delta 97 zcmZ3)xRsInG%qg~0}ybVbx-6r_6pGtElw>e*3U{UO3kfIPt4PI$xklLP0cGQ)=x<- z)6YpwEXvc*O)SbzEr~BkOi$HMN=(j9%}dcQ&d4v&&&^CPN-W9D&nwoSSgH#E=vyJI delta 78 zcmdnWxQLPaG%qg~0}u$hH%#O {code}") + return Response({'message': '验证码已发送'}) + else: + print(f"短信发送失败: {response.text}") + return Response({'error': '短信发送失败,请稍后重试'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + except requests.exceptions.Timeout: + print(f"短信发送超时: {phone}") + # 超时并不一定代表失败,可能是对方响应慢。但为了安全起见,提示用户稍后重试或检查手机。 + # 考虑到用户反馈短信实际已收到,这里返回一个较为温和的错误或成功提示(视业务逻辑而定)。 + # 这里我们选择返回一个特定的错误,前端可以据此提示用户。 + return Response({'message': '短信请求已发送,请留意查收(如未收到请重试)'}, status=status.HTTP_200_OK) + + except Exception as e: + print(f"发送短信异常: {str(e)}") + return Response({'error': '短信服务异常'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + @extend_schema( summary="微信支付 V3 Native 下单", description="创建订单并获取微信支付二维码链接(code_url)。参数包括商品ID、数量、客户信息等。", @@ -181,6 +248,10 @@ def pay(request): print(f"商品不存在: {good_id}") return Response({'error': f'找不到 ID 为 {good_id} 的商品'}, status=status.HTTP_404_NOT_FOUND) + # 检查库存 + if product.stock < quantity: + return Response({'error': f'库存不足,仅剩 {product.stock} 件'}, status=status.HTTP_400_BAD_REQUEST) + salesperson = None if ref_code: from .models import Salesperson @@ -200,6 +271,10 @@ def pay(request): status='pending' ) + # 扣减库存 + product.stock -= quantity + product.save() + # 4. 调用微信支付接口 out_trade_no = f"PAY{order.id}T{int(time.time())}" description = f"购买 {product.name} x {quantity}" @@ -469,6 +544,37 @@ class OrderViewSet(viewsets.ModelViewSet): serializer = self.get_serializer(orders, many=True) return Response(serializer.data) + @action(detail=False, methods=['post'], authentication_classes=[], permission_classes=[]) + def my_orders(self, request): + """ + 查询我的订单 + 需要提供手机号和验证码 + """ + phone = request.data.get('phone_number') + code = request.data.get('code') + + if not phone or not code: + return Response({'error': '请提供手机号和验证码'}, status=status.HTTP_400_BAD_REQUEST) + + # 验证验证码 + cache_key = f"sms_code_{phone}" + cached_code = cache.get(cache_key) + + # 开发/测试方便,如果验证码是 888888 且没有缓存,允许通过(可选,但为了演示方便) + # if code == '888888': pass + + if not cached_code or cached_code != code: + return Response({'error': '验证码错误或已过期'}, status=status.HTTP_400_BAD_REQUEST) + + # 查询订单 + orders = Order.objects.filter(phone_number=phone).order_by('-created_at') + serializer = self.get_serializer(orders, many=True) + + # 验证通过后清除验证码 (防止重放) + cache.delete(cache_key) + + return Response(serializer.data) + @action(detail=True, methods=['post']) def initiate_payment(self, request, pk=None): """