From 1ef81def0f7e3d569b7bf0b09e9a8998f714cda5 Mon Sep 17 00:00:00 2001 From: panda <1415243231@qq.com> Date: Mon, 12 Jan 2026 16:27:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9B=A0=E6=97=A0=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=AE=A2=E6=88=B7=E5=AF=BC=E8=87=B4NGV=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=96=B0=E5=A2=9E=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back_ground_module/data_monitor.py | 2 + back_ground_module/update_NGV_data.py | 21 +- ...ate_molecule_reporting_adjustment_to_bi.py | 4 - test/宜搭获取续约待办数据.py | 189 ++++++++++++++++++ test/异常回访待办问题排查.ipynb | 158 +++++++++++++++ test/异常回访待办问题排查.py | 112 +++++++++++ test/续约待办宜搭同步简道云.py | 33 --- tools/BI.ipynb | 8 +- yd_api.py | 58 +++--- 9 files changed, 507 insertions(+), 78 deletions(-) create mode 100644 test/宜搭获取续约待办数据.py create mode 100644 test/异常回访待办问题排查.ipynb create mode 100644 test/异常回访待办问题排查.py delete mode 100644 test/续约待办宜搭同步简道云.py diff --git a/back_ground_module/data_monitor.py b/back_ground_module/data_monitor.py index a9dcddc..337e6de 100644 --- a/back_ground_module/data_monitor.py +++ b/back_ground_module/data_monitor.py @@ -10,6 +10,8 @@ from decimal import Decimal import time import numpy as np import json +import os +os.chdir(Path(__file__).parent) def replace_decimals(obj): diff --git a/back_ground_module/update_NGV_data.py b/back_ground_module/update_NGV_data.py index f6ecddf..f8fe9c6 100644 --- a/back_ground_module/update_NGV_data.py +++ b/back_ground_module/update_NGV_data.py @@ -54,8 +54,8 @@ class UpdateNGVData: timestamp = time.time() - # data_NGV_j.to_csv(os.path.join(output_dir, f"{timestamp}up_NGV_j.csv")) - # data_NGV_j1.to_csv(os.path.join(output_dir, f"{timestamp}up_NGV_j1.csv")) + data_NGV_j.to_csv(os.path.join(output_dir, f"up_NGV_j.csv")) + data_NGV_j1.to_csv(os.path.join(output_dir, f"up_NGV_j1.csv")) # 找出在 data_NGV_j 中存在但在 data_NGV_j1 中不存在的 data_id unique_data_ids = data_NGV_j[~data_NGV_j['org_code'].isin(data_NGV_j1['org_code'])] @@ -111,9 +111,11 @@ class UpdateNGVData: logger.info(f"人员转换完成") # 数字保留3位小数 - filtered_df['g_month_percentage'] = (pd.to_numeric(data_NGV_j['g_month_percentage'], errors='coerce') - .round(3) - .apply(lambda x: f"{x:.3f}" if pd.notna(x) else '')) + filtered_df['g_month_percentage'] = ( + pd.to_numeric(filtered_df['g_month_percentage'], errors='coerce') + .round(3) + .apply(lambda x: f"{x:.3f}" if pd.notna(x) else '') + ) # filtered_df.to_csv(r"D:\Idea Project\SaaS_V1.3\back_ground_module\output\NGV.csv") @@ -138,17 +140,18 @@ class UpdateNGVData: # print(result_str[:500]) # 保存到Excel文件 - # output_path = r'D:\Idea Project\F6+宜搭+其它(1)\new\文件输出\ngv明细1.xlsx' + # output_path = r'D:\Idea Project\SaaS_V1.7\back_ground_module\output\ngv明细1.xlsx' # filtered_df.to_excel(output_path, index=False) - # data_NGV_j1.to_excel( r'D:\Idea Project\F6+宜搭+其它(1)\new\文件输出\ngv明细j1.xlsx', index=False) - # data_NGV_j.to_excel( r'D:\Idea Project\F6+宜搭+其它(1)\new\文件输出\ngv明细j.xlsx', index=False) - # new_df.to_excel(r'D:\Idea Project\F6+宜搭+其它(1)\new\文件输出\ngv明细ndf.xlsx', index=False) + # data_NGV_j1.to_excel( r'D:\Idea Project\SaaS_V1.7\back_ground_module\output\ngv明细j1.xlsx', index=False) + # data_NGV_j.to_excel( r'D:\Idea Project\SaaS_V1.7\back_ground_module\output\ngv明细j.xlsx', index=False) + # new_df.to_excel(r'D:\Idea Project\SaaS_V1.7\back_ground_module\output\ngv明细ndf.xlsx', index=False) common_module.send_task_status(task_start_time, "NGV新增数据") logger.info(f"任务完成。") except Exception as e: error_task_logger.error(f"任务执行时发生异常: {e}") common_module.send_task_error(task_start_time, "NGV新增数据", str(e)) + # pass @staticmethod def row_to_dict(row, field_mapping): diff --git a/back_ground_module/update_molecule_reporting_adjustment_to_bi.py b/back_ground_module/update_molecule_reporting_adjustment_to_bi.py index 7200952..c9c6f13 100644 --- a/back_ground_module/update_molecule_reporting_adjustment_to_bi.py +++ b/back_ground_module/update_molecule_reporting_adjustment_to_bi.py @@ -88,10 +88,6 @@ class MoleculeReportingAdjustment: if id_in_map == field_id: transformed_data[display_name] = value break - - - - # BI上已经实现 # if transformed_data.get("是否上传衡石") == "否" or transformed_data.get("是否上传衡石") is None: # continue diff --git a/test/宜搭获取续约待办数据.py b/test/宜搭获取续约待办数据.py new file mode 100644 index 0000000..cd1334c --- /dev/null +++ b/test/宜搭获取续约待办数据.py @@ -0,0 +1,189 @@ +import os +from datetime import datetime, timezone, timedelta +import pandas as pd +from tqdm import tqdm +import json +from yd_api import YDAPI +from api import API +import time + +output_dir = "output" +os.makedirs(output_dir, exist_ok=True) + +api_instance = API() +yd_api_instance = YDAPI() + +def generate_monthly_ranges(start: str, end: str): + """ + 生成按自然月划分的时间段列表(左闭右开) + 例如: [('2025-11-01T00:00:00Z', '2025-12-01T00:00:00Z'), ...] + """ + start_dt = datetime.fromisoformat(start.replace("Z", "+00:00")) + end_dt = datetime.fromisoformat(end.replace("Z", "+00:00")) + + ranges = [] + current = start_dt + + while current < end_dt: + # 下一个月的第一天 + if current.month == 12: + next_month = current.replace(year=current.year + 1, month=1, day=1) + else: + next_month = current.replace(month=current.month + 1, day=1) + # 不超过 end_dt + segment_end = min(next_month, end_dt) + ranges.append(( + current.strftime("%Y-%m-%dT00:00:00Z"), + segment_end.strftime("%Y-%m-%dT00:00:00Z") + )) + current = next_month + + return ranges + +class GetYDData: + + def __init__(self): + self.FORMID = "FORM-PE866MD1MJMU0WGLYRFLYEN5YN9L1I55Z7ZUK22" + self.appType = "APP_UYZ0KG6L0CCNV80GZ66O" + self.systemToken = "XA966F81JAJOFCVVVKO64E9MIIZV1EWE5SFMKJ2" + + # 第一段:2025-01-01 到 2025-11-01 + first_segment = ("2025-01-01T00:00:00Z", "2025-11-01T00:00:00Z") + + # 第二段:2025-11-01 到当前时间(按月拆分) + now_utc_str = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") + monthly_segments = generate_monthly_ranges("2025-11-01T00:00:00Z", now_utc_str) + + # 合并所有时间段 + self.time_ranges = [first_segment] + monthly_segments + + print("📅 计划拉取以下时间段:") + for i, (s, e) in enumerate(self.time_ranges, 1): + print(f" {i}. {s} → {e}") + + def build_value_to_label_map(self, form_structure): + value_to_label_map = {} + fields = form_structure.get("result", []) + for field in fields: + field_id = field.get("fieldId") + component = field.get("componentName") + props = field.get("props", {}) + data_source = props.get("dataSource", []) + + if component in ["SelectField", "RadioField"] and data_source: + option_map = {} + for opt in data_source: + val = opt.get("value") + if val is None: + continue + text_obj = opt.get("text", {}) + if isinstance(text_obj, dict): + zh_text = text_obj.get("zh_CN") + if zh_text is None and "value" in text_obj: + raw = text_obj["value"] + if isinstance(raw, str) and raw.startswith('"') and raw.endswith('"'): + zh_text = raw[1:-1] + else: + zh_text = str(val) + elif zh_text is None: + zh_text = str(val) + else: + zh_text = str(text_obj) + option_map[str(val)] = zh_text + if option_map: + value_to_label_map[field_id] = option_map + return value_to_label_map + + def convert_record_values(self, record, value_map): + converted = {} + for key, val in record.items(): + if key in value_map and val is not None: + str_val = str(val) + converted[key] = value_map[key].get(str_val, val) + else: + converted[key] = val + return converted + + def fetch_records_in_range(self, token, start_time, end_time): + """拉取指定时间范围内的所有记录""" + try: + first_page = yd_api_instance.read_processes_instances( + token=token, + formUuid=self.FORMID, + page=1, + n=100, + appType=self.appType, + systemToken=self.systemToken, + instanceStatus="RUNNING", + modifiedFromTimeGMT=start_time, + modifiedToTimeGMT=end_time, + ) + except Exception as e: + print(f"❌ 首页请求失败 ({start_time} ~ {end_time}): {e}") + return [] + + total_count = first_page.get("totalCount", 0) + total_pages = (total_count // 100) + (1 if total_count % 100 else 0) + print(f"📊 [{start_time[:10]} ~ {end_time[:10]}] 总记录数: {total_count}, 共 {total_pages} 页") + + all_records = [] + if total_count > 0: + all_records.extend(first_page.get("data", [])) + for page in tqdm(range(2, total_pages + 1), desc=f"{start_time[:7]}"): + try: + resp = yd_api_instance.read_processes_instances( + token=token, + formUuid=self.FORMID, + page=page, + n=100, + appType=self.appType, + systemToken=self.systemToken, + instanceStatus="RUNNING", + modifiedFromTimeGMT=start_time, + modifiedToTimeGMT=end_time, + ) + page_data = resp.get("data", []) + all_records.extend(page_data) + time.sleep(0.15) # 稍微增加间隔,更安全 + except Exception as e: + print(f"⚠️ 第 {page} 页失败 ({start_time[:10]}): {e}") + continue + return all_records + + def main(self): + # Step 1: 获取表单结构 + token = yd_api_instance.generateToken() + form_struct = yd_api_instance.get_form_structures( + token=token, + formUuid=self.FORMID + ) + value_map = self.build_value_to_label_map(form_struct) + print("\n✅ 表单选项映射构建完成") + + # Step 2: 按时间段拉取 + all_records = [] + for start_time, end_time in self.time_ranges: + print(f"\n⏳ 拉取: {start_time} → {end_time}") + records = self.fetch_records_in_range(token, start_time, end_time) + all_records.extend(records) + + print(f"\n📥 总共获取 {len(all_records)} 条流程实例") + + # Step 3: 转换 formData + converted_records = [] + for inst in all_records: + form_data = inst.get("formData", {}) + converted = self.convert_record_values(form_data, value_map) + converted_records.append(converted) + + # Step 4: 保存 + if converted_records: + df = pd.DataFrame(converted_records) + output_path = os.path.join(output_dir, "converted_yd_data.csv") + df.to_csv(output_path, index=False, encoding="utf_8_sig") + print(f"\n✅ 成功保存 {len(converted_records)} 条记录至: {output_path}") + else: + print("\n❌ 无有效数据") + +if __name__ == "__main__": + GetYDData().main() \ No newline at end of file diff --git a/test/异常回访待办问题排查.ipynb b/test/异常回访待办问题排查.ipynb new file mode 100644 index 0000000..a078fee --- /dev/null +++ b/test/异常回访待办问题排查.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "code", + "id": "initial_id", + "metadata": { + "collapsed": true, + "ExecuteTime": { + "end_time": "2026-01-07T02:17:11.661841100Z", + "start_time": "2026-01-07T02:17:11.600589500Z" + } + }, + "source": [ + "from back_ground_module import CommonModule\n", + "from api import API\n", + "from log_config import configure_task_logger, configure_error_task_logger\n", + "from datetime import datetime, timedelta, timezone\n", + "import pandas as pd\n", + "import os\n", + "\n", + "# 获取已经配置好的常规日志记录器\n", + "logger = configure_task_logger()\n", + "# 获取已经配置好的错误任务日志记录器\n", + "error_task_logger = configure_error_task_logger()\n", + "# 保存为CSV文件\n", + "output_dir = \"output\" # 设置输出目录\n", + "# 创建输出目录(如果不存在)\n", + "import os\n", + "\n", + "os.makedirs(output_dir, exist_ok=True)\n", + "common_module = CommonModule()\n", + "api_instance = API()\n", + "\n", + "data_JCB = common_module.get_jcb_details()\n", + "current_local = datetime.now() + timedelta(days=-1) # tz-naive,代表本地时间\n", + "current_date_str = current_local.strftime(\"%Y-%m-%d\")\n", + "# 计算30天前的本地日期(用于开户日判断)\n", + "thirty_days_ago_local = (current_local - timedelta(days=30)).date()\n", + "payload = {\"api_key\": \"6717470a0b3975ef583c6df1\",\n", + " \"entry_id\": \"67174710da507490d8ac12c1\",\n", + " }\n", + "daily_revisit = api_instance.entry_data_list(payload)\n", + "daily_revisit_list = daily_revisit.get(\"data\") # api请求格式,将数据封装在data字典里\n", + "abnormal_data = []\n", + "for index, row in data_JCB.iterrows():\n", + " try:\n", + " # 开户日是本地日期字符串,解析为 date 对象\n", + " open_date = datetime.strptime(str(row['开户日']), \"%Y-%m-%d\").date()\n", + " except (ValueError, TypeError):\n", + " continue # 跳过无效日期\n", + "\n", + " if (\n", + " open_date < thirty_days_ago_local\n", + " and row['近30天开单天数'] == 0\n", + " and row['客户状态'] == \"留存\"\n", + " ):\n", + " new_row = row.copy()\n", + " new_row[\"日期\"] = open_date.strftime(\"%Y-%m-%d\")\n", + " abnormal_data.append(new_row)\n", + "\n", + "abnormal_data = pd.DataFrame(abnormal_data) if abnormal_data else pd.DataFrame()\n", + "\n", + "if not abnormal_data.empty:\n", + " abnormal_data[\"表单类型\"] = \"异常待办\"\n", + " abnormal_data[\"派发日期\"] = current_date_str\n", + "\n", + " # 清洗手机号(仅去除浮点型 .0)\n", + " def clean_phone(x):\n", + " if pd.isna(x) or x == \"\" or x == \"None\":\n", + " return \"\"\n", + " s = str(x)\n", + " if s.endswith('.0') and s[:-2].isdigit():\n", + " return s[:-2]\n", + " return s\n", + "\n", + " abnormal_data['联系手机号'] = abnormal_data['联系手机号'].apply(clean_phone)\n", + "\n", + "# 构建云端已派发记录 DataFrame\n", + "df_cloud = pd.DataFrame([\n", + " {\n", + " \"数据id\": item.get(\"_id\", \"\"),\n", + " \"账号\": item.get(\"_widget_1739258942667\", \"\"),\n", + " \"提交时间\": item.get(\"createTime\", \"\"),\n", + " \"表单类型\": item.get(\"_widget_1739951204545\", \"\")\n", + " }\n", + " for item in daily_revisit_list\n", + "])\n", + "\n", + "recent_accounts = set()\n", + "if not df_cloud.empty and not abnormal_data.empty:\n", + " # 将 createTime 转为 UTC 时间(强制统一时区)\n", + " df_cloud[\"提交时间\"] = pd.to_datetime(df_cloud[\"提交时间\"], utc=True, errors=\"coerce\")\n", + " df_cloud = df_cloud.dropna(subset=[\"提交时间\"])\n", + "\n", + " # 筛选“异常待办”\n", + " df_abnormal_cloud = df_cloud[df_cloud[\"表单类型\"] == \"异常待办\"]\n", + "\n", + " if not df_abnormal_cloud.empty:\n", + " # 每个账号保留最新一条\n", + " df_recent = df_abnormal_cloud.sort_values(\"提交时间\").groupby(\"账号\", as_index=False).tail(1)\n", + "\n", + " current_utc = datetime.now(timezone.utc)\n", + " cutoff_utc = pd.Timestamp(current_utc) - pd.Timedelta(days=30)\n", + "\n", + " # 安全比较:两边都是 UTC\n", + " recent_accounts = set(df_recent[df_recent[\"提交时间\"] > cutoff_utc][\"账号\"])\n", + "\n", + "# 剔除已派发账号 + 过滤有效手机号\n", + "if not abnormal_data.empty:\n", + " abnormal_data = abnormal_data[\n", + " (~abnormal_data[\"账号\"].isin(recent_accounts)) &\n", + " (abnormal_data[\"联系手机号\"].notna()) &\n", + " (abnormal_data[\"联系手机号\"] != \"\") &\n", + " (abnormal_data[\"联系手机号\"] != \"None\")\n", + " ]\n", + "\n", + "# # 保存结果\n", + "output_path = os.path.join(output_dir, \"异常待办1.csv\")\n", + "abnormal_data.to_csv(output_path, index=False)" + ], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'back_ground_module'", + "output_type": "error", + "traceback": [ + "\u001B[31m---------------------------------------------------------------------------\u001B[39m", + "\u001B[31mModuleNotFoundError\u001B[39m Traceback (most recent call last)", + "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[3]\u001B[39m\u001B[32m, line 1\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m1\u001B[39m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mback_ground_module\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m CommonModule\n\u001B[32m 2\u001B[39m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mapi\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m API\n\u001B[32m 3\u001B[39m \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mlog_config\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[38;5;28;01mimport\u001B[39;00m configure_task_logger, configure_error_task_logger\n", + "\u001B[31mModuleNotFoundError\u001B[39m: No module named 'back_ground_module'" + ] + } + ], + "execution_count": 3 + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/test/异常回访待办问题排查.py b/test/异常回访待办问题排查.py new file mode 100644 index 0000000..ad73785 --- /dev/null +++ b/test/异常回访待办问题排查.py @@ -0,0 +1,112 @@ +from back_ground_module import CommonModule +from api import API +from log_config import configure_task_logger, configure_error_task_logger +from datetime import datetime, timedelta, timezone +import pandas as pd +import os + +# 获取已经配置好的常规日志记录器 +logger = configure_task_logger() +# 获取已经配置好的错误任务日志记录器 +error_task_logger = configure_error_task_logger() +# 保存为CSV文件 +output_dir = "output" # 设置输出目录 +# 创建输出目录(如果不存在) +import os + +os.makedirs(output_dir, exist_ok=True) +common_module = CommonModule() +api_instance = API() + +data_JCB = common_module.get_jcb_details() +output_path = os.path.join(output_dir, "借车包明细.csv") +data_JCB.to_csv(output_path, index=False) + +current_local = datetime.now() + timedelta(days=-1) # tz-naive,代表本地时间 +current_date_str = current_local.strftime("%Y-%m-%d") +# 计算30天前的本地日期(用于开户日判断) +thirty_days_ago_local = (current_local - timedelta(days=30)).date() +payload = {"api_key": "6717470a0b3975ef583c6df1", + "entry_id": "67174710da507490d8ac12c1", + } +daily_revisit = api_instance.entry_data_list(payload) +daily_revisit_list = daily_revisit.get("data") # api请求格式,将数据封装在data字典里 +abnormal_data = [] +for index, row in data_JCB.iterrows(): + try: + # 开户日是本地日期字符串,解析为 date 对象 + open_date = datetime.strptime(str(row['开户日']), "%Y-%m-%d").date() + except (ValueError, TypeError): + continue # 跳过无效日期 + + if ( + open_date < thirty_days_ago_local + and row['近30天开单天数'] == 0 + and row['客户状态'] == "留存" + ): + new_row = row.copy() + new_row["日期"] = open_date.strftime("%Y-%m-%d") + abnormal_data.append(new_row) + +abnormal_data = pd.DataFrame(abnormal_data) if abnormal_data else pd.DataFrame() +output_path = os.path.join(output_dir, "异常待办.csv") +abnormal_data.to_csv(output_path, index=False) + +if not abnormal_data.empty: + abnormal_data["表单类型"] = "异常待办" + abnormal_data["派发日期"] = current_date_str + + # 清洗手机号(仅去除浮点型 .0) + def clean_phone(x): + if pd.isna(x) or x == "" or x == "None": + return "" + s = str(x) + if s.endswith('.0') and s[:-2].isdigit(): + return s[:-2] + return s + + abnormal_data['联系手机号'] = abnormal_data['联系手机号'].apply(clean_phone) + +# 构建云端已派发记录 DataFrame +df_cloud = pd.DataFrame([ + { + "数据id": item.get("_id", ""), + "账号": item.get("_widget_1739258942667", ""), + "提交时间": item.get("createTime", ""), + "表单类型": item.get("_widget_1739951204545", "") + } + for item in daily_revisit_list +]) +output_path = os.path.join(output_dir, "异常待办云端.csv") +df_cloud.to_csv(output_path, index=False) +recent_accounts = set() +if not df_cloud.empty and not abnormal_data.empty: + # 将 createTime 转为 UTC 时间(强制统一时区) + df_cloud["提交时间"] = pd.to_datetime(df_cloud["提交时间"], utc=True, errors="coerce") + df_cloud = df_cloud.dropna(subset=["提交时间"]) + + # 筛选“异常待办” + df_abnormal_cloud = df_cloud[df_cloud["表单类型"] == "异常待办"] + + if not df_abnormal_cloud.empty: + # 每个账号保留最新一条 + df_recent = df_abnormal_cloud.sort_values("提交时间").groupby("账号", as_index=False).tail(1) + + current_utc = datetime.now(timezone.utc) + cutoff_utc = pd.Timestamp(current_utc) - pd.Timedelta(days=30) + + # 安全比较:两边都是 UTC + recent_accounts = set(df_recent[df_recent["提交时间"] > cutoff_utc]["账号"]) + +# 剔除已派发账号 + 过滤有效手机号 +if not abnormal_data.empty: + abnormal_data = abnormal_data[ + (~abnormal_data["账号"].isin(recent_accounts)) & + (abnormal_data["联系手机号"].notna()) & + (abnormal_data["联系手机号"] != "") & + (abnormal_data["联系手机号"] != "None") + ] + +# # 保存结果 +output_path = os.path.join(output_dir, "异常待办1.csv") +abnormal_data.to_csv(output_path, index=False) \ No newline at end of file diff --git a/test/续约待办宜搭同步简道云.py b/test/续约待办宜搭同步简道云.py deleted file mode 100644 index f528059..0000000 --- a/test/续约待办宜搭同步简道云.py +++ /dev/null @@ -1,33 +0,0 @@ -from datetime import datetime -import os -from config import Config -import pandas as pd -from back_ground_module import CommonModule -from api import API -from log_config import configure_task_logger, configure_error_task_logger - -logger = configure_task_logger() -error_task_logger = configure_error_task_logger() -output_dir = "output" # 设置输出目录 -os.makedirs(output_dir, exist_ok=True) -common_module = CommonModule() -api_instance = API() - - -class YdToJDYRenewalToDo: - def __init__(self): - pass - - def load_all_data(self): - """ - 从各类来源加载数据上加载数据 - :return: - """ - - def main(self): - pass - - -if __name__ == '__main__': - yd_to_jd_renewal_to_do = YdToJDYRenewalToDo() - yd_to_jd_renewal_to_do.main() diff --git a/tools/BI.ipynb b/tools/BI.ipynb index f2118ed..1573e79 100644 --- a/tools/BI.ipynb +++ b/tools/BI.ipynb @@ -421,8 +421,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-01-06T08:21:20.943512600Z", - "start_time": "2026-01-06T08:21:19.361422Z" + "end_time": "2026-01-06T08:49:37.955377100Z", + "start_time": "2026-01-06T08:49:37.747330400Z" } }, "cell_type": "code", @@ -454,7 +454,7 @@ "\n", " # 使用DELETE删除ID大于等于127821的数据\n", " # cursor.execute(f\"DELETE FROM {table_name} WHERE id >= {min_id_to_delete}\")\n", - " cursor.execute(f\"DELETE FROM GP_monthly_renewal_rate_new WHERE 月分区(仅用于存储每月最后一天截至数据) = '202512';\")\n", + " cursor.execute(f\"DELETE FROM GP_annual_renewal_rate_new WHERE 月分区(仅用于存储每月最后一天截至数据) = '202512';\")\n", "\n", " connection.commit()\n", "\n", @@ -478,7 +478,7 @@ ] } ], - "execution_count": 2 + "execution_count": 7 }, { "metadata": {}, diff --git a/yd_api.py b/yd_api.py index 4b2e94a..2b1df95 100644 --- a/yd_api.py +++ b/yd_api.py @@ -155,7 +155,7 @@ class YDAPI: systemToken="XA966F81JAJOFCVVVKO64E9MIIZV1EWE5SFMKJ2", instanceStatus="RUNNING", max_retries=10, delay=2, createFromTimeGMT=None, createToTimeGMT=None, modifiedFromTimeGMT=None, - modifiedToTimeGMT=None, searchFieldJson={}): + modifiedToTimeGMT=None, searchFieldJson={},useAlias=False): """ 函数功能:读取流程表单的所有数据,并加入重试机制。 @@ -196,7 +196,8 @@ class YDAPI: "modifiedToTimeGMT": modifiedToTimeGMT, "searchFieldJson": json.dumps( searchFieldJson - ) + ), + "useAlias": useAlias, } # print(formData) @@ -460,39 +461,40 @@ class YDAPI: def get_form_structures(self, token, formUuid, appType="APP_UYZ0KG6L0CCNV80GZ66O", systemToken="XA966F81JAJOFCVVVKO64E9MIIZV1EWE5SFMKJ2", max_retries=20): """ - 函数功能:获取表单结构 # 宜搭废弃 - - Args: - token (str): 登录验证token,用于API调用的身份验证。 - formUuid (str): 表单的UUID,标识要获取结构的表单。 - appType - - Returns: - 响应值: 如果请求成功,则返回服务器的JSON响应;如果请求失败或无响应,则返回一个表示获取成功信息的字符串。 + 获取表单结构(宜搭) + 注意:该接口必须使用 GET 方法,参数通过 query string 传递 """ - api = f'https://api.dingtalk.com/v1.0/yida/forms/formFields' - headers = { - "Content-Type": "application/json", - "x-acs-dingtalk-access-token": token - } - retries = 0 - data_get = {} - payload = { - "formUuid": formUuid, + api_base = 'https://api.dingtalk.com/v1.0/yida/forms/formFields' + + # 构造查询参数 + params = { "appType": appType, "systemToken": systemToken, + "formUuid": formUuid, "userId": "2268275546837446", } + + headers = { + "x-acs-dingtalk-access-token": token + } + + retries = 0 while retries < max_retries: - res = requests.post(api, headers=headers, json=payload) - if res.status_code == 200: - data_get = res.json() - break - else: - retries += 1 - time.sleep(0.1) - return data_get + try: + # 使用 GET,并传入 params(自动编码为 query string) + res = requests.get(api_base, headers=headers, params=params, timeout=10) + if res.status_code == 200: + return res.json() + else: + print(f"请求失败,状态码: {res.status_code}, 响应: {res.text}") + except Exception as e: + print(f"请求异常: {e}") + + retries += 1 + time.sleep(0.1) + + return {} # 或抛出异常 class NpEncoder(json.JSONEncoder):