Files
eu_active_script/hang/daily-active-check-eu-oj.py

183 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pandas as pd
import pymysql
from sqlalchemy import create_engine
import requests
import json
import pandas as pd
from datetime import datetime
import os
def get_access_token():
"""获取飞书访问令牌"""
api_token_url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
api_post_data = {"app_id": "cli_a8b50ec0eed1500d", "app_secret": "ccxkE7ZCFQZcwkkM1rLy0ccZRXYsT2xK"}
response = requests.post(api_token_url, json=api_post_data)
if response.status_code == 200 and response.json().get("code") == 0:
return response.json()["tenant_access_token"]
else:
raise Exception(f"获取 Token 失败: {response.text}")
def overwrite_data(spreadsheet_token, values, access_token=None):
"""覆盖写入数据到飞书多维表格"""
if not access_token:
access_token = get_access_token()
url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values"
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json; charset=utf-8",
}
row_count = len(values) + 1
range_str = f"46ea20!A1:B{row_count}"
post_data = {
"valueRange": {
"range": range_str,
"values": values
}
}
response = requests.put(url, json=post_data, headers=headers)
return response # 返回响应对象以便检查状态
# 数据库连接配置
DB_CONFIG = {
'host': 'eutsp-prod.mysql.germany.rds.aliyuncs.com',
'port': 3306,
'user': 'international_tsp_eu_r',
'password': 'ZXhBgo1TB2XbF3kP',
'database': 'chery_international_tsp_eu'
}
def fetch_data_from_db():
"""从数据库执行SQL查询获取数据"""
connection = pymysql.connect(**DB_CONFIG)
try:
sql_query = """
SELECT
v_vehicle_info.VIN AS car_vins,
CASE v_sim_info.STATE
WHEN 2 THEN 'active'
ELSE 'no_active'
END AS active_status,
v_vehicle_info.MATERIAL_ID as MATERIAL,
v_vehicle_info.SALES_TERRITORY as Area,
v_sim_info.ACTIVATION_DATE as active_date
FROM v_vehicle_info
JOIN v_tbox_info USING (VIN)
JOIN v_sim_info USING (SN);
"""
return pd.read_sql(sql_query, connection)
finally:
connection.close()
def send_feishu_message(webhook_url, message, spreadsheet_token=None):
"""
通过Webhook发送飞书消息支持添加多维表格链接
:param webhook_url: 机器人Webhook地址
:param message: 要发送的文本内容
:param spreadsheet_token: 多维表格ID可选
"""
headers = {'Content-Type': 'application/json'}
# 如果有提供多维表格ID添加表格链接按钮
if spreadsheet_token:
# 创建多维表格链接
spreadsheet_url = f"https://my-ichery.feishu.cn/sheets/{spreadsheet_token}"
# 使用交互式消息卡片格式
payload = {
"msg_type": "interactive",
"card": {
"config": {
"wide_screen_mode": True
},
"elements": [{
"tag": "div",
"text": {
"content": message,
"tag": "lark_md"
}
}, {
"actions": [{
"tag": "button",
"text": {
"content": "查看多维表格",
"tag": "plain_text"
},
"type": "primary",
"url": spreadsheet_url
}],
"tag": "action"
}],
"header": {
"title": {
"content": "数据同步完成通知",
"tag": "plain_text"
},
"template": "green"
}
}
}
else:
# 普通文本消息
payload = {
"msg_type": "text",
"content": {"text": message}
}
response = requests.post(webhook_url, headers=headers, data=json.dumps(payload))
return response.json()
if __name__ == '__main__':
# 配置参数
SPREADSHEET_ID = "MIqssvuB3h3XmgtkI26cBX7Angc"
WEBHOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/d82e4ada-8f78-40ae-b98e-75af0c448c95"
try:
# 1. 从数据库获取数据
df = fetch_data_from_db()
# 2. 处理数据
df['active_date'] = pd.to_datetime(df['active_date'], errors='coerce')
active_df = df[df['active_status'] == 'active']
# 3. 按天统计活跃数
daily_count = active_df.groupby(active_df['active_date'].dt.date).size().reset_index(name='active_count')
values = [[str(d), c] for d, c in daily_count.values.tolist()]
# 4. 覆盖写入多维表格
response = overwrite_data(SPREADSHEET_ID, values)
if response.status_code == 200:
# 5. 构建通知消息
current_time = datetime.now().strftime("%Y-%m-%d %H:%M")
stats_summary = f"• 今日活跃车辆: {daily_count['active_count'].iloc[-1] if len(daily_count) > 0 else 0}\n"
stats_summary += f"• 本周活跃车辆: {daily_count[daily_count['active_date'] >= (datetime.now() - pd.Timedelta(days=7)).date()]['active_count'].sum()}\n"
stats_summary += f"• 累计活跃车辆: {len(active_df)}"
message = f"🚗 车辆数据同步完成 ✅\n"
message += f"⏰ 时间: {current_time}\n"
message += f"📊 统计摘要:\n{stats_summary}\n"
message += "[安全关键词:告警]"
# 6. 发送包含多维表格链接的通知
result = send_feishu_message(WEBHOOK_URL, message, SPREADSHEET_ID)
print("飞书消息发送成功:", result)
else:
error_msg = f"表格写入失败: {response.status_code} - {response.text}"
error_message = f"❌ 数据同步失败\n{error_msg}\n[安全关键词:告警]"
send_feishu_message(WEBHOOK_URL, error_message)
print(error_msg)
except Exception as e:
error_message = f"❌ 数据同步异常: {str(e)}\n[安全关键词:告警]"
send_feishu_message(WEBHOOK_URL, error_message)
print("发生异常:", str(e))