105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
"""消息格式化器"""
|
||
from typing import List, Dict
|
||
from datetime import datetime
|
||
|
||
|
||
class MessageFormatter:
|
||
"""消息格式化器"""
|
||
|
||
def __init__(self, logger=None):
|
||
self.logger = logger
|
||
self.unmapped_users = set()
|
||
|
||
def format_message(
|
||
self,
|
||
items: List[dict],
|
||
user_mapping: Dict[str, str],
|
||
date: str = None,
|
||
group_name: str = None
|
||
) -> tuple:
|
||
"""格式化消息
|
||
返回: (markdown_content, mentioned_list)
|
||
"""
|
||
if not items:
|
||
return None, []
|
||
|
||
if date is None:
|
||
date = datetime.now().strftime('%Y-%m-%d')
|
||
|
||
# 按处理人分组
|
||
grouped = self._group_by_owner(items)
|
||
|
||
# 排序
|
||
sorted_groups = self._sort_groups(grouped)
|
||
|
||
# 生成Markdown
|
||
group_label = self._format_group_label(group_name)
|
||
if group_label:
|
||
lines = [f"⏰ TAPD 过期单提醒 — {group_label}({date})\n\n"]
|
||
else:
|
||
lines = [f"⏰ TAPD 过期单提醒({date})\n\n"]
|
||
mentioned_list = []
|
||
total_count = 0
|
||
item_index = 1
|
||
|
||
for owner, owner_items in sorted_groups:
|
||
wework_id = user_mapping.get(owner)
|
||
|
||
if wework_id:
|
||
mentioned_list.append(wework_id)
|
||
lines.append(f"<@{wework_id}>({len(owner_items)} 条过期)")
|
||
else:
|
||
# 处理人不在映射表中
|
||
self.unmapped_users.add(owner)
|
||
lines.append(f"@{owner}({len(owner_items)} 条过期)")
|
||
if self.logger:
|
||
self.logger.log_api_call("formatter", "unmapped_user", {"owner": owner}, {}, False, "用户未在映射表中")
|
||
|
||
for item in owner_items:
|
||
type_label = "需求" if item['type'] == 'story' else "缺陷"
|
||
title = item.get('name') or item.get('title', '未命名')
|
||
lines.append(f"{item_index}.【{type_label}】{title} | 过期 {item['overdue_days']} 天 | [查看]({item['url']})")
|
||
item_index += 1
|
||
total_count += 1
|
||
|
||
lines.append("\n\n========================")
|
||
|
||
lines.append(f"共 {total_count} 条过期单,请今日内更新状态 🙏")
|
||
|
||
return "\n".join(lines), mentioned_list
|
||
|
||
def _format_group_label(self, group_name: str) -> str:
|
||
"""格式化组别显示文本"""
|
||
if not group_name:
|
||
return ""
|
||
normalized = str(group_name).strip()
|
||
if not normalized:
|
||
return ""
|
||
if normalized.endswith("组"):
|
||
return normalized
|
||
return f"{normalized}组"
|
||
|
||
def _group_by_owner(self, items: List[dict]) -> Dict[str, List[dict]]:
|
||
"""按处理人分组"""
|
||
grouped = {}
|
||
for item in items:
|
||
owner = item['owner']
|
||
if owner not in grouped:
|
||
grouped[owner] = []
|
||
grouped[owner].append(item)
|
||
return grouped
|
||
|
||
def _sort_groups(self, grouped: Dict[str, List[dict]]) -> List[tuple]:
|
||
"""排序:组内按过期天数降序,组间按最大过期天数降序"""
|
||
sorted_groups = []
|
||
|
||
for owner, items in grouped.items():
|
||
# 组内排序
|
||
items.sort(key=lambda x: x['overdue_days'], reverse=True)
|
||
sorted_groups.append((owner, items))
|
||
|
||
# 组间排序
|
||
sorted_groups.sort(key=lambda x: max(item['overdue_days'] for item in x[1]), reverse=True)
|
||
|
||
return sorted_groups
|