320 lines
14 KiB
Python
320 lines
14 KiB
Python
import requests
|
||
from module import F6_module
|
||
import time
|
||
import pandas as pd
|
||
import re
|
||
from typing import Dict, Any, Optional
|
||
|
||
f6_module = F6_module()
|
||
|
||
entry_data = {
|
||
"data": {
|
||
"账号": "18742526670",
|
||
"密码": "Zy18742526670",
|
||
"公司名称": "F6汽车科技数据组测试(废弃)"
|
||
}
|
||
}
|
||
|
||
username = entry_data['data']['账号']
|
||
password = entry_data['data']['密码']
|
||
company_name = entry_data['data']['公司名称']
|
||
|
||
|
||
res = f6_module.login_in(username, password, company_name)
|
||
cookies = requests.utils.dict_from_cookiejar(res.cookies)
|
||
|
||
|
||
df = pd.read_excel(fr"D:\Idea Project\简道云\模板文件\客户信息修改.xlsx", sheet_name=0).astype( str)
|
||
# headers = {
|
||
# 'accept': 'application/json, text/plain, */*',
|
||
# 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
|
||
# 'priority': 'u=1, i',
|
||
# 'referer': 'https://yunxiu.f6car.cn/erp/view/index.html',
|
||
# 'sec-ch-ua': '"Not)A;Brand";v="8", "Chromium";v="138", "Microsoft Edge";v="138"',
|
||
# 'sec-ch-ua-mobile': '?0',
|
||
# 'sec-ch-ua-platform': '"Windows"',
|
||
# 'sec-fetch-dest': 'empty',
|
||
# 'sec-fetch-mode': 'cors',
|
||
# 'sec-fetch-site': 'same-origin',
|
||
# 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0',
|
||
# 'x-requested-with': 'XMLHttpRequest',
|
||
# # 'cookie': 'memberSESSIONID=51cbcae1-6734-4ff2-8440-0ba499afb046; erpLanguage=zh-CN; prodOrg=11240984669917217520; unp=15865484595890778191; un=15865484595890778191; _up=-NillNN-qyBEJ--t3vnSknvoOF53y_SJuMkA2n43U-daUfnArpjQjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqEfAQq4Ih0AAM_PBRv-ZNHu3M-GTc1p60EX-sq-RQgeIal1HLPxpurEj90B7u9sDXaGA.; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2215865484595890778191%22%2C%22first_id%22%3A%22198318ea9e5465-0620cc84e196ca8-4c657b58-1327104-198318ea9e61865%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%22198318ea9e5465-0620cc84e196ca8-4c657b58-1327104-198318ea9e61865%22%7D; tmall=false; Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a=1753239849,1753319248,1753329553,1753429373; Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a=1753429373; HMACCOUNT=6C57D3B85B36E54F',
|
||
# }
|
||
|
||
params = {
|
||
'pageSize': 100,
|
||
'pageNo': '1',
|
||
}
|
||
|
||
res = requests.get(
|
||
'https://yunxiu.f6car.cn/member/customer/listForPermission',
|
||
params=params,
|
||
cookies=cookies,
|
||
# headers=headers,
|
||
)
|
||
|
||
total = int(res.json().get("data").get("total"))
|
||
total_pages = (total // params["pageSize"]) + (1 if total % params["pageSize"] > 0 else 0)
|
||
total_pages = 2
|
||
print(f"总计{total_pages}页")
|
||
|
||
all_customers = []
|
||
max_retries = 10
|
||
retry_count = 0
|
||
for page in range(1, total_pages + 1):
|
||
print(f"正在请求第 {page} 页...")
|
||
params["currentPage"] = page
|
||
|
||
while retry_count < max_retries:
|
||
response = requests.get(
|
||
'https://yunxiu.f6car.cn/member/customer/listForPermission',
|
||
params=params,
|
||
cookies=cookies,
|
||
# headers=headers,
|
||
timeout=10
|
||
)
|
||
time.sleep(1)
|
||
if response.status_code == 200:
|
||
suppliers = response.json().get("data", {}).get("data", [])
|
||
print(suppliers)
|
||
all_customers.extend(suppliers)
|
||
break
|
||
else:
|
||
retry_count += 1
|
||
print(f"请求第 {page} 页失败,正在重试(第 {retry_count} 次)...")
|
||
time.sleep(3)
|
||
|
||
# try:
|
||
|
||
# except Exception as e:
|
||
# print(f"请求第 {page} 页失败,错误:", e)
|
||
# continue
|
||
|
||
# 获取专属运营顾问列表
|
||
json_data = {
|
||
'includeStopedEmployee': False,
|
||
'pageSize': 1000,
|
||
'filterNullUser': False,
|
||
'keyword': '',
|
||
'idOwnOrgList': [],
|
||
}
|
||
|
||
response = requests.post(
|
||
'https://yunxiu.f6car.cn/hive/employee/searchStaffInGroup',
|
||
cookies=cookies,
|
||
# headers=headers,
|
||
json=json_data,
|
||
)
|
||
|
||
# Note: json_data will not be serialized by requests
|
||
# exactly as it was in the original request.
|
||
# data = '{"includeStopedEmployee":false,"pageSize":10,"filterNullUser":false,"keyword":"","idOwnOrgList":[]}'
|
||
# response = requests.post('https://yunxiu.f6car.cn/hive/employee/searchStaffInGroup', cookies=cookies, headers=headers, data=data)
|
||
staff_list = response.json().get("data").get("list")
|
||
name_to_userid = {
|
||
emp['name']: emp['userId']
|
||
for emp in staff_list
|
||
if emp['userId'] is not None
|
||
}
|
||
df['userId'] = df['专属运营顾问'].map(name_to_userid)
|
||
|
||
|
||
def extract_province_city_district(address: Optional[str]) -> Dict[str, Optional[str]]:
|
||
"""安全解析省市区信息,所有返回值都可能为None"""
|
||
if not address:
|
||
return {'省': None, '市': None, '区': None}
|
||
|
||
try:
|
||
pattern = r'(?P<省>(?:[\u4e00-\u9fa5]+(?:省|自治区|特别行政区))?)' \
|
||
r'(?P<市>(?:[\u4e00-\u9fa5]+(?:市|自治州|地区|盟))?)' \
|
||
r'(?P<区>(?:[\u4e00-\u9fa5]+区|[\u4e00-\u9fa5]+县|[\u4e00-\u9fa5]+旗)?)'
|
||
match = re.match(pattern, address.strip())
|
||
return {k: v if v else None for k, v in match.groupdict().items()} if match else {'省': None, '市': None,
|
||
'区': None}
|
||
except Exception:
|
||
return {'省': None, '市': None, '区': None}
|
||
|
||
|
||
def safe_get(d: Optional[Dict], *keys, default=None):
|
||
"""多层字典安全获取值,始终返回可能为None的值"""
|
||
if not isinstance(d, dict):
|
||
return default
|
||
|
||
for key in keys:
|
||
d = d.get(key, {})
|
||
if not isinstance(d, dict):
|
||
break
|
||
return d if d != {} else default
|
||
|
||
|
||
def convert_to_request_data(original_data: Optional[Dict[str, Any]], df: pd.DataFrame) -> Dict[str, Any]:
|
||
"""
|
||
完全安全的字典转换函数
|
||
特点:
|
||
1. 每个字段的值都可能为None
|
||
2. 不会因为任何字段为空而报错
|
||
3. 不使用任何默认值,完全保留原始数据的空值状态
|
||
"""
|
||
# 安全获取嵌套数据,所有中间步骤都可能为None
|
||
customer_info = safe_get(original_data, 'data', 'customerInfo') if original_data else None
|
||
|
||
# 安全解析地址信息(结果中的省市区都可能为None)
|
||
address_parts = extract_province_city_district(
|
||
safe_get(customer_info, 'provinceCityAreaName') if customer_info else None
|
||
)
|
||
|
||
# 获取当前客户的手机号
|
||
cell_phone = safe_get(customer_info, 'cellPhone')
|
||
|
||
# 从DataFrame中查找匹配的专属运营顾问信息
|
||
exclusive_info = None
|
||
df_row = None
|
||
if cell_phone and not df.empty:
|
||
matched_rows = df[df['客户手机号'] == cell_phone]
|
||
if not matched_rows.empty:
|
||
df_row = matched_rows.iloc[0]
|
||
exclusive_info = {
|
||
'userId': df_row.get('userId'),
|
||
'name': df_row.get('专属运营顾问')
|
||
}
|
||
|
||
# 构建请求数据字典,所有字段都允许为None
|
||
request_data = {
|
||
# 标识字段
|
||
"pkId": safe_get(customer_info, 'idCustomer'),
|
||
"idCustomer": safe_get(customer_info, 'idCustomer'),
|
||
|
||
# 基本信息 - 从DataFrame中获取或保留原值
|
||
"name": df_row.get('客户姓名') if df_row is not None and pd.notna(df_row.get('客户姓名')) else safe_get(
|
||
customer_info, 'name'),
|
||
"sex": safe_get(customer_info, 'sex'),
|
||
"customerType": df_row.get('客户类型') if df_row is not None and pd.notna(df_row.get('客户类型')) else safe_get(
|
||
customer_info, 'customerType'),
|
||
|
||
# 来源信息 - 从DataFrame中获取或保留原值
|
||
"customerSource": safe_get(customer_info, 'customerSource'),
|
||
"customerSourceName": df_row.get('客户来源') if df_row is not None and pd.notna(
|
||
df_row.get('客户来源')) else safe_get(customer_info, 'customerSourceName'),
|
||
|
||
# 联系信息 - 从DataFrame中获取或保留原值
|
||
"companyName": df_row.get('单位名称') if df_row is not None and pd.notna(df_row.get('单位名称')) else safe_get(
|
||
customer_info, 'companyName'),
|
||
"cellPhone": cell_phone,
|
||
"wechart": safe_get(customer_info, 'wechart'),
|
||
"qq": safe_get(customer_info, 'qq'),
|
||
"contacts": safe_get(customer_info, 'contacts'),
|
||
"contactTelephone": safe_get(customer_info, 'contactTelephone'),
|
||
|
||
# 地址信息(全部允许为None)
|
||
"province": safe_get(customer_info, 'province'),
|
||
"city": safe_get(customer_info, 'city'),
|
||
"area": safe_get(customer_info, 'area'),
|
||
"street": safe_get(customer_info, 'street'),
|
||
"address": safe_get(customer_info, 'address'),
|
||
"detailAddress": safe_get(customer_info, 'detailAddress'),
|
||
"pId": safe_get(customer_info, 'province'),
|
||
"cId": safe_get(customer_info, 'city'),
|
||
"aId": safe_get(customer_info, 'area'),
|
||
"provinceName": address_parts.get('省'),
|
||
"cityName": address_parts.get('市'),
|
||
"areaName": address_parts.get('区'),
|
||
"provinceCityAreaName": safe_get(customer_info, 'provinceCityAreaName'),
|
||
|
||
# 时间信息
|
||
"birthday": safe_get(customer_info, 'birthday'),
|
||
"creationtime": safe_get(customer_info, 'creationtime'),
|
||
"modifiedtime": safe_get(customer_info, 'modifiedtime'),
|
||
|
||
# 系统信息
|
||
"creator": safe_get(customer_info, 'creator'),
|
||
"creatorName": safe_get(customer_info, 'creatorName'),
|
||
"modifier": safe_get(customer_info, 'modifier'),
|
||
"idOwnOrg": safe_get(customer_info, 'idOwnOrg'),
|
||
"idOwnGroup": safe_get(customer_info, 'idOwnGroup'),
|
||
|
||
# 个人资料
|
||
"insuranceCompany": safe_get(customer_info, 'insuranceCompany'),
|
||
"maritalStatus": safe_get(customer_info, 'maritalStatus'),
|
||
"monthlyIncome": safe_get(customer_info, 'monthlyIncome'),
|
||
"idNumber": safe_get(customer_info, 'idNumber'),
|
||
"personHobby": safe_get(customer_info, 'personHobby'),
|
||
"credentialsType": safe_get(customer_info, 'credentialsType'),
|
||
|
||
# 数值信息
|
||
"points": safe_get(customer_info, 'points'),
|
||
"maxAccountAmount": safe_get(customer_info, 'maxAccountAmount'),
|
||
"pointsEnable": safe_get(customer_info, 'pointsEnable'),
|
||
|
||
# 会员信息
|
||
"level": safe_get(customer_info, 'level'),
|
||
"memberCardNo": safe_get(customer_info, 'memberCardNo'),
|
||
"customerLevel": safe_get(customer_info, 'customerLevel'),
|
||
|
||
# 关联信息
|
||
"exclusiveConsultantId": exclusive_info['userId'] if exclusive_info else safe_get(customer_info,
|
||
'exclusiveConsultantId'),
|
||
"exclusiveConsultantName": exclusive_info['name'] if exclusive_info else safe_get(customer_info,
|
||
'exclusiveConsultantName'),
|
||
"exclusiveOrgId": safe_get(customer_info, 'exclusiveOrgId'),
|
||
"exclusiveOrgName": safe_get(customer_info, 'exclusiveOrgName'),
|
||
|
||
# 备注信息 - 从DataFrame中获取或保留原值
|
||
"customerMemo": df_row.get('客户备注') if df_row is not None and pd.notna(df_row.get('客户备注')) else safe_get(
|
||
customer_info, 'customerMemo'),
|
||
|
||
# 其他字段
|
||
"isDel": safe_get(customer_info, 'isDel'),
|
||
"idFrom": safe_get(customer_info, 'idFrom'),
|
||
"mnemonic": safe_get(customer_info, 'mnemonic'),
|
||
"idOrgSource": safe_get(customer_info, 'idOrgSource'),
|
||
"firstArrivalIdSourceBill": safe_get(customer_info, 'firstArrivalIdSourceBill'),
|
||
"lastArrivalIdSourceBill": safe_get(customer_info, 'lastArrivalIdSourceBill'),
|
||
"customerInfoType": safe_get(customer_info, 'customerInfoType'),
|
||
"customerInfoCompleteDate": safe_get(customer_info, 'customerInfoCompleteDate'),
|
||
"customerInfoCompleteType": safe_get(customer_info, 'customerInfoCompleteType'),
|
||
"xczUserId": safe_get(customer_info, 'xczUserId'),
|
||
"xczUuid": safe_get(customer_info, 'xczUuid'),
|
||
"idWxbCustomer": safe_get(customer_info, 'idWxbCustomer'),
|
||
"promoteEmployeeId": safe_get(customer_info, 'promoteEmployeeId'),
|
||
"promoteEmployeeName": safe_get(customer_info, 'promoteEmployeeName'),
|
||
"promoteMemberId": safe_get(customer_info, 'promoteMemberId'),
|
||
"promoteMemberName": safe_get(customer_info, 'promoteMemberName'),
|
||
"driverExpiryDate": safe_get(customer_info, 'driverExpiryDate'),
|
||
"crmDeleteExclusiveFlag": safe_get(customer_info, 'crmDeleteExclusiveFlag'),
|
||
"totalObtainPoints": safe_get(customer_info, 'totalObtainPoints'),
|
||
"totalUsedPoints": safe_get(customer_info, 'totalUsedPoints'),
|
||
"orgName": safe_get(customer_info, 'orgName'),
|
||
"weChatFollower": safe_get(customer_info, 'weChatFollower'),
|
||
"pointsEnableConfig": safe_get(customer_info, 'pointsEnableConfig'),
|
||
"personalPointsEnableConfig": safe_get(customer_info, 'personalPointsEnableConfig'),
|
||
"pointsButtonStatus": safe_get(customer_info, 'pointsButtonStatus'),
|
||
"tmallInstallMember": safe_get(customer_info, 'tmallInstallMember'),
|
||
"corpId": safe_get(customer_info, 'corpId'),
|
||
"thirdCorpId": safe_get(customer_info, 'thirdCorpId'),
|
||
}
|
||
|
||
return request_data
|
||
|
||
|
||
new_customers = []
|
||
for customer in all_customers:
|
||
phone = customer.get("cellPhone")
|
||
if phone in df["客户手机号"].tolist():
|
||
print("开始修改")
|
||
cus_id = customer.get("idCustomer", {})
|
||
# 获取客户id
|
||
cus_response = requests.get(f'https://yunxiu.f6car.cn/member/customer/{cus_id}', cookies=cookies,
|
||
# headers=headers
|
||
) # 做过滤,如果请求结果少于目前条数,则不执行
|
||
original_data = cus_response.json()
|
||
final_json_data = convert_to_request_data(original_data, df)
|
||
# 修改
|
||
response = requests.post(
|
||
'https://yunxiu.f6car.cn/member/customer/modifyCustomer',
|
||
cookies=cookies,
|
||
# headers=headers,
|
||
json=final_json_data,
|
||
)
|
||
print("修改完成")
|
||
time.sleep(1)
|