diff --git a/a_long_dianjing/settings.py b/a_long_dianjing/settings.py index ed3499e..5728cb2 100644 --- a/a_long_dianjing/settings.py +++ b/a_long_dianjing/settings.py @@ -29,14 +29,14 @@ INSTALLED_APPS = [ 'corsheaders', 'django_celery_results', 'celery', - 'yonghu', - 'dingdan', - 'shangpin', - 'peizhi', - 'houtai', + 'users', + 'orders', + 'products', + 'config', + 'backend', 'utils', - 'shangdian', - 'dengji', + 'shop', + 'rank', ] MIDDLEWARE = [ @@ -131,7 +131,7 @@ AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', ] -AUTH_USER_MODEL = 'yonghu.UserMain' +AUTH_USER_MODEL = 'users.UserMain' # ==================== DRF 配置 ==================== REST_FRAMEWORK = { diff --git a/a_long_dianjing/urls.py b/a_long_dianjing/urls.py index 65a0134..d0c2f9e 100644 --- a/a_long_dianjing/urls.py +++ b/a_long_dianjing/urls.py @@ -10,20 +10,20 @@ urlpatterns = [ path('admin/', admin.site.urls), # 用户相关路由 - path('yonghu/', include('yonghu.urls')), + path('yonghu/', include('users.urls')), # 订单相关路由 - path('dingdan/', include('dingdan.urls')), + path('dingdan/', include('orders.urls')), # 商品/陪玩服务相关路由 - path('shangpin/', include('shangpin.urls')), + path('shangpin/', include('products.urls')), # 配置相关路由(系统配置) - path('peizhi/', include('peizhi.urls')), - path('houtai/', include('houtai.urls')), - path('shangdian/', include('shangdian.urls')), - path('dengji/', include('dengji.urls')), + path('peizhi/', include('config.urls')), + path('houtai/', include('backend.urls')), + path('shangdian/', include('shop.urls')), + path('dengji/', include('rank.urls')), ] # 重要说明: diff --git a/config/views.py b/config/views.py index 86b09c7..3180f0c 100644 --- a/config/views.py +++ b/config/views.py @@ -26,7 +26,7 @@ from rest_framework.throttling import AnonRateThrottle, SimpleRateThrottle from utils.oss_utils import upload_to_oss, delete_from_oss, validate_image from utils.weixin_broadcast import WeixinBroadcastSender # from utils.ip_security import * -from Django.utils.invitationcode_utils import CreateInvitationCode, VerifyInvitationCode +from utils.invitationcode_utils import CreateInvitationCode, VerifyInvitationCode from backend.utils import update_shangjia_daily from orders.utils import sync_order_to_partners diff --git a/find.py b/find.py new file mode 100644 index 0000000..487974e --- /dev/null +++ b/find.py @@ -0,0 +1,163 @@ +""" +REPL 模式文件内容搜索工具 +支持正则或纯文本搜索,默认搜索当前目录 +""" +import os +import re +import sys + +# 硬编码排除目录 +EXCLUDE_DIRS = { + '.git', '.vs', 'node_modules', '__pycache__', '.idea', + 'miniprogram_npm', '_backup_pre_redesign', +} + +# 排除的文件扩展名 +EXCLUDE_EXTS = { + '.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico', '.bmp', + '.mp3', '.mp4', '.wav', '.avi', + '.zip', '.rar', '.7z', '.tar', '.gz', + '.exe', '.dll', '.so', '.dylib', + '.pyc', '.pyo', '.class', '.o', '.obj', + '.db', '.sqlite', '.vsidx', +} + +# 默认搜索根目录 +DEFAULT_ROOT = os.path.dirname(os.path.abspath(__file__)) + + +def should_skip(dirpath): + """判断目录是否应跳过""" + parts = dirpath.replace('\\', '/').split('/') + return any(p in EXCLUDE_DIRS for p in parts) + + +def search(pattern, root=DEFAULT_ROOT, use_regex=True, max_results=50): + """搜索文件内容""" + try: + if use_regex: + compiled = re.compile(pattern, re.IGNORECASE) + except re.error as e: + print(f' 正则语法错误: {e}') + return + + count = 0 + for dirpath, dirnames, filenames in os.walk(root): + # 就地修改 dirnames 以跳过排除目录 + dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS] + + for fname in filenames: + ext = os.path.splitext(fname)[1].lower() + if ext in EXCLUDE_EXTS: + continue + + fpath = os.path.join(dirpath, fname) + relpath = os.path.relpath(fpath, root) + try: + with open(fpath, 'r', encoding='utf-8', errors='ignore') as f: + for lineno, line in enumerate(f, 1): + line_stripped = line.rstrip('\n\r') + if use_regex: + match = compiled.search(line_stripped) + if match: + highlight = line_stripped[:match.start()] + \ + f'>>> {match.group()} <<<' + \ + line_stripped[match.end():] + print(f' {relpath}:{lineno} {highlight}') + count += 1 + else: + if pattern.lower() in line_stripped.lower(): + print(f' {relpath}:{lineno} {line_stripped}') + count += 1 + + if count >= max_results: + print(f'\n ... 已达上限 {max_results} 条,停止') + return + except (PermissionError, OSError): + continue + + if count == 0: + print(' 未找到匹配内容') + else: + print(f'\n 共 {count} 条匹配') + + +def main(): + print('=== 文件内容搜索工具 ===') + print(f'搜索根目录: {DEFAULT_ROOT}') + print(f'排除目录: {EXCLUDE_DIRS}') + print() + print('命令:') + print(' /regex 正则搜索') + print(' /text 纯文本搜索') + print(' /max 设置结果上限(默认50)') + print(' /dir 切换搜索目录') + print(' /help 显示帮助') + print(' /quit 退出') + print() + print('直接输入内容默认使用正则搜索') + print() + + root = DEFAULT_ROOT + use_regex = True + max_results = 50 + + while True: + try: + raw = input('find> ').strip() + except (EOFError, KeyboardInterrupt): + print('\n再见') + break + + if not raw: + continue + + if raw == '/quit': + print('再见') + break + + if raw == '/help': + print(' /regex 正则搜索') + print(' /text 纯文本搜索') + print(' /max 设置结果上限') + print(' /dir 切换搜索目录') + print(' /help 显示帮助') + print(' /quit 退出') + print(' 直接输入内容默认使用正则搜索') + continue + + if raw.startswith('/regex '): + pattern = raw[7:].strip() + if pattern: + search(pattern, root, use_regex=True, max_results=max_results) + continue + + if raw.startswith('/text '): + pattern = raw[6:].strip() + if pattern: + search(pattern, root, use_regex=False, max_results=max_results) + continue + + if raw.startswith('/max '): + try: + max_results = int(raw[5:].strip()) + print(f' 结果上限设为 {max_results}') + except ValueError: + print(' 请输入数字') + continue + + if raw.startswith('/dir '): + new_dir = raw[5:].strip() + if os.path.isdir(new_dir): + root = os.path.abspath(new_dir) + print(f' 搜索目录切换为: {root}') + else: + print(f' 目录不存在: {new_dir}') + continue + + # 默认正则搜索 + search(raw, root, use_regex=use_regex, max_results=max_results) + + +if __name__ == '__main__': + main() diff --git a/orders/models.py b/orders/models.py index ceee486..ca8cba7 100644 --- a/orders/models.py +++ b/orders/models.py @@ -53,7 +53,6 @@ class Dingdan(models.Model): db_index=True, verbose_name='微信支付订单号' ) - class Meta: db_table = 'dingdan' @@ -90,7 +89,6 @@ class DingdanPingtai(models.Model): verbose_name='上级分红金额') # ============================= - class Meta: db_table = 'dingdan_pingtai' @@ -99,13 +97,12 @@ class DingdanPingtai(models.Model): indexes = [ models.Index(fields=['laoban_id']), models.Index(fields=['dianpu_id']), # 为新字段加索引 - - ] def __str__(self): return f"平台扩展-{self.dingdan.dingdan_id}" + class DingdanShangjia(models.Model): """商家发单扩展表 (当 fadan_pingtai=2 时使用)""" dingdan = models.OneToOneField(Dingdan, on_delete=models.CASCADE, related_name='shangjia_kuozhan', verbose_name='订单') @@ -553,10 +550,6 @@ class Ptliushui(models.Model): db_table = 'ptliushui' -# models.py - ChatRelation 模型 - - - class Liaotian(models.Model): """聊天关系表 - 极简设计,不设置唯一约束""" # 主键 diff --git a/orders/tasks.py b/orders/tasks.py index a898b43..544adc5 100644 --- a/orders/tasks.py +++ b/orders/tasks.py @@ -18,6 +18,8 @@ from orders.models import Dingdan from users.models import UserMain, UserDashou, UserShangjia from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure +# from users.utils import update_platform_profit # 导入函数 + logger = logging.getLogger(__name__) @@ -109,7 +111,6 @@ def process_expired_order(self, dingdan_id): if fadan_pingtai == 1: try: - from orders.utils import update_platform_profit # 导入函数 update_platform_profit(dingdan_id) except Exception as e: # 平台收益更新失败不影响主流程,但记录日志 diff --git a/orders/views.py b/orders/views.py index 076353d..8ede6e5 100644 --- a/orders/views.py +++ b/orders/views.py @@ -39,9 +39,10 @@ from tencentcloud.sts.v20180813 import sts_client, models from utils.weixin_broadcast import WeixinBroadcastSender from utils.chat_utils import _send_group_message, _subscribe_users_to_group, establish_order_chat from utils.fadan_utils import check_fadan_qiangdan_eligible +# from utils.admin import update_platform_profit from orders.utils import ( - update_platform_profit, calc_shangjia_order_fencheng, sync_order_to_partners, + calc_shangjia_order_fencheng, sync_order_to_partners, update_daily_dispatch_stat, update_daily_income, update_daily_payout, settle_shangjia_order_guanshi_fenhong ) diff --git a/products/models.py b/products/models.py index fe5da00..3a91f7e 100644 --- a/products/models.py +++ b/products/models.py @@ -36,7 +36,7 @@ class Shangpin(models.Model): shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用') dianpu = models.ForeignKey( - 'shangdian.Dianpu', # 🔥 跨应用完整路径 + 'shop.Dianpu', # 🔥 跨应用完整路径 on_delete=models.CASCADE, null=True, blank=True, @@ -44,7 +44,7 @@ class Shangpin(models.Model): verbose_name='所属店铺' ) dianpu_leixing = models.ForeignKey( - 'shangdian.ShangpinLeixingDianpu', + 'shop.ShangpinLeixingDianpu', on_delete=models.SET_NULL, null=True, blank=True, @@ -79,7 +79,7 @@ class ShangpinLeixing(models.Model): paixu = models.IntegerField(default=0, verbose_name='排序权重') shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用') bankuai = models.ForeignKey( - 'dengji.Bankuai', + 'rank.Bankuai', on_delete=models.SET_NULL, null=True, blank=True, @@ -104,7 +104,7 @@ class ShangpinZhuanqu(models.Model): shenhezhuangtai = models.IntegerField(default=1, verbose_name='审核状态', help_text='1=正常, 2=审核专用') dianpu = models.ForeignKey( - 'shangdian.Dianpu', # 🔥 跨应用完整路径 + 'shop.Dianpu', # 🔥 跨应用完整路径 on_delete=models.CASCADE, null=True, blank=True, @@ -112,7 +112,7 @@ class ShangpinZhuanqu(models.Model): verbose_name='所属店铺' ) dianpu_leixing = models.ForeignKey( - 'shangdian.ShangpinLeixingDianpu', + 'shop.ShangpinLeixingDianpu', on_delete=models.SET_NULL, null=True, blank=True, @@ -144,7 +144,7 @@ class Huiyuan(models.Model): create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间') bankuai = models.ForeignKey( - 'dengji.Bankuai', + 'rank.Bankuai', on_delete=models.SET_NULL, null=True, blank=True, @@ -308,7 +308,7 @@ class ShangpinMeiriTongji(models.Model): 日期精确到天,冗余年月日字段便于分组查询 """ shangpin = models.ForeignKey( - 'shangpin.Shangpin', + 'products.Shangpin', on_delete=models.CASCADE, db_index=True, verbose_name='商品ID' diff --git a/rank/models.py b/rank/models.py index 0ebb16a..8be36ad 100644 --- a/rank/models.py +++ b/rank/models.py @@ -19,7 +19,7 @@ class Bankuai(models.Model): # ==================== 打手订单表现记录 ==================== class DashouBiaoxian(models.Model): - dingdan = models.ForeignKey('dingdan.Dingdan', to_field='dingdan_id', on_delete=models.CASCADE, related_name='biaoxian', verbose_name='关联订单', db_index=True) + dingdan = models.ForeignKey('orders.Dingdan', to_field='dingdan_id', on_delete=models.CASCADE, related_name='biaoxian', verbose_name='关联订单', db_index=True) dashou_id = models.CharField(max_length=32, db_index=True, verbose_name='打手ID') bankuai = models.ForeignKey(Bankuai, on_delete=models.PROTECT, to_field='bankuai_id', verbose_name='所属板块', db_index=True,null=True) @@ -94,7 +94,6 @@ class YonghuChenghao(models.Model): - class DingdanBiaoqian(models.Model): """订单需求标签关联表""" dingdan = models.ForeignKey( @@ -104,7 +103,7 @@ class DingdanBiaoqian(models.Model): verbose_name='订单', db_index=True ) - chenghao = models.ForeignKey('dengji.Chenghao', on_delete=models.CASCADE, verbose_name='标签') + chenghao = models.ForeignKey('rank.Chenghao', on_delete=models.CASCADE, verbose_name='标签') create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') class Meta: diff --git a/rank/utils.py b/rank/utils.py index 2a2464c..f9a1f01 100644 --- a/rank/utils.py +++ b/rank/utils.py @@ -14,7 +14,7 @@ from .models import ( ## users应用 from users.models import UserMain, UserShenheguan, UserDashou ## orders应用 -from orders.models import YonghuChenghao +from .models import YonghuChenghao # 日志对象 logger = logging.getLogger(__name__) diff --git a/shop/models.py b/shop/models.py index 45f1cdf..aea67c8 100644 --- a/shop/models.py +++ b/shop/models.py @@ -1,7 +1,5 @@ from django.db import models -# Create your models here. - class YonghuPingzheng(models.Model): id = models.AutoField(primary_key=True, verbose_name='自增主键ID') @@ -26,7 +24,7 @@ class YonghuPingzheng(models.Model): class Dianpu(models.Model): id = models.AutoField(primary_key=True, verbose_name='店铺自增ID') pingzheng = models.OneToOneField( - 'shangdian.YonghuPingzheng', # 同应用内可简写,但完整路径更清晰 + 'shop.YonghuPingzheng', # 同应用内可简写,但完整路径更清晰 on_delete=models.CASCADE, db_index=True, verbose_name='关联用户凭证' @@ -149,7 +147,7 @@ class DianpuShouzhiMeiriTongji(models.Model): class YonghuDianpuBangding(models.Model): id = models.AutoField(primary_key=True, verbose_name='绑定自增ID') yonghu = models.ForeignKey( - 'yonghu.UserMain', # 🔥 完整路径 + 'users.UserMain', # 🔥 完整路径 to_field='yonghuid', on_delete=models.CASCADE, db_index=True, @@ -166,8 +164,6 @@ class YonghuDianpuBangding(models.Model): unique_together = [['yonghu', 'dianpu']] -# shangdian/models.py - class ShangpinLeixingDianpu(models.Model): """ 店铺级商品类型映射表 @@ -175,14 +171,14 @@ class ShangpinLeixingDianpu(models.Model): """ id = models.AutoField(primary_key=True, verbose_name='类型自增ID') dianpu = models.ForeignKey( - 'shangdian.Dianpu', + 'shop.Dianpu', on_delete=models.CASCADE, db_index=True, verbose_name='所属店铺' ) # 🔥 强制映射到公共商品类型,不可为空 gonggong_leixing = models.ForeignKey( - 'shangpin.ShangpinLeixing', + 'shop.ShangpinLeixing', on_delete=models.CASCADE, db_index=True, verbose_name='映射的公共商品类型' diff --git a/shop/urls.py b/shop/urls.py index 48ff274..a482b89 100644 --- a/shop/urls.py +++ b/shop/urls.py @@ -10,8 +10,8 @@ urlpatterns = [ path('bdsd', BindDianpuView.as_view(), name='绑定或更新商家店铺'), path('hqsp', ShopGoodsView.as_view(), name='获取商品数据'), - path('login', ShangdianLoginView.as_view(), name='商家登录'), - path('sjdpgl', ShopOverviewView.as_view(), name='商家获取店铺信息'), + path('login', ShangdianLoginView.as_view(), name='商家登录'), + path('sjdpgl', ShopOverviewView.as_view(), name='商家获取店铺信息'), path('sdscdpm', ShopQrcodeView.as_view(), name='生成或更新店铺二维码'), path('dphqspxx', ShopProductConfigView.as_view(), name='商店获取商品类型专区'), diff --git a/shop/views.py b/shop/views.py index 3673e96..61b0e93 100644 --- a/shop/views.py +++ b/shop/views.py @@ -3370,4 +3370,4 @@ class ShopFineApplyView(APIView): except Exception as e: logger.error(f"店铺罚款申请异常: {traceback.format_exc()}") - return Response({'code': 500, 'msg': '服务器内部错误'}) \ No newline at end of file + return Response({'code': 500, 'msg': '服务器内部错误'}) \ No newline at end of file diff --git a/users/models.py b/users/models.py index bfc02fd..9b8fce7 100644 --- a/users/models.py +++ b/users/models.py @@ -2,6 +2,7 @@ from django.db import models from django.contrib.auth.models import AbstractBaseUser + # ==================== 用户主表 ==================== class UserMain(AbstractBaseUser): # ID字段 diff --git a/users/views.py b/users/views.py index 4c45ee3..ebef143 100644 --- a/users/views.py +++ b/users/views.py @@ -43,7 +43,7 @@ from utils.oss_utils import validate_image, upload_to_oss, delete_from_oss from utils.fadan_utils import check_fadan_qiangdan_eligible from utils.wechat_v3 import verify_wechat_sign, decrypt_callback_ciphertext -from Django.utils.invitationcode_utils import CreateInvitationCode, VerifyInvitationCode +from utils.invitationcode_utils import CreateInvitationCode, VerifyInvitationCode from users.fadan_fenhong_utils import process_fadan_fenhong from orders.utils import ( @@ -86,7 +86,7 @@ from rank.models import ( from users.models import UserShenheguan from products.utils import update_shangpin_daily_stat from shop.utils import update_dianpu_daily_stat -from orders.utils import create_shenhe_jilu_from_temp +from rank.utils import create_shenhe_jilu_from_temp import logging logger = logging.getLogger(__name__) diff --git a/utils/exception_handler.py b/utils/exception_handler.py index 81cdfb2..359acd0 100644 --- a/utils/exception_handler.py +++ b/utils/exception_handler.py @@ -67,6 +67,8 @@ def custom_exception_handler(exc, context): f"错误类型: {type(exc).__name__}, 错误: {str(exc)}" ) if not settings.DEBUG: + import traceback + print(traceback.format_exc()) return Response( {'code': 500, 'message': '服务器内部错误,请稍后重试'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR diff --git a/utils/fadan_utils.py b/utils/fadan_utils.py index 8abd86f..2e4a9b5 100644 --- a/utils/fadan_utils.py +++ b/utils/fadan_utils.py @@ -57,7 +57,7 @@ def check_fadan_qiangdan_eligible(yonghuid: str, action_type: int) -> tuple: import logging from django.db import transaction from decimal import Decimal -from dingdan.models import Fadan, FadanFenhong, FadanFenhongLilv +from orders.models import Fadan, FadanFenhong, FadanFenhongLilv logger = logging.getLogger('xiaochengxu') diff --git a/utils/models.py b/utils/models.py index 71a8362..137941f 100644 --- a/utils/models.py +++ b/utils/models.py @@ -1,3 +1 @@ from django.db import models - -# Create your models here.