From 92b0c3b136a25c1ef7553df0920f82231d79c01d Mon Sep 17 00:00:00 2001 From: ddrwode <34234@3来 34> Date: Wed, 4 Feb 2026 13:45:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E5=BF=85=E8=A6=81?= =?UTF-8?q?=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- analyze_models.py | 144 -------------------------------------- check_project_types.py | 25 ------- requirements.txt | Bin 1732 -> 822 bytes test_todo_logic.py | 124 -------------------------------- test_todo_logic_simple.py | 127 --------------------------------- 5 files changed, 420 deletions(-) delete mode 100644 analyze_models.py delete mode 100644 check_project_types.py delete mode 100644 test_todo_logic.py delete mode 100644 test_todo_logic_simple.py diff --git a/analyze_models.py b/analyze_models.py deleted file mode 100644 index 6bd575f..0000000 --- a/analyze_models.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -分析所有模型类,生成字段列表报告 -用于对比数据库字段和模型类字段 -""" -import os -import sys -import django - -# 设置 Django 环境 -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jyls_django.settings') -django.setup() - -from django.apps import apps -from django.db import models - -def analyze_model(model): - """分析单个模型,返回字段信息""" - fields_info = { - 'model_name': model.__name__, - 'table_name': model._meta.db_table, - 'fields': [], - 'm2m_fields': [], - 'foreign_keys': [] - } - - for field in model._meta.get_fields(include_parents=False): - # 多对多关系 - if isinstance(field, models.ManyToManyField): - fields_info['m2m_fields'].append({ - 'name': field.name, - 'related_model': field.related_model.__name__ if field.related_model else None, - 'through_table': field.remote_field.through._meta.db_table if hasattr(field.remote_field, 'through') else None - }) - continue - - # 跳过反向关系 - if getattr(field, 'auto_created', False): - continue - - # 跳过没有 column 属性的字段(反向关系) - if not hasattr(field, 'column'): - continue - - field_info = { - 'name': field.name, - 'column': field.column, - 'type': type(field).__name__, - 'null': getattr(field, 'null', False), - 'blank': getattr(field, 'blank', False), - 'max_length': getattr(field, 'max_length', None), - 'default': str(getattr(field, 'default', 'NOT_PROVIDED')), - } - - # 外键 - if isinstance(field, models.ForeignKey): - field_info['related_model'] = field.related_model.__name__ if field.related_model else None - fields_info['foreign_keys'].append(field_info) - else: - fields_info['fields'].append(field_info) - - return fields_info - -def main(): - print('=' * 80) - print('模型类字段分析报告') - print('=' * 80) - - apps_to_check = [ - apps.get_app_config('User'), - apps.get_app_config('finance'), - apps.get_app_config('business') - ] - - all_models_info = [] - - for app_config in apps_to_check: - print(f'\n\n应用: {app_config.name}') - print('=' * 80) - - models_to_check = app_config.get_models() - - for model in models_to_check: - info = analyze_model(model) - all_models_info.append(info) - - print(f'\n模型: {info["model_name"]}') - print(f'表名: {info["table_name"]}') - print('-' * 80) - - # 普通字段 - if info['fields']: - print('\n普通字段:') - for field in info['fields']: - null_str = 'NULL' if field['null'] else 'NOT NULL' - max_len_str = f", max_length={field['max_length']}" if field['max_length'] else '' - default_str = f", default={field['default']}" if field['default'] != 'NOT_PROVIDED' else '' - print(f" - {field['column']} ({field['type']}{max_len_str}, {null_str}{default_str})") - - # 外键 - if info['foreign_keys']: - print('\n外键字段:') - for field in info['foreign_keys']: - null_str = 'NULL' if field['null'] else 'NOT NULL' - related = field.get('related_model', 'Unknown') - print(f" - {field['column']} (ForeignKey -> {related}, {null_str})") - - # 多对多关系 - if info['m2m_fields']: - print('\n多对多关系:') - for field in info['m2m_fields']: - related = field.get('related_model', 'Unknown') - through = field.get('through_table', 'auto') - print(f" - {field['name']} (ManyToMany -> {related}, through={through})") - - # 生成汇总报告 - print('\n\n' + '=' * 80) - print('汇总报告') - print('=' * 80) - print(f'\n总共检查了 {len(all_models_info)} 个模型:') - for info in all_models_info: - field_count = len(info['fields']) + len(info['foreign_keys']) - m2m_count = len(info['m2m_fields']) - print(f" - {info['model_name']} ({info['table_name']}): {field_count} 个字段, {m2m_count} 个多对多关系") - - # 检查是否有 User 模型缺少 approvers_order 字段 - print('\n\n' + '=' * 80) - print('特殊检查: User 模型字段') - print('=' * 80) - - user_model = apps.get_model('User', 'User') - user_info = analyze_model(user_model) - - has_approvers_order = any(f['name'] == 'approvers_order' for f in user_info['fields']) - - if not has_approvers_order: - print('\n⚠️ 发现: User 模型没有 approvers_order 字段') - print(' 这可能导致入职/离职登记的审批流程无法正确获取审核人列表') - print(' 建议: 从 Approval.content 字段解析审核人列表(已在代码中实现)') - else: - print('\n✅ User 模型有 approvers_order 字段') - -if __name__ == '__main__': - main() diff --git a/check_project_types.py b/check_project_types.py deleted file mode 100644 index ae6e8a5..0000000 --- a/check_project_types.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -"""查询数据库中现有的项目类型""" - -import os -import sys -import django - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jyls_django.settings') -django.setup() - -from business.models import ProjectRegistration - -# 查询所有不重复的项目类型 -types = ProjectRegistration.objects.filter(is_deleted=False).values_list('type', flat=True).distinct() -print('=== 数据库中现有的项目类型 ===') -for t in types: - count = ProjectRegistration.objects.filter(type=t, is_deleted=False).count() - print(f' - {t}: {count}条记录') - -print() -print('=== 最近10条合同编号示例 ===') -samples = ProjectRegistration.objects.filter(is_deleted=False).order_by('-id')[:10].values_list('ContractNo', 'type', 'times') -for contract_no, proj_type, times in samples: - print(f' {contract_no} | {proj_type} | {times}') diff --git a/requirements.txt b/requirements.txt index 3aa5741b4cf3be78568f5f5c696169d56e235478..6f8492e3c60dfe0f9cc7b146c877f76d64c0dc60 100644 GIT binary patch literal 822 zcmZWnyN=s15bXIcB1Bp8qfmeVDRaODSEUMg5^eEJku*u2kN*11Qfi!Z(hhfaXJ)0* zd9jtxX>zuTsy*l;fY zyugzTQKibdFoXD^0(G{$WrMTHEy3r$7ktNeYzV{bM*2J8JNx7=LHY@Ji?!%M9t`!@ zTwqo9<3rku1IioTbZjiYBqdgplA{V(y5%SAxIr;3@2GWne|)M{>MK3hgNo@K6Sw%0?R1}aoSAEyfnNJcWV9JTj zGI`^Y(eInVM`oAV=Wi4aI$VrRiQ)umFNdqVXnR4W1L&n4Wl4(c^x7DA2l3kJ^WZ58 zjDlT&^Xl>FW<&c8VsU>McRPdL37Zb+k^gxBq zpkX&{_0snTE)L)g>bAhqb+-m5f|FPfa53swmyn|VDs$<5yqU5rIn_Z+%3j6lHUIwp zg5~HMpo%8dC(&)_KQnL@D_**x;SWMqHfm=}ID#BY4@f~g+tN!gaDGR!2)$2AL1WEZ H95(w4S>F3j literal 1732 zcma)6!A|Qy4D=c4eM+mQEroaBfW#3b5GPJ3q%BRGCMBCt%EtpU_HH&j9tc$%CAB^F zjO~4YOQn!p4$?{~1KHuNk(E^XhLpIYSfg&o_mZDsyOca3@L*>da$}sVFo@aFdUE?uqlrafMv9!zRX7UQhnoTubVuJ0oUiWuvSC^JP_A_Kce z{VQl2`Omb6mMe!kB{Yh4*#B$vlr`^Q<2KN4U5Qh*!8Go1oZ>&jzg9m^i0RDUaLO9s z6!2tLDs21ML#vb(W>7NKE#i!r7rS9yrbh{$ zDKG*;oZuZ86k6S0tzqtBG-s0-wm-&^RgC=(ux9Q-nD#lCQa$Ek9{L5eYj|DZ+{%qy z`g~*(m=Y`G%5~xciuIR@(kI?f 0: - print(f"\n✅ 场景:{description}") - print(f" 状态:{state}") - print(f" 期望返回:{expected_status}") - print(f" 找到 {count} 条记录") - - # 检查第一条记录 - approval = approvals.first() - print(f" 示例记录ID:{approval.id}") - print(f" 审批类型:{approval.type}") - print(f" 当前状态:{approval.state}") - - # 模拟逻辑判断 - if approval.type == "待办": - if approval.state == "已抄送财务" or approval.state == "已通过": - calculated_status = "已完成" - elif approval.state == "审核中": - calculated_status = "审批中" - elif approval.state == "未通过": - calculated_status = "审批中" - else: - calculated_status = "审批中" - else: - calculated_status = "未知" - - if calculated_status == expected_status: - print(f" ✅ 逻辑正确:计算状态 = {calculated_status}") - else: - print(f" ❌ 逻辑错误:计算状态 = {calculated_status},期望 = {expected_status}") - else: - print(f"\n⚠️ 场景:{description}") - print(f" 状态:{state}") - print(f" 未找到该状态的记录") - - print("\n" + "=" * 60) - print("测试完成") - print("=" * 60) - - # 显示所有待办记录的状态分布 - print("\n待办审批记录状态分布:") - print("-" * 60) - from django.db.models import Count - status_distribution = todo_approvals.values('state').annotate(count=Count('id')).order_by('state') - for item in status_distribution: - print(f" {item['state']}: {item['count']} 条") - - print("\n" + "=" * 60) - print("验证逻辑代码:") - print("=" * 60) - print(""" -# 在 roxyExhibition 中的逻辑: -if info.type == "待办": - # 待办类型:审核通过后(已抄送财务或已通过)即为已完成,不需要等待财务查看 - if info.state == "已抄送财务" or info.state == "已通过": - approval_status = "已完成" - elif info.state == "审核中": - approval_status = "审批中" - elif info.state == "未通过": - approval_status = "审批中" -""") - - print("\n" + "=" * 60) - print("结论:") - print("=" * 60) - print("✅ 对于'待办'类型:") - print(" - 状态为'已抄送财务' → 返回'已完成'(不需要等待财务查看)") - print(" - 状态为'已通过' → 返回'已完成'") - print(" - 状态为'审核中' → 返回'审批中'") - print(" - 状态为'未通过' → 返回'审批中'") - print("\n✅ 逻辑已正确实现:审核通过后(已抄送财务),不管财务有没有查看,都显示'已完成'") - -if __name__ == "__main__": - test_todo_completion_logic() diff --git a/test_todo_logic_simple.py b/test_todo_logic_simple.py deleted file mode 100644 index 04de222..0000000 --- a/test_todo_logic_simple.py +++ /dev/null @@ -1,127 +0,0 @@ -""" -简单测试待办事项的已完成逻辑 -直接验证代码逻辑,不依赖数据库 -""" - -def test_todo_status_logic(): - """测试待办事项状态判断逻辑""" - print("=" * 60) - print("测试待办事项的已完成逻辑") - print("=" * 60) - - # 模拟不同的审批状态 - test_cases = [ - { - "type": "待办", - "state": "已抄送财务", - "expected": "已完成", - "description": "审核通过后,状态为'已抄送财务',应该显示'已完成'(不需要等待财务查看)" - }, - { - "type": "待办", - "state": "已通过", - "expected": "已完成", - "description": "财务查看后,状态为'已通过',应该显示'已完成'" - }, - { - "type": "待办", - "state": "审核中", - "expected": "审批中", - "description": "审核中,应该显示'审批中'" - }, - { - "type": "待办", - "state": "未通过", - "expected": "审批中", - "description": "未通过,应该显示'审批中'" - }, - { - "type": "其他类型", - "state": "已抄送财务", - "expected": "待查看", - "description": "其他类型:已抄送财务,应该显示'待查看'(需要财务查看)" - }, - { - "type": "其他类型", - "state": "已通过", - "expected": "已完成", - "description": "其他类型:已通过,应该显示'已完成'" - }, - ] - - print("\n测试场景:") - print("-" * 60) - - all_passed = True - - for i, case in enumerate(test_cases, 1): - info_type = case["type"] - info_state = case["state"] - expected_status = case["expected"] - description = case["description"] - - # 模拟 roxyExhibition 中的逻辑 - approval_status = "审批中" # 默认状态 - if info_type == "待办": - # 待办类型:审核通过后(已抄送财务或已通过)即为已完成,不需要等待财务查看 - if info_state == "已抄送财务" or info_state == "已通过": - approval_status = "已完成" - elif info_state == "审核中": - approval_status = "审批中" - elif info_state == "未通过": - approval_status = "审批中" # 未通过也可以继续审批流程 - else: - # 其他类型:保持原有逻辑 - if info_state == "已抄送财务": - # 优先判断:已抄送财务时,显示"待查看"(财务部需要查看) - approval_status = "待查看" - elif info_state == "已通过": - # 审批记录状态为"已通过"(通常是财务查看后),显示"已完成" - approval_status = "已完成" - elif info_state == "审核中": - approval_status = "审批中" - elif info_state == "未通过": - approval_status = "审批中" # 未通过也可以继续审批流程 - - # 验证结果 - passed = approval_status == expected_status - status_icon = "[PASS]" if passed else "[FAIL]" - - print(f"\n{status_icon} 测试 {i}: {description}") - print(f" 类型: {info_type}") - print(f" 状态: {info_state}") - print(f" 期望返回: {expected_status}") - print(f" 实际返回: {approval_status}") - - if not passed: - all_passed = False - print(f" [WARNING] 不匹配!") - - print("\n" + "=" * 60) - print("测试结果:") - print("=" * 60) - - if all_passed: - print("[PASS] 所有测试通过!") - print("\n[PASS] 逻辑验证正确:") - print(" - 对于'待办'类型:") - print(" * 状态为'已抄送财务' → 返回'已完成'(不需要等待财务查看)") - print(" * 状态为'已通过' → 返回'已完成'") - print(" * 状态为'审核中' → 返回'审批中'") - print(" * 状态为'未通过' → 返回'审批中'") - print("\n - 对于其他类型:") - print(" * 状态为'已抄送财务' → 返回'待查看'(需要财务查看)") - print(" * 状态为'已通过' → 返回'已完成'") - else: - print("[FAIL] 部分测试失败,请检查逻辑") - - print("\n" + "=" * 60) - print("关键逻辑验证:") - print("=" * 60) - print("[PASS] 待办类型在审核通过后(状态为'已抄送财务'),") - print(" 不管财务有没有查看,都会显示'已完成'") - print(" 这符合需求:'审核通过了不管财务有没有查看都是已完成'") - print("=" * 60) - -if __name__ == "__main__": - test_todo_status_logic()