|
@@ -52,7 +52,8 @@ class DataSend:
|
|
|
title_prev = utils.get_config_value("email.report_title_prev", "【中标报告】")
|
|
|
title = f"{start_date.month}月中标结果报告"
|
|
|
body = self._build_report_email_html(title, items)
|
|
|
- flag = utils.send_email(email, f"{title_prev} {title}", body, True)
|
|
|
+ attach_path = self._gen_report_exlecl(title, items)
|
|
|
+ flag = utils.send_email(email, f"{title_prev} {title}", body, True, attach_path)
|
|
|
if flag:
|
|
|
utils.get_logger().info("发送中标报告邮件成功")
|
|
|
|
|
@@ -177,10 +178,8 @@ class DataSend:
|
|
|
"""
|
|
|
return html_body
|
|
|
|
|
|
- def _build_report_email_html(self, title, items) -> str:
|
|
|
- body = ""
|
|
|
- for item in items:
|
|
|
- body += self._build_report_email_body(item)
|
|
|
+ def _build_report_email_html(self, title, items: list[ProcessResultData]) -> str:
|
|
|
+ body = self._build_report_email_body(items)
|
|
|
html = f"""
|
|
|
<html>
|
|
|
<head>
|
|
@@ -196,63 +195,52 @@ class DataSend:
|
|
|
color: #333;
|
|
|
}}
|
|
|
.container {{
|
|
|
- max-width: 600px;
|
|
|
+ max-width: 1000px;
|
|
|
margin: 0 auto;
|
|
|
background-color: #fff;
|
|
|
padding: 20px;
|
|
|
border-radius: 8px;
|
|
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
|
}}
|
|
|
- .button-container {{
|
|
|
- text-align: center;
|
|
|
- margin-top: 20px;
|
|
|
- }}
|
|
|
- .button {{
|
|
|
- display: inline-block;
|
|
|
- padding: 10px 20px;
|
|
|
- font-size: 16px;
|
|
|
- color: #fff!important;
|
|
|
- background-color: #007bff;
|
|
|
- text-decoration: none;
|
|
|
- border-radius: 5px;
|
|
|
- transition: background-color 0.3s;
|
|
|
- }}
|
|
|
- .button:hover {{
|
|
|
- background-color: #0056b3;
|
|
|
- }}
|
|
|
.system {{
|
|
|
color: #aaa;
|
|
|
+ font-size: 80%;
|
|
|
}}
|
|
|
- .card {{
|
|
|
+ .table-container {{
|
|
|
+ overflow-x: auto;
|
|
|
+ width: 100%;
|
|
|
+ }}
|
|
|
+ .table {{
|
|
|
+ width: 1000px;
|
|
|
background-color: #ffffff;
|
|
|
border: 1px solid #dddddd;
|
|
|
border-radius: 8px;
|
|
|
margin-bottom: 20px;
|
|
|
padding: 20px;
|
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
+ border-collapse: collapse;
|
|
|
}}
|
|
|
- .card h2 {{
|
|
|
- margin-top: 0;
|
|
|
+ .table th, .table td {{
|
|
|
+ padding: 5px;
|
|
|
+ border-bottom: 1px solid #dddddd;
|
|
|
+ word-wrap: break-word;
|
|
|
+ text-align: center;
|
|
|
+ font-size:12px;
|
|
|
}}
|
|
|
- .card p {{
|
|
|
- margin: 0;
|
|
|
+ .table th:not(:first-child), .table td:not(:first-child) {{
|
|
|
+ border-left: 1px solid #dddddd;
|
|
|
}}
|
|
|
- .button-container {{
|
|
|
- text-align: center;
|
|
|
- margin-top: 15px;
|
|
|
+ .table th {{
|
|
|
+ padding: 10px;
|
|
|
+ background-color: #f8f9fa;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size:14px;
|
|
|
}}
|
|
|
- .button {{
|
|
|
- display: inline-block;
|
|
|
- padding: 6px 15px;
|
|
|
- font-size: 14px;
|
|
|
- color: #fff!important;
|
|
|
- background-color: #007bff;
|
|
|
- text-decoration: none;
|
|
|
- border-radius: 3px;
|
|
|
- transition: background-color 0.3s;
|
|
|
+ .table tr:last-child td {{
|
|
|
+ border-bottom: none;
|
|
|
}}
|
|
|
- .button:hover {{
|
|
|
- background-color: #0056b3;
|
|
|
+ .table td a{{
|
|
|
+ color: #007bff;
|
|
|
}}
|
|
|
</style>
|
|
|
</head>
|
|
@@ -268,23 +256,48 @@ class DataSend:
|
|
|
return html
|
|
|
|
|
|
@staticmethod
|
|
|
- def _build_report_email_body(item: ProcessResultData) -> str:
|
|
|
- body = f"""
|
|
|
- <div class="card">
|
|
|
- <h2>{item.title}</h2>
|
|
|
- <p><strong>项目编号:</strong> {item.no}</p>
|
|
|
- <p><strong>公告日期:</strong> {item.date}</p>
|
|
|
- <p><strong>关键词:</strong> {item.keyword}</p>
|
|
|
- <p><strong>价格:</strong> {item.price}</p>
|
|
|
- <p><strong>中标人:</strong> {item.bidder}</p>
|
|
|
- <p><strong>摘要:</strong> {item.summary}</p>
|
|
|
- <div class="button-container">
|
|
|
- <a href="{item.url}" class="button">查看详情</a>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- """
|
|
|
+ def _build_report_email_body(items: list[ProcessResultData]) -> str:
|
|
|
+ if not items:
|
|
|
+ return ""
|
|
|
+
|
|
|
+ body = """
|
|
|
+ <div class="table-container">
|
|
|
+ <table class="table">
|
|
|
+ <tr>
|
|
|
+ <th style="width:200px">项目名称</th>
|
|
|
+ <th style="width:150px">公告日期</th>
|
|
|
+ <th style="width:120px">价格</th>
|
|
|
+ <th>中标人</th>
|
|
|
+ </tr>
|
|
|
+ """
|
|
|
+ for item in items:
|
|
|
+ body += f"""
|
|
|
+ <tr>
|
|
|
+ <td><a title="点击查看详情" href="{item.url}">{item.title}</a></td>
|
|
|
+ <td>{item.date}</td>
|
|
|
+ <td>{item.price}</td>
|
|
|
+ <td>{item.bidder}</td>
|
|
|
+ </tr>
|
|
|
+ """
|
|
|
+ body += "</table></div>"
|
|
|
return body
|
|
|
|
|
|
+ @staticmethod
|
|
|
+ def _gen_report_exlecl(title, items: list[ProcessResultData]) -> str:
|
|
|
+ if not items:
|
|
|
+ return ""
|
|
|
+ # 将 list 数据转换为 DataFrame
|
|
|
+ data = {
|
|
|
+ "项目编号": [item.no for item in items],
|
|
|
+ "项目名称": [item.title for item in items],
|
|
|
+ "公告日期": [item.date for item in items],
|
|
|
+ "价格": [item.price for item in items],
|
|
|
+ "中标人": [item.bidder for item in items],
|
|
|
+ "公告摘要": [item.summary for item in items],
|
|
|
+ "URL": [item.url for item in items],
|
|
|
+ }
|
|
|
+ return utils.save_reort_excel(data, title)
|
|
|
+
|
|
|
def _send_email_no_found(self) -> None:
|
|
|
email = utils.get_config_value("email.error_email")
|
|
|
utils.get_logger().info(f"开始发送区域邮箱未匹配邮件: {email}")
|