增加公共下载进度、增加接收SKU、密钥分别存放

This commit is contained in:
super
2026-05-28 16:41:20 +08:00
parent ca4a2cd07a
commit 2ed1250604
119 changed files with 4077 additions and 293 deletions

View File

@@ -4,6 +4,8 @@ import json
import sys
import shutil
import os
import uuid
import ctypes
os.makedirs(cache_path,exist_ok=True)
if not debug:
today = datetime.datetime.now().strftime("%Y_%m_%d")
@@ -186,17 +188,7 @@ class WindowAPI:
if not result:
return {'success': False, 'error': '用户取消'}
path = result[0] if isinstance(result, (list, tuple)) else result
try:
import requests
resp = requests.get(url.strip(), timeout=120, stream=True)
resp.raise_for_status()
with open(path, 'wb') as f:
for chunk in resp.iter_content(chunk_size=65536):
if chunk:
f.write(chunk)
return {'success': True, 'path': path}
except Exception as e:
return {'success': False, 'error': str(e)}
return self._download_url_to_path(url, path)
def save_file_from_url_new(self, url, default_filename='download.bin'):
"""弹窗选择保存位置,从 url 下载文件并保存。根据文件后缀动态设置保存类型。"""
@@ -230,18 +222,124 @@ class WindowAPI:
return {'success': False, 'error': '用户取消'}
path = result[0] if isinstance(result, (list, tuple)) else result
return self._download_url_to_path(url, path)
def save_file_from_url_with_progress(self, url, default_filename='download.bin', download_id=''):
"""弹窗选择保存位置,从 url 下载文件并通过前端事件上报下载进度。"""
print("调用到save_file_from_url_with_progress方法")
if not url or not url.strip():
return {'success': False, 'error': '下载地址为空'}
filename = str(default_filename or 'download.bin').strip() or 'download.bin'
ext = os.path.splitext(filename)[1].lower()
if ext == '.zip':
file_types = ('ZIP 压缩包 (*.zip)', '所有文件 (*.*)')
elif ext in ('.xlsx', '.xls'):
file_types = ('Excel 文件 (*.xlsx;*.xls)', '所有文件 (*.*)')
elif ext == '.csv':
file_types = ('CSV 文件 (*.csv)', '所有文件 (*.*)')
elif ext == '.txt':
file_types = ('文本文件 (*.txt)', '所有文件 (*.*)')
elif ext == '.json':
file_types = ('JSON 文件 (*.json)', '所有文件 (*.*)')
else:
file_types = ('所有文件 (*.*)',)
result = self._window.create_file_dialog(
webview.SAVE_DIALOG,
save_filename=filename,
file_types=file_types
)
if not result:
return {'success': False, 'error': '用户取消'}
path = result[0] if isinstance(result, (list, tuple)) else result
progress_id = str(download_id or uuid.uuid4())
return self._download_url_to_path(url, path, progress_id)
def _download_url_to_path(self, url, path, download_id=''):
"""先下载到临时文件,完整下载后再替换为最终文件,避免用户打开半成品。"""
final_path = os.path.abspath(path)
final_dir = os.path.dirname(final_path) or os.getcwd()
final_name = os.path.basename(final_path)
temp_path = os.path.join(final_dir, f".{final_name}.crdownload")
last_progress_emit = 0.0
last_progress_percent = -1
try:
import requests
os.makedirs(final_dir, exist_ok=True)
if os.path.exists(temp_path):
os.remove(temp_path)
resp = requests.get(url.strip(), timeout=120, stream=True)
resp.raise_for_status()
with open(path, 'wb') as f:
total = int(resp.headers.get('Content-Length') or 0)
downloaded = 0
self._emit_download_progress(download_id, 'running', final_path, downloaded, total)
with open(temp_path, 'wb') as f:
self._hide_file(temp_path)
for chunk in resp.iter_content(chunk_size=65536):
if chunk:
f.write(chunk)
return {'success': True, 'path': path}
downloaded += len(chunk)
percent = int(downloaded * 100 / total) if total else 0
now_time = time.time()
if percent != last_progress_percent or now_time - last_progress_emit >= 0.2:
self._emit_download_progress(download_id, 'running', final_path, downloaded, total)
last_progress_emit = now_time
last_progress_percent = percent
f.flush()
os.fsync(f.fileno())
self._show_file(temp_path)
os.replace(temp_path, final_path)
self._emit_download_progress(download_id, 'success', final_path, downloaded, total)
return {'success': True, 'path': final_path}
except Exception as e:
try:
if os.path.exists(temp_path):
os.remove(temp_path)
except Exception:
pass
self._emit_download_progress(download_id, 'failed', final_path, 0, 0, str(e))
return {'success': False, 'error': str(e)}
def _emit_download_progress(self, download_id, status, path, downloaded, total, error=''):
if not download_id:
return
payload = {
'id': download_id,
'status': status,
'path': path,
'downloaded': downloaded,
'total': total,
'percent': round(downloaded * 100 / total, 1) if total else 0,
'error': error,
}
script = (
"window.dispatchEvent(new CustomEvent('pywebview-download-progress', "
f"{{ detail: {json.dumps(payload, ensure_ascii=False)} }}));"
)
try:
self._window.evaluate_js(script)
except Exception:
pass
def _hide_file(self, path):
"""Windows 下隐藏临时下载文件,减少用户误打开半成品的机会。"""
if os.name != 'nt':
return
try:
ctypes.windll.kernel32.SetFileAttributesW(path, 0x02)
except Exception:
pass
def _show_file(self, path):
"""恢复普通文件属性,避免最终保存文件被隐藏。"""
if os.name != 'nt':
return
try:
ctypes.windll.kernel32.SetFileAttributesW(path, 0x80)
except Exception:
pass
def save_template_xlsx(self):
"""弹窗选择保存位置,将品牌文档格式模板 xlsx 保存到用户选择的位置。"""
template_name = '品牌文档格式_模板.xlsx'
@@ -440,7 +538,7 @@ def main():
api = WindowAPI(window)
window.expose(api.close, api.minimize, api.maximize, api.toggle_maximize, generate_images, api.save_image, api.save_image_to_folder, api.select_folder, api.select_brand_xlsx_files, api.select_brand_folder,
api.save_file_from_url, api.save_template_xlsx,api.save_template_zip,api.upload_file_to_java,api.open_external_url,api.enqueue_json,api.get_detail_del,api.save_file_from_url_new,api.get_device_id)
api.save_file_from_url, api.save_template_xlsx,api.save_template_zip,api.upload_file_to_java,api.open_external_url,api.enqueue_json,api.get_detail_del,api.save_file_from_url_new,api.save_file_from_url_with_progress,api.get_device_id)
webview.start(
debug=True,
storage_path=cache_path,