#
#
#
#
# import os
# os.environ['NO_PROXY'] = 'stackoverflow.com'
# import logging
# logging.captureWarnings(True)
# from DrissionPage import ChromiumPage,ChromiumOptions
# import time
# from datetime import datetime, timedelta
# from time import sleep
# from random import randint
# import requests
# import math
# import pandas as pd
# import redis
# import json
# from pathlib import Path
# import re
#
#
#
# class TkOrderExport():
#     def __init__(self):
#         self.page = ChromiumPage()
#         # 修改请求头
#         self.headers = {
#             'accept': '*/*',
#             'accept-language': 'en-US,en;q=0.9', # 'en-US,en;q=0.9'
#             'cache-control': 'no-cache',
#             'content-type': 'application/json; charset=UTF-8',
#             'origin': 'https://www.tiktok.com',
#             'pragma': 'no-cache',
#             'priority': 'u=1, i',
#             'referer': 'https://www.tiktok.com/',
#             'sec-ch-ua': '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
#             'sec-ch-ua-mobile': '?0',
#             'sec-ch-ua-platform': '"Windows"',
#             'sec-fetch-dest': 'empty',
#             'sec-fetch-mode': 'cors',
#             'sec-fetch-site': 'cross-site',
#             'sec-fetch-storage-access': 'active',
#             'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',
#         }
#         self.shop_code = "CNUSCBRZELPJ"
#
#         # 店铺账号
#         self.account = 'Hiboomtiktok@outlook.com'
#         # 下载文件路径
#         self.download_folder = r"D:\Downloads"
#         self.file_suffix = ".xlsx"  # 设置你期望的文件名后缀（包括点）
#         self.receiver_name = 'wangjing5'
#
#         # Redis 配置信息
#         self.REDIS_CONFIG = {
#             'host': '120.79.147.190',  # 外网地址，如需内网可改为 192.168.10.224
#             'port': 6379,  # 端口
#             'db': 13,  # 数据库编号
#             'password': 'Vm5vQH4ydFXh',  # 密码
#             'decode_responses': True  # 自动解码响应为字符串
#         }
#
#         # chrome_options = ChromiumOptions()
#         # chrome_options.set_browser_path(r'C:\Program Files\Google\Chrome\Application\chrome.exe')
#         # chrome_options.set_local_port(9333)  # 设置 Chrome 的调试端口
#         #
#         # self.page = ChromiumPage(addr_or_opts=chrome_options)
#         # print(f"Chrome 浏览器运行在端口: {9333}")
#
#         self.url = "https://affiliate.tiktokglobalshop.com/product/order?shop_region=US"
#         # self.cookies = self.get_cookies()
#         # print(self.cookies)
#
#
#
#
#     def login_with_cookies(self):
#         # 打开目标网站前清空旧 cookies
#         # self.page.clear_cache()
#
#         # 检查是否登录状态
#         try:
#             self.page.get(self.url)
#             login_status = self.page.ele('xpath://span[@id="TikTok_Ads_SSO_Login_Email_Panel_Button"]', timeout=10).text
#             if login_status and str(login_status) == "使用邮箱登录":
#                 print("需要登录")
#                 try:
#                     # 打开一个空白页，否则无法设置 cookie
#                     self.page.get('https://www.tiktok.com')
#
#                     # 设置 cookies
#                     for ck in self.cookies:
#                         self.page.set.cookies(ck)
#
#                     # 重新打开目标网址，此时应为已登录状态
#                     self.page.get(self.url)
#                     cookies = self.page.cookies()
#                     # print(cookies, 111111111111111111)
#                     self.save_cookie(cookies)
#                     # 等待页面加载完成
#                     time.sleep(5)
#
#                 except:
#                     print("登录失败")
#             else:
#                 raise
#         except:
#             print("在登录状态")
#             cookies = self.page.cookies()
#             print(cookies, 22222222222222)
#             self.save_cookie(cookies)
#
#
#     def save_cookie(self,cookies):
#         """将整个 cookies 列表一次性存入 Redis，作为一条 JSON 数据"""
#         key = f"tk_shop_cookie:{self.shop_code}:order:list"
#
#         # 将整个 cookies 列表转换为 JSON 字符串
#         value = json.dumps(cookies, ensure_ascii=False)
#
#         # 存储到 Redis（覆盖旧数据）
#         self.r.set(key, value)
#         print(f"💾 已将 {len(cookies)} 个 cookie 存入 Redis，键为: {key}")
#
#     def get_cookies(self):
#         # self.shop_code = "CNUSCBWZELPC"
#         self.r = redis.StrictRedis(**self.REDIS_CONFIG)
#         """从 Redis 中获取并解析 cookies"""
#         key = f"tk_shop_cookie:{self.shop_code}:order:list"
#         cookie_json = self.r.get(key)
#
#         if cookie_json:
#             cookies = json.loads(cookie_json)
#             print(f"🔄 从 Redis 成功读取 {len(cookies)} 个 cookie")
#             return cookies
#         else:
#             print("❌ 未找到对应的 cookie 数据")
#             return None
#
#
#
#     def change_language(self):
#         # self.login_with_cookies()
#         # 初始化浏览器对象
#         self.page.get("https://affiliate.tiktokglobalshop.com/product/order?shop_region=US")
#         # 等待页面初始加载
#         # time.sleep(randint(6, 10))
#         self.page.set.window.max()
#
#         self.cookies = self.page.cookies()
#         self.save_cookie(self.cookies)
#         # retry_num = 0
#         # max_retry = 1  # 最多重试次数
#         # while retry_num <= max_retry:
#         #     try:
#         #         # 初始化浏览器对象
#         #         self.page.get("https://affiliate.tiktokglobalshop.com/product/order?shop_region=US")
#         #         # 等待页面初始加载
#         #         # time.sleep(randint(6, 10))
#         #         self.page.set.window.max()
#         #
#         #         tou_xiang = self.page.ele('xpath://span[@class="m4b-avatar-image"]', timeout=10)
#         #         tou_xiang.click()
#         #         sleep(randint(5, 10))
#         #
#         #         self.store_name = self.page.ele('xpath://div[@class="text-body-m-medium text-neutral-text1"]',
#         #                                         timeout=10).text
#         #         print('店铺名：', self.store_name)
#         #         sleep(randint(1, 3))
#         #
#         #         self.shop_code = self.page.ele('xpath://div[@class="text-body-s text-neutral-text4"]/span',
#         #                                        timeout=10).text
#         #         self.shop_code = self.shop_code.split(': ')[1]
#         #         print('店铺编号：', self.shop_code)
#         #         sleep(randint(1, 3))
#         #
#         #         language_element = self.page.ele('xpath=(//span[@class="text-neutral-text1 text-body-m-regular"])[3]',
#         #                                          timeout=10)
#         #         language = language_element.text
#         #         print('目前的语言是：', language)
#         #         sleep(randint(5, 10))
#         #
#         #         if language != 'English':
#         #             print('需要转换成英文')
#         #             self.page.actions.move_to(ele_or_loc=language_element)
#         #             sleep(randint(10, 20))
#         #             self.page.ele('xpath://div[text()="English"]', timeout=10).click()
#         #             sleep(randint(5, 10))
#         #             language_element = self.page.ele(
#         #                 'xpath=(//span[@class="text-neutral-text1 text-body-m-regular"])[3]', timeout=10)
#         #             language = language_element.text
#         #             if language == 'English':
#         #                 print('已转换成英文')
#         #                 self.get_tk_order()
#         #                 self.send_success_message_via_wechat()
#         #             else:
#         #                 print('转换英文失败,暂停...')
#         #
#         #         else:
#         #             print('是英文')
#         #             self.get_tk_order()
#         #             self.send_success_message_via_wechat()
#         #         break
#         #
#         #     except Exception as e:
#         #         print(f"change_language出现错误: {e}")
#         #         self.send_error_notification_via_wechat(e)
#         #         if "没有" in str(e):
#         #             retry_num += 1
#         #             sleep(5)
#         #         else:
#         #             raise
#         # self.page.quit()
#
#     def get_tk_order(self):
#         export_orders = self.page.ele('xpath://span[text()="Export orders"]',timeout=10)
#         export_orders.click()
#         print('点击Export orders')
#         sleep(randint(5, 10))
#
#
#         # 获取开始时间
#         start_time_input = self.page.ele(f'xpath://input[@placeholder="Start date"]')
#         self.start_time = start_time_input.attr("value")
#         print(self.start_time)
#
#         # 获取结束时间
#         end_time_input = self.page.ele(f'xpath://input[@placeholder="End date"]')
#         self.end_time = end_time_input.attr("value")
#         print(self.end_time)
#         time.sleep(2)
#
#
#         sleep(randint(3, 6))
#         print('点击Excel')
#         excel = self.page.ele('xpath://div[text()="Excel"]',timeout=10).click()
#
#         print('点击Export')
#         export = self.page.ele('xpath://span[text()="Export"]',timeout=10).click()
#         print('等待导出...')
#         sleep(randint(60, 80))
#
#         file_name = self.page.ele('xpath:(//div[@class="arco-list-item-content"]//span[@data-e2e="16edc1ab-98cd-1ef8"])[1]',timeout=10).text
#         print('file_name: ',file_name)
#
#
#         download = self.page.ele('xpath:(//div[@class="arco-list-content arco-list-virtual"]//span[text()="Download"])[1]',timeout=10).click()
#         print('已点击下载')
#         sleep(randint(10, 20))
#
#         self.save_to_redis(file_name)
#
#
#     def connect_redis(self):
#         """建立 Redis 连接"""
#         self.r = redis.StrictRedis(**self.REDIS_CONFIG)
#         try:
#             self.r.ping()  # 测试连接
#             print("✅ 成功连接到 Redis")
#         except redis.exceptions.ConnectionError as e:
#             print(f"❌ 无法连接到 Redis: {e}")
#             raise
#
#     def read_excel(self, file_path):
#         """读取 Excel 文件内容，并防止数值被转为科学计数法"""
#         print(f"📄 正在读取文件：{file_path}")
#
#         # 假设 'Order ID'、'Product ID' 这类字段容易被转成科学计数法
#         columns_to_keep_as_string = ['Order ID', 'Product ID']  # 替换为你实际的列名
#
#         # 构造 dtype 字典，强制这些列为字符串类型
#         dtype_mapping = {col: str for col in columns_to_keep_as_string}
#
#         # 读取 Excel，指定某些列为字符串
#         df = pd.read_excel(file_path, dtype=dtype_mapping)
#
#         data = df.to_dict(orient='records')  # 转换为字典列表
#         print(f"📊 已读取 {len(data)} 条记录")
#         return data
#
#     def store_data_in_redis(self,r, data, shop_code):
#         """将数据存储到 Redis 中，所有相同 shop_code 的记录使用同一个列表结构存储"""
#         key = f"tk_shop_order:{shop_code}:order:list"
#
#         for idx, record in enumerate(data):
#             # 替换 NaN 为 空字符串
#             cleaned_record = {
#                 key: ("" if isinstance(value, float) and math.isnan(value) else value)
#                 for key, value in record.items()
#             }
#
#             # 序列化前确保没有 NaN
#             value = json.dumps(cleaned_record, ensure_ascii=False)
#
#             r.rpush(key, value)
#             print(f"💾 存储键: {key}，新增记录")
#
#
#     def find_latest_file(self, file_name, max_retries=1, retry_interval=10):
#         """
#         查找最新生成的 .xlsx 文件，若未找到则重试一次。
#
#         :param file_name: 文件名前缀
#         :param max_retries: 最大重试次数
#         :param retry_interval: 每次重试间隔时间（秒）
#         :return: 最新文件路径（字符串）
#         """
#         retry_count = 0
#
#         while retry_count <= max_retries:
#             download_path = Path(self.download_folder)
#
#             # 查找所有匹配的 .xlsx 文件
#             matching_files = [
#                 f for f in download_path.iterdir()
#                 if f.is_file() and f.name.startswith(file_name) and f.suffix == '.xlsx'
#             ]
#
#             if matching_files:
#                 # 定义一个从文件名提取时间戳的函数（假设时间戳是14位数字）
#                 def extract_timestamp(file_path):
#                     match = re.search(r'\d{14}', file_path.name)
#                     return match.group(0) if match else None
#
#                 # 根据文件名中的时间戳排序，取最新的文件
#                 latest_file = max(matching_files, key=lambda f: extract_timestamp(f) or '0')
#                 return str(latest_file)
#
#             # 没有找到文件时的处理
#             if retry_count < max_retries:
#                 print(f"未找到以 '{file_name}' 开头的 .xlsx 文件，第 {retry_count + 1} 次重试...")
#                 time.sleep(retry_interval)
#             retry_count += 1
#
#         # 超出最大重试次数仍未找到
#         raise FileNotFoundError(
#             f"在 {self.download_folder} 中经过 {max_retries} 次重试，"
#             f"仍未找到以 '{file_name}' 开头的 .xlsx 文件"
#         )
#
#     def save_to_redis(self,file_name):
#         EXCEL_FILE = self.find_latest_file(file_name)
#         print(f'保存文件：{EXCEL_FILE}')
#         data = self.read_excel(EXCEL_FILE)
#         self.store_data_in_redis(self.r, data, self.shop_code)
#         print(f"完成保存到redis")
#
#     def send_success_message_via_wechat(self):
#         webhook_url = 'http://47.112.96.71:8082/selection/sendMessage'  # 替换为你的企业微信机器人的Webhook URL
#         data = {
#             "account": self.receiver_name,
#             "title": '【TK订单导出成功提醒】',
#             "content": f'账号: {self.account}, 店铺: {self.store_name},下载文件范围时间：{self.start_time} - {self.end_time}, 程序运行时间: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}'
#         }
#
#         response = requests.post(url=webhook_url, data=data, timeout=15)
#         if response.status_code == 200:
#             print("已成功发送通知到企业微信")
#         else:
#             print(f"发送通知失败: {response.text}")
#
#     def send_error_notification_via_wechat(self,error_message):
#         webhook_url = 'http://47.112.96.71:8082/selection/sendMessage'  # 替换为你的企业微信机器人的Webhook URL
#         data = {
#             "account": self.receiver_name,
#             'title':'【TK订单导出异常提醒】',
#             'content':f'账号：{self.account}，店铺：{self.store_name},错误信息：{error_message}, 时间: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}'
#         }
#
#         response = requests.post(url=webhook_url, data=data,timeout=15)
#         if response.status_code == 200:
#             print("已成功发送错误通知到企业微信")
#         else:
#             print(f"发送错误通知失败: {response.text}")
#
#
#     def run(self):
#         self.connect_redis()
#         self.change_language()
#
#
# if __name__ == '__main__':
#     TkOrderExport().run()
#
#
#
#
#