删除不必要的文件
This commit is contained in:
@@ -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()
|
|
||||||
@@ -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}')
|
|
||||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@@ -1,124 +0,0 @@
|
|||||||
"""
|
|
||||||
测试待办事项的已完成逻辑
|
|
||||||
验证:审核通过后(状态为"已抄送财务"),不管财务有没有查看,都应该显示"已完成"
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import django
|
|
||||||
|
|
||||||
# 设置Django环境
|
|
||||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jyls_django.settings')
|
|
||||||
django.setup()
|
|
||||||
|
|
||||||
from User.models import Approval
|
|
||||||
from business.models import Schedule
|
|
||||||
from User.views import roxyExhibition
|
|
||||||
from rest_framework.test import APIRequestFactory
|
|
||||||
from rest_framework.request import Request
|
|
||||||
import json
|
|
||||||
|
|
||||||
def test_todo_completion_logic():
|
|
||||||
"""测试待办事项的已完成逻辑"""
|
|
||||||
print("=" * 60)
|
|
||||||
print("测试待办事项的已完成逻辑")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
# 查找所有"待办"类型的审批记录
|
|
||||||
todo_approvals = Approval.objects.filter(type="待办", is_deleted=False)
|
|
||||||
|
|
||||||
if not todo_approvals.exists():
|
|
||||||
print("\n❌ 未找到任何待办类型的审批记录")
|
|
||||||
print("请先创建一些待办事项进行测试")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"\n找到 {todo_approvals.count()} 条待办审批记录\n")
|
|
||||||
|
|
||||||
# 测试不同状态下的逻辑
|
|
||||||
test_cases = [
|
|
||||||
("已抄送财务", "已完成", "审核通过后,状态为'已抄送财务',应该显示'已完成'"),
|
|
||||||
("已通过", "已完成", "财务查看后,状态为'已通过',应该显示'已完成'"),
|
|
||||||
("审核中", "审批中", "审核中,应该显示'审批中'"),
|
|
||||||
("未通过", "审批中", "未通过,应该显示'审批中'"),
|
|
||||||
]
|
|
||||||
|
|
||||||
print("测试场景:")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
for state, expected_status, description in test_cases:
|
|
||||||
approvals = todo_approvals.filter(state=state)
|
|
||||||
count = approvals.count()
|
|
||||||
|
|
||||||
if count > 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()
|
|
||||||
@@ -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()
|
|
||||||
Reference in New Issue
Block a user