优化了投标待办
This commit is contained in:
@@ -59,6 +59,7 @@ class Approval(models.Model):
|
|||||||
state = models.CharField(max_length=100) # 状态
|
state = models.CharField(max_length=100) # 状态
|
||||||
type = models.CharField(max_length=100) # 类别
|
type = models.CharField(max_length=100) # 类别
|
||||||
user_id = models.CharField(max_length=100) # 事件id
|
user_id = models.CharField(max_length=100) # 事件id
|
||||||
|
applicant = models.CharField(max_length=100, null=True, blank=True) # 申请人(提交人,用于投标登记、立项等)
|
||||||
rejection_reason = models.TextField(null=True, blank=True) # 不通过原因(审核不通过时填写)
|
rejection_reason = models.TextField(null=True, blank=True) # 不通过原因(审核不通过时填写)
|
||||||
is_deleted = models.BooleanField(default=False) # 软删除标记
|
is_deleted = models.BooleanField(default=False) # 软删除标记
|
||||||
|
|
||||||
|
|||||||
@@ -802,12 +802,8 @@ class roxyExhibition(APIView):
|
|||||||
# 单个值
|
# 单个值
|
||||||
query = Q(state=filter_state)
|
query = Q(state=filter_state)
|
||||||
else:
|
else:
|
||||||
# 默认状态筛选:审核中 或 已抄送财务
|
# 默认状态筛选:审核中、已抄送财务;非财务也包含"已通过"以便按申请人/审批人过滤后展示(待办、投标登记等)
|
||||||
# 如果是财务部人员,还需要包含"已通过"状态(可以看到已完成的待办)
|
query = Q(state__in=["审核中", "已抄送财务", "已通过"])
|
||||||
if is_finance_user:
|
|
||||||
query = Q(state__in=["审核中", "已抄送财务", "已通过"])
|
|
||||||
else:
|
|
||||||
query = Q(state__in=["审核中", "已抄送财务"])
|
|
||||||
|
|
||||||
# 添加筛选条件
|
# 添加筛选条件
|
||||||
if filter_type:
|
if filter_type:
|
||||||
@@ -867,14 +863,37 @@ class roxyExhibition(APIView):
|
|||||||
if user_submitted_schedule_ids_str:
|
if user_submitted_schedule_ids_str:
|
||||||
completed_todo_query = Q(type="待办", state="已通过", user_id__in=user_submitted_schedule_ids_str)
|
completed_todo_query = Q(type="待办", state="已通过", user_id__in=user_submitted_schedule_ids_str)
|
||||||
|
|
||||||
# 组合查询:部门匹配 OR 审批员匹配 OR 财务匹配 OR 已通过的待办查询
|
# 投标登记审批完成后,申请人与审批人均可见
|
||||||
|
completed_bid_query = Q()
|
||||||
|
completed_bid_applicant = Q(type="投标登记", state="已通过", applicant=user.username)
|
||||||
|
try:
|
||||||
|
approved_bid_ids = list(Approval.objects.filter(type="投标登记", state="已通过").values_list('user_id', flat=True))
|
||||||
|
bid_ids_where_user_is_approver = []
|
||||||
|
if approved_bid_ids:
|
||||||
|
bid_ids_int = [int(x) for x in approved_bid_ids if str(x).isdigit()]
|
||||||
|
from business.models import Bid
|
||||||
|
for bid in Bid.objects.filter(id__in=bid_ids_int, is_deleted=False):
|
||||||
|
try:
|
||||||
|
order = json.loads(bid.approvers_order or '[]')
|
||||||
|
if isinstance(order, list) and user.username in order:
|
||||||
|
bid_ids_where_user_is_approver.append(bid.id)
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
pass
|
||||||
|
if bid_ids_where_user_is_approver:
|
||||||
|
completed_bid_query = completed_bid_applicant | Q(type="投标登记", state="已通过", user_id__in=[str(x) for x in bid_ids_where_user_is_approver])
|
||||||
|
else:
|
||||||
|
completed_bid_query = completed_bid_applicant
|
||||||
|
except Exception:
|
||||||
|
completed_bid_query = completed_bid_applicant
|
||||||
|
|
||||||
|
# 组合查询:部门匹配 OR 审批员匹配 OR 财务匹配 OR 已通过的待办查询 OR 已通过的投标登记(申请人/审批人可见)
|
||||||
# 如果用户有部门,使用部门匹配;否则只使用审批员匹配
|
# 如果用户有部门,使用部门匹配;否则只使用审批员匹配
|
||||||
# 注意:审批员匹配必须精确匹配当前用户名,确保多人团队审核时,只有当前审核人能看到
|
# 注意:审批员匹配必须精确匹配当前用户名,确保多人团队审核时,只有当前审核人能看到
|
||||||
if user_department_ids_str:
|
if user_department_ids_str:
|
||||||
query &= (department_query | person_query | finance_query | completed_todo_query)
|
query &= (department_query | person_query | finance_query | completed_todo_query | completed_bid_query)
|
||||||
else:
|
else:
|
||||||
# 如果用户没有部门,匹配审批员或财务(仅财务部人员)或已通过的待办
|
# 如果用户没有部门,匹配审批员或财务(仅财务部人员)或已通过的待办或已通过的投标登记
|
||||||
query &= (person_query | finance_query | completed_todo_query)
|
query &= (person_query | finance_query | completed_todo_query | completed_bid_query)
|
||||||
|
|
||||||
# 添加调试日志
|
# 添加调试日志
|
||||||
import logging
|
import logging
|
||||||
@@ -1409,9 +1428,9 @@ class roxyExhibition(APIView):
|
|||||||
itme["project_conflicts"] = []
|
itme["project_conflicts"] = []
|
||||||
itme["bid_conflicts"] = []
|
itme["bid_conflicts"] = []
|
||||||
|
|
||||||
# 如果是投标登记类型:返回提交人、冲突信息等(与立项相同逻辑)
|
# 如果是投标登记类型:返回申请人、审批流程、冲突信息等(与立项相同逻辑)
|
||||||
if info.type == "投标登记":
|
if info.type == "投标登记":
|
||||||
# 提交人:优先从 Approval.applicant 取,否则从 content 解析「申请人:xxx」
|
# 申请人:优先从 Approval.applicant 取,否则从 content 解析「申请人:xxx」
|
||||||
submitter = getattr(info, 'applicant', None)
|
submitter = getattr(info, 'applicant', None)
|
||||||
if not submitter and content and "申请人:" in content:
|
if not submitter and content and "申请人:" in content:
|
||||||
import re
|
import re
|
||||||
@@ -1419,13 +1438,23 @@ class roxyExhibition(APIView):
|
|||||||
if m:
|
if m:
|
||||||
submitter = m.group(1).strip()
|
submitter = m.group(1).strip()
|
||||||
itme["submitter"] = submitter or ""
|
itme["submitter"] = submitter or ""
|
||||||
# 将提交人拼接到待办展示信息(content)中,便于列表一眼看到
|
itme["applicant"] = submitter or "" # 投标待办展示“申请人”字段(审批人--->申请人)
|
||||||
if submitter and ("提交人:" not in (itme.get("content") or "")):
|
|
||||||
itme["content"] = (itme.get("content") or "").rstrip() + ",提交人:" + submitter
|
|
||||||
try:
|
try:
|
||||||
from business.views import conflict_search
|
from business.views import conflict_search
|
||||||
bid_id = int(info.user_id)
|
bid_id = int(info.user_id)
|
||||||
bid = Bid.objects.filter(id=bid_id, is_deleted=False).first()
|
bid = Bid.objects.filter(id=bid_id, is_deleted=False).first()
|
||||||
|
# 审批流程:从 Bid.approvers_order 解析为名单列表
|
||||||
|
approvers_order_list = []
|
||||||
|
if bid and getattr(bid, 'approvers_order', None):
|
||||||
|
try:
|
||||||
|
order = json.loads(bid.approvers_order or '[]')
|
||||||
|
approvers_order_list = order if isinstance(order, list) else []
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
pass
|
||||||
|
itme["approvers_order"] = approvers_order_list # 审批流程(审批人顺序)
|
||||||
|
# 将申请人拼接到待办展示信息(content)中,便于列表一眼看到
|
||||||
|
if submitter and ("申请人:" not in (itme.get("content") or "") and ("提交人:" not in (itme.get("content") or "")):
|
||||||
|
itme["content"] = (itme.get("content") or "").rstrip() + ",申请人:" + submitter
|
||||||
if bid and bid.BiddingUnit:
|
if bid and bid.BiddingUnit:
|
||||||
conflict_result = conflict_search(bidding_unit=bid.BiddingUnit, exclude_bid_id=bid_id)
|
conflict_result = conflict_search(bidding_unit=bid.BiddingUnit, exclude_bid_id=bid_id)
|
||||||
def parse_json_fields_bid(records):
|
def parse_json_fields_bid(records):
|
||||||
|
|||||||
@@ -1130,7 +1130,8 @@ class BidRegistration(APIView):
|
|||||||
# 使用统一的审核流程函数
|
# 使用统一的审核流程函数
|
||||||
from User.utils import create_approval_with_team_logic
|
from User.utils import create_approval_with_team_logic
|
||||||
|
|
||||||
content = f"项目名称:{ProjectName},申请日期:{times},招标单位:{BiddingUnit}{conflict_text}"
|
applicant_name = user.username if user else ""
|
||||||
|
content = f"项目名称:{ProjectName},申请日期:{times},招标单位:{BiddingUnit},申请人:{applicant_name}{conflict_text}"
|
||||||
|
|
||||||
approval, approvers_order_json, needs_approval = create_approval_with_team_logic(
|
approval, approvers_order_json, needs_approval = create_approval_with_team_logic(
|
||||||
team_name=team_name,
|
team_name=team_name,
|
||||||
@@ -1143,6 +1144,11 @@ class BidRegistration(APIView):
|
|||||||
today=formatted_date
|
today=formatted_date
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 写入申请人,便于待办列表展示及“审批完成后申请人可见”
|
||||||
|
if approval and applicant_name:
|
||||||
|
approval.applicant = applicant_name
|
||||||
|
approval.save(update_fields=['applicant'])
|
||||||
|
|
||||||
# 如果返回None且需要审核,说明缺少审核人
|
# 如果返回None且需要审核,说明缺少审核人
|
||||||
if approval is None and needs_approval:
|
if approval is None and needs_approval:
|
||||||
return Response({
|
return Response({
|
||||||
@@ -1246,6 +1252,7 @@ class EditBid(APIView):
|
|||||||
today = datetime.datetime.now()
|
today = datetime.datetime.now()
|
||||||
formatted_date = today.strftime("%Y-%m-%d")
|
formatted_date = today.strftime("%Y-%m-%d")
|
||||||
team_name = None
|
team_name = None
|
||||||
|
edit_user = None
|
||||||
token = request.META.get('token')
|
token = request.META.get('token')
|
||||||
if token:
|
if token:
|
||||||
try:
|
try:
|
||||||
@@ -1254,16 +1261,21 @@ class EditBid(APIView):
|
|||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
team_name = None
|
team_name = None
|
||||||
from User.utils import create_approval_with_team_logic
|
from User.utils import create_approval_with_team_logic
|
||||||
|
applicant_name = edit_user.username if edit_user else ""
|
||||||
|
content_edit = f"项目名称:{bid.ProjectName},申请日期:{times or bid.times},申请人:{applicant_name}"
|
||||||
approval, approvers_order_json, needs_approval = create_approval_with_team_logic(
|
approval, approvers_order_json, needs_approval = create_approval_with_team_logic(
|
||||||
team_name=team_name,
|
team_name=team_name,
|
||||||
approvers=approvers,
|
approvers=approvers,
|
||||||
title=bid.ProjectName + "投标登记重新编辑",
|
title=bid.ProjectName + "投标登记重新编辑",
|
||||||
content="项目名称:" + bid.ProjectName + ",申请日期:" + (times or bid.times),
|
content=content_edit,
|
||||||
approval_type="投标登记",
|
approval_type="投标登记",
|
||||||
user_id=bid.id,
|
user_id=bid.id,
|
||||||
business_record=bid,
|
business_record=bid,
|
||||||
today=formatted_date
|
today=formatted_date
|
||||||
)
|
)
|
||||||
|
if approval and applicant_name:
|
||||||
|
approval.applicant = applicant_name
|
||||||
|
approval.save(update_fields=['applicant'])
|
||||||
if approval is None and needs_approval:
|
if approval is None and needs_approval:
|
||||||
return Response({
|
return Response({
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
|
|||||||
Reference in New Issue
Block a user