From 5232ab99604fb536e0cc0215a37a44ca44a722e8 Mon Sep 17 00:00:00 2001 From: jeremygan2021 Date: Wed, 11 Feb 2026 00:19:33 +0800 Subject: [PATCH] sale --- backend/db.sqlite3 | Bin 196608 -> 208896 bytes .../shop/__pycache__/admin.cpython-312.pyc | Bin 10408 -> 10514 bytes .../shop/__pycache__/models.cpython-312.pyc | Bin 15298 -> 17642 bytes backend/shop/__pycache__/urls.cpython-312.pyc | Bin 1186 -> 1269 bytes .../shop/__pycache__/views.cpython-312.pyc | Bin 28986 -> 33280 bytes backend/shop/admin.py | 26 ++++- ...15_esp32config_commission_rate_and_more.py | 50 +++++++++ backend/shop/models.py | 31 ++++++ backend/shop/serializers.py | 18 +++- backend/shop/views.py | 97 ++++++++++++------ 10 files changed, 183 insertions(+), 39 deletions(-) create mode 100644 backend/shop/migrations/0015_esp32config_commission_rate_and_more.py diff --git a/backend/db.sqlite3 b/backend/db.sqlite3 index 5e31f0f8289345d7c1be4e70a50d3d289bc63d3c..9de3983a3f44727c5d8a34fa9a4a6b0b9a96b5cc 100644 GIT binary patch delta 1786 zcma)6Urbw77(eIq&+Wa?dw@|2E)BOeY&2V;7bs9D0yDuSB8+S#MrD`V-aDw47Fvcz zAE3w-VT+JzPPRBT?r9GWN8P$TkSso!m^sH5lNlf8OmvP17q`Ud!$>^$R)kt+yvaQ| z`F-E-_x-+;bH1sm!l^rj3plJ;Hni#FG3&o;G!b4IhHZl@UB*L+%6qmem{ntkU3NwGvW7 zj?fBfJQ0hQI#R*fY8Xh(*Y1Zn^=<8*3MWS$Vty6i`}hZZ6|dlr@jPzlSJP$QOT4|z zXxj}nnN4Gn*bq+t@{|J_0%k77bc|WdADJU&znP=$&6y@W0TX~?6P^gGuWspw(w>&1 zf`$q|t(;kVd-2}6&wgHcUu>o6zE-TL5tTNaQ%56Y@mxwvmJ%A4qeK6uXq;>yhqK2| zIki44D@uM13g#rIzwT;g4FPU7#T*#36jT-%xixMz?Gz4hljTMz!fl!hJYj@BxNRG) z+0b@&TkJ+y3-ew1b=<0-VM2{hghOg9uBh?mbnlB7#ti}fbc$IWv+zs&S^f-vnp$)4 zVQ!unza9`igF3 zDrV7Tl=*!g6~WAG2!4e!?+(GE&l@m*oiJCR1M$~st+Tw{hK<0sJMU&>?tTLW*|-Am z3cZSH%ymKwsI2H@7(i~dBe&3g`K0!pYJczbAD=l_`iAyEj0HCVUt*mrykBsWs((>n zo37wWz;g}=S(ZumS(6C>EEckG8w!Mb3EeBHV2eSg9!4}wB`m}+faXd}mMm^zQPQ2o zKO8_4wpW-^;Bi1!!%b9f+BRKj$y6Uk-$71$01!U{_)!LSpoiFKFaY-AAcBIEMyy~T zu(-`m!+Cs&|J=%QSCN~WgA0}$;33$zxF~cdJwe7Ui!j+AjwxpoYII!l6Aacj1sjw`-49J+ zH>TGv-Hz+OS(+QNq{1@WKZ-8*o2CKA?(x85ZNxE;ZWZqpT$@d4gO&&iv}2VHVMU6l z6KZ4wEHh_i$fX%{F!Sd$a+&HI2N}C4!nf?>a*&QzZN_e@(J_~gh-C2?+F{MfN_7_c z%<@R=Xmp%76=*Z*bqSW?@y{S*R{L cb3@?~IU@A*9uj)`ySv>P_5}JP{>dHhUrC`wG5`Po delta 597 zcmX9(Ur19?96rBuw|jQ(-92ZQ%{H;&onNGJ8f=uE|*bTryum^J{m#-_;G_UseP8kfNiWFaV__*RSO=2zjjOO)xBS3V+f=)Q1wg zDi*3ZU_lQq=q}HH+Cy=!d6$0BgC_!4h#y76KzC@j$jaB`>z$@v{2rbqF&GiejWkq6 z-rMRA)vvs!Wlt?hyGQUZKER%86jjZB--2>0c#Z_4QMi+`-WG5p9Iz5o*zd3+-T>#( zP2Avi{w84_%bneF@J!T-j6leGSit*~+~CPwXFhGU+09c_sS^0WvQy=;)8Vef88@^<2e%Y3C? zOSdp9-HO--FZmkIjdFX+m{&%ujq!D(#(D9&QPbRb{U~4Y)L@UVd6!)@nrnJmxB?pT zzY`CvGWP0xXc7>9_+f0|11J#~lUiWFR0Ky2JR}R6NC4gzY|{lXBaHAst!b&lk8%Tp zi|$1^4`D}CAet4x6;nNFX8w{CKf_K)TWV2ZEg^@Xt>_3j2wBB%$O*_4H<5N&RWf94 zXQm!CwW9YFgQRA#*(NI{VWxRd-^Lh=kemx__77!FOY zXg_95)`Ud4m21W4R=8CDp0q;RFdIJW3~;kzj?HKAaXwxoJJma#0wm zD}6yRK17XqP(_3+@o8tdl$eL5c`eVhaf| z1KVQs(T4~nprv z?F-|HepY-Ky^r9T-CURH=o!D7n3_@3`#AG}L9u=8jHf&M(l<}02fEpY;&PPucxV6E z(3vR{p(8Bra%RD-f*DZd$f>@CMK&Y;JC=7ahIr0yse|Ew>Z?{|a;d@ZSWT9&U&I8x zjxv2|UOtytJ9(h*z$?cf-^Y?=wHT&GCg?Tjs`OVWzm0O#l@Fy<|F@%@wJaF+#R9@| d`YN?>_Eu6-NVpT`2^AYAG%9t`H#JjApI=C1E)M_z delta 894 zcmY+C-Ahwp9LM+U<@hp>b55IEYs|S#)KYr&4lzpr`bW;V8Hy73_)-Gsxgew2qFrVmOgF-1(L=~&v2$NHAu}*%y+kfTL(>Ox1-`S~rZ+37ww6jp_ zwvs&f+(+7H(5OP-&S{=OG0U+8O$8%@9HwG2B_^c3vD285Lu6sW?c^p(607QD_EwXk6b*(V5h}>Cn*MbuS6V8Rsx}r&Yj@b4Z9$LMO144pddUU^EKSx; z?0|U7etC@Hg65;;JZyNo!0Kz}8+kLAKTbU?KsTYww{BWxlAT_H)}!|bxYk&m`lQuY ks@}vVOt&5&?~1ot2Z+r=xU2TEhAm~CMr-|{WlHV$8^>}1k^lez diff --git a/backend/shop/__pycache__/models.cpython-312.pyc b/backend/shop/__pycache__/models.cpython-312.pyc index 76b3ce2a7f34955a6e218909230a8b3bf394009a..2bc2a56609bd16bbd7e391a390d3264f835fc118 100644 GIT binary patch delta 5224 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 X*HnDAq`72Rf$iaZ>UesC3itj$_^F44 delta 3379 zcmaJ^3rw5W75;x?j2}2a0AphyHV=oNS4c>p;gyD0l9musAg?ibf9)UY%&%VCtY)jo zRMy5xNkZ?EsOy@gom2%uvuu_cO;s0lof@^1x>nPw^smxs(n!aqNn1*_P1CfUbAS9; zW)Jj#+N)ti{peZGLjB?q^D4dP7>m zqzz1pvPyT=%9fO7-TFX%9ZFD_v>+rWC3)CIz%SHC z|EYh2{>E^Dcf_aiFRBuo;tRTAJG})~zKWhGXyXNXuHejW8<@zsVNcjAk!m#O0c>ou z1Q(n&jgo*n;tCH*VmLyi7N;{5CQfGyJzUtxJLnawgHanw{hjsBDKXR01&1-6^X(oqwmQ=|ipcPKoux?wD3Nrs5$}x`#lYv?5?cWja+< zJ~xbAoQ)hr=tAfQkaZqc!0+^nK8f^TU(fm;pExa%Jvg9c0}9^#w>2y(12oubQN6}NYCqkqaqCwM$qdrD^C7qNEVqo1Tbq&+L$p9B zq>Uxl=&jPH_sptn^)fFADq@2LWVI^*Ud$Mv;xW-Hg@O_Z1^kKV?4jQ@IaqXd(vMBM z<^-4{qyHZVK_7e}BLMop8vVcRBds;v@%dRDuejR=#^h@NvT;BROXD7&G~|)IZdval zkTz1Y+bM>#JM8@q&%O%PNn1NYD`<^vD!_zP5@F(B)byUqf%#I&4@8NCaTE z#LVGxE!tP#B6>C^L_Y>~IMN zJxl-5)V9GOv02E@pci4C7<|cm+QKSWDxW|$BG@u9NZvFyzIS|L%-O&H(1HHJF;>dR zV_=|^^f7438Yo>;p07@`$|P%_jEH`y)=|=lLPIzZ7QN0O@wg;~ikHzExg=}H2FINv z6T`!@A(W~RIkm*r!D6< z66KkAu=Nww)^ZqTabJDuXZNl?XRDuhY*-*wF#4qi;PdOJe*flKvY!Uq{J@^yw!H{9 zX>{j7z}q_y6k0%qR3dCd)wZi=??LQmtbYY#5}ASXCn9$hG{3++I>p^7C_X2L{OY!~i?@JqX>3aosH1``qu~m||AdBqwAW<#HHuzG zP(tD8+nzlX?}FaPsC$DMASiFNqKw|pL4_1&QuJW#F}MP7xjNI{V+G1c2ODBHTFQS} zUH1+yg76+S_Qwp2$k-K%=qvpra|0;G%E+!aR=OCsn6sJP11}_5+wFs=uUG0NzXCIS z7>6)N{sRB1@OQb2yPWVTXS~aq0N2%KzWajXa?@hdItR`5_RW0dg(H_I7bn*_Xs$OD T8u`|Q0yNic^y0u_HE!}hOkNJh diff --git a/backend/shop/__pycache__/urls.cpython-312.pyc b/backend/shop/__pycache__/urls.cpython-312.pyc index e427f955ff47e9aeadc5fc409c717d391c924b11..fe344bf0774ac7a6b31429ce23e9a513bd78cdf3 100644 GIT binary patch delta 333 zcmZ3)`IS@sG%qg~0}y!mbZ2@nGcY^`abN%}1LS<3Hc{PMB9}jkpOJxyA(eGCR6&$L zsz8?V#5P4{5VZLe|`QGfi*m3Ylg}_|GKx(8#+1QSBrrLexlv6KXf-1c7as%?AD9^# z8SgXbU1ZR^%V6-GiG`8rI|GpTI+=;3oI`Sk?TV@^ELM|CSd_WB+4z|nxr^k1x&TG~ BM?C-l delta 234 zcmey$xrkH!G%qg~0}ybVb!Yx%Vqka-;=lkWl<~Q4qPn*TBLfpdD(h;fSQLLMf0p9J zE=6V#wN6nTNWt_W=oI!;uGK(eL4c6~tm7M4$7Cr+e`(GXfi*mWqfg}@9 znbPDLjLPgRQ9_kMn!=M0F`6-QO#aE(IJuK4domxh2BYv~bLNc6OPK4p6u>4kFcfc@ dtivMB_<6DiOZnt8EOOkOto%%k+(mLgc>sQiE4Bat diff --git a/backend/shop/__pycache__/views.cpython-312.pyc b/backend/shop/__pycache__/views.cpython-312.pyc index 45a7d66f511294913ce1f2d91447aeba4ee58c7e..ec8d7e86c6ceb8adb0263be45730de89d9e63fb6 100644 GIT binary patch delta 8177 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 B<8uH2 delta 4594 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 {code}") - return Response({'message': '验证码已发送'}) - else: - print(f"短信发送失败: {response.text}") - return Response({'error': '短信发送失败,请稍后重试'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + # 异步发送短信 + def _send_async(): + try: + api_url = "https://data.tangledup-ai.com/api/send-sms" + payload = { + "phone_number": phone, + "code": code, + "template_code": "SMS_493295002", + "sign_name": "叠加态科技云南" + } + headers = { + "Content-Type": "application/json", + "accept": "application/json" + } + requests.post(api_url, json=payload, headers=headers, timeout=15) + print(f"短信异步发送请求已发出: {phone} -> {code}") + except Exception as e: + print(f"异步发送短信异常: {str(e)}") - 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) + + threading.Thread(target=_send_async).start() + sleep(2) + # 立即返回成功,无需等待外部API响应 + return Response({'message': '验证码已发送'}) @extend_schema( summary="微信支付 V3 Native 下单", @@ -463,6 +456,44 @@ def payment_finish(request): order.wechat_trade_no = transaction_id order.save() print(f"订单 {order.id} 状态已更新") + + # 计算佣金 + try: + salesperson = order.salesperson + if salesperson: + # 1. 计算直接佣金 (一级) + # 优先级: 产品独立分润比例 > 销售员个人分润比例 + rate_1 = order.config.commission_rate if order.config.commission_rate > 0 else salesperson.commission_rate + amount_1 = order.total_price * rate_1 + + if amount_1 > 0: + CommissionLog.objects.create( + order=order, + salesperson=salesperson, + amount=amount_1, + level=1, + status='pending' + ) + print(f"生成一级佣金: {salesperson.name} - {amount_1}") + + # 2. 计算上级佣金 (二级) + parent = salesperson.parent + if parent: + rate_2 = parent.second_level_rate + amount_2 = order.total_price * rate_2 + + if amount_2 > 0: + CommissionLog.objects.create( + order=order, + salesperson=parent, + amount=amount_2, + level=2, + status='pending' + ) + print(f"生成二级佣金: {parent.name} - {amount_2}") + except Exception as e: + print(f"佣金计算失败: {str(e)}") + except Exception as e: print(f"订单更新失败: {str(e)}")