Commit 9bc77bb3 authored by mayinghao's avatar mayinghao

添加下载

parent 75dbfedd
...@@ -4,7 +4,8 @@ import base64 ...@@ -4,7 +4,8 @@ import base64
from login import * from login import *
import uuid import uuid
import re import re
from PyQt5.QtWidgets import QMessageBox, QProgressBar, QTableWidget, QTableWidgetItem, QDesktopWidget from PyQt5.QtWidgets import QMessageBox, QProgressBar, QTableWidget, QTableWidgetItem, QDesktopWidget, QDialog, \
QCheckBox
import requests import requests
import json import json
import datetime import datetime
...@@ -27,7 +28,7 @@ from multipleThread.thread_resume import Resume_Thread ...@@ -27,7 +28,7 @@ from multipleThread.thread_resume import Resume_Thread
from multipleThread.config import version from multipleThread.config import version
from multipleThread.config import * from multipleThread.config import *
from multipleThread.config import login_url, order_detail_url, order_info_url, product_manager_url, \ from multipleThread.config import login_url, order_detail_url, order_info_url, product_manager_url, \
product_callback_url, fileupload_url product_callback_url, fileupload_url, download_url
# 命令行查看文件md5 # 命令行查看文件md5
# certutil -hashfile music.mp4 MD5 # certutil -hashfile music.mp4 MD5
...@@ -37,7 +38,6 @@ from multipleThread.config import login_url, order_detail_url, order_info_url, p ...@@ -37,7 +38,6 @@ from multipleThread.config import login_url, order_detail_url, order_info_url, p
user_now = '' user_now = ''
token = '' token = ''
print(f"{fileupload_url} {login_url} {order_detail_url} {order_info_url} {product_manager_url}")
# 未完成任务列表 # 未完成任务列表
job_list = {} job_list = {}
...@@ -57,7 +57,6 @@ def nanoseconds_to_date(nano_seconds): ...@@ -57,7 +57,6 @@ def nanoseconds_to_date(nano_seconds):
return str_date return str_date
def process_data(data): def process_data(data):
result = [] result = []
for j in data["obj"]["files"]: for j in data["obj"]["files"]:
...@@ -68,6 +67,73 @@ def process_data(data): ...@@ -68,6 +67,73 @@ def process_data(data):
result.append([j["info"], "Bom资料", j['addTime']]) result.append([j["info"], "Bom资料", j['addTime']])
return result return result
def process_data2(data):
result = []
for j in data["obj"]["files"]:
result.append([j["info"], j['addTime'], j["name"]])
for j in data["obj"]["files1"]:
result.append([j["info"], j['addTime'], j["name"]])
for j in data["obj"]["files2"]:
result.append([j["info"], j['addTime'], j["name"]])
return result
class DownloadThread(QThread):
"""
下载线程:执行实际的 OSS 下载操作
"""
# 定义信号:用于传递进度值 (0-100) 和完成状态
progress_updated = pyqtSignal(int)
download_finished = pyqtSignal(bool, str) # 成功标志, 消息
def __init__(self, bucket_name, object_key, local_path, endpoint, region):
super().__init__()
self.bucket_name = bucket_name
self.object_key = object_key
print(f"--------------->{self.object_key}")
self.local_path = local_path
self.endpoint = endpoint
self.region = region
def run(self):
"""
线程运行函数
"""
try:
# 1. 初始化 OSS 客户端
auth = oss2.Auth(aliyun_key, aliyun_secret)
bucket = oss2.Bucket(auth, endpoint, "qgongye", region=region)
# 2. 定义进度回调函数
# 注意:progress_callback 会在 OSS SDK 内部被调用
# 它运行在子线程中,所以需要用信号来更新 UI
def progress_callback(consumed_bytes, total_bytes):
if total_bytes:
rate = int(100 * (consumed_bytes / total_bytes))
# 发出信号,主线程会更新进度条
self.progress_updated.emit(rate)
# 3. 执行下载
# bucket.get_object_to_file(
# self.object_key,
# self.local_path,
# progress_callback=progress_callback
# )
oss2.resumable_download(
bucket,
self.object_key,
self.local_path,
progress_callback=progress_callback
)
# 4. 下载完成
self.download_finished.emit(True, f"下载成功!文件保存至:{self.local_path}")
except Exception as e:
self.download_finished.emit(False, f"下载失败:{str(e)}")
# 密码加密存储类 # 密码加密存储类
class PasswordManager: class PasswordManager:
...@@ -792,6 +858,264 @@ class NavigatorPage(QWidget): ...@@ -792,6 +858,264 @@ class NavigatorPage(QWidget):
#self.hide() #self.hide()
class TableDialog(QDialog):
"""弹出窗口,包含一个带有操作按钮的表格"""
def __init__(self, parent=None, data=[]):
super().__init__(parent)
self.setWindowTitle("数据表格")
self.resize(600, 400)
# 创建布局
layout = QVBoxLayout(self)
# 创建表格部件
self.table = QTableWidget()
layout.addWidget(self.table)
self.checkboxes = []
btn_multi = QPushButton("多选下载")
btn_multi.clicked.connect(self.show_selected_items)
btn_multi.setStyleSheet("background-color: #4CAF50; color: white;")
# 设置按钮大小
self.select_rows = []
btn_multi.setFixedSize(60, 25)
layout.addWidget(btn_multi)
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(0)
# 设置进度条样式(可选)
self.progress_bar.setStyleSheet("""
QProgressBar {
border: 1px solid grey;
border-radius: 3px;
text-align: center;
font-size: 12px;
}
QProgressBar::chunk {
background-color: #4CAF50;
width: 10px;
}
""")
self.progress_bar.setVisible(True)
layout.addWidget(self.progress_bar)
self.single = True
self.data = data
# 设置表格属性
self.setup_table()
# 填充示例数据
self.populate_data()
def setup_table(self):
"""设置表格的列数、标题等"""
# 设置列数:4列数据 + 1列操作按钮
self.table.setColumnCount(4)
# 设置列标题
headers = ["选择", "文件名称", "上传时间", "操作"]
self.table.setHorizontalHeaderLabels(headers)
# 设置表格选择行为:选中整行
self.table.setSelectionBehavior(QTableWidget.SelectRows)
# 禁止编辑表格内容(可选)
self.table.setEditTriggers(QTableWidget.NoEditTriggers)
# 让操作列的宽度适应内容,其他列自适应拉伸
header = self.table.horizontalHeader()
header.setSectionResizeMode(0, QHeaderView.Stretch) # ID列
header.setSectionResizeMode(1, QHeaderView.Stretch) # 姓名列拉伸
header.setSectionResizeMode(2, QHeaderView.Stretch) # 年龄列
header.setSectionResizeMode(3, QHeaderView.Stretch) # 年龄列
def on_checkbox_changed(self, row, state):
"""复选框状态改变时的处理"""
pass
def populate_data(self):
"""填充示例数据,并在最后一列添加按钮"""
# 设置行数
self.table.setRowCount(len(self.data))
if len(self.data) >= 1:
# 填充数据并添加按钮
for row, [name, age, _] in enumerate(self.data):
checkbox_widget = QWidget()
checkbox_layout = QHBoxLayout(checkbox_widget)
checkbox_layout.setAlignment(Qt.AlignCenter)
checkbox_layout.setContentsMargins(0, 0, 0, 0)
checkbox = QCheckBox()
checkbox.stateChanged.connect(lambda state, r=row: self.on_checkbox_changed(r, state))
checkbox_layout.addWidget(checkbox)
self.table.setCellWidget(row, 0, checkbox_widget)
self.checkboxes.append(checkbox)
# 填充ID列
# 填充姓名列
name_item = QTableWidgetItem(name)
name_item.setTextAlignment(Qt.AlignCenter)
self.table.setItem(row, 1, name_item)
# 填充年龄列
age_item = QTableWidgetItem(nanoseconds_to_date(age))
age_item.setTextAlignment(Qt.AlignCenter)
self.table.setItem(row, 2, age_item)
# 为操作列创建按钮控件
btn = QPushButton("下载")
btn.setStyleSheet("background-color: #4CAF50; color: white;")
# 设置按钮大小
btn.setFixedSize(60, 25)
btn.clicked.connect(lambda checked, r=row: self.on_action_button_clicked(r))
btn_widget = QWidget()
btn_layout = QHBoxLayout(btn_widget)
btn_layout.addWidget(btn)
btn_layout.setContentsMargins(5, 2, 5, 2)
btn_layout.setSpacing(5)
# 将按钮放入单元格
self.table.setCellWidget(row, 3, btn_widget)
def update_progress(self, value):
"""更新进度条"""
self.progress_bar.setValue(value)
# 在进度条上显示百分比(可选,默认已显示)
self.progress_bar.setFormat(f"{value}%")
def show_selected_items(self):
"""显示选中的项目"""
self.selected_rows = self.get_selected_rows()
# 获取该行的数据
if user_now == "admin":
# id_val = self.table.item(row, 0).text()
#
# response = requests.post(download_url, data={"id": self.data[row][-1], "name": self.data[row][0]}, stream=True)
#
# with open(id_val, 'wb') as f:
# for chunk in response.iter_content(chunk_size=8192):
# if chunk:
# f.write(chunk)
# 禁用按钮,防止重复点击
# 创建并启动下载线程
if not os.path.exists("./Download"):
os.mkdir("./Download")
if self.single:
self.progress_bar.setValue(0)
self.single = False
self.download_thread = DownloadThread(
bucket_name=bucket,
object_key="upload/order/" + self.data[self.selected_rows[0]][2],
local_path="./Download/" + self.data[self.selected_rows[0]][0],
endpoint=endpoint,
region=region
)
# 连接信号
self.download_thread.progress_updated.connect(self.update_progress)
self.download_thread.download_finished.connect(self.on_download_finished2)
self.download_thread.start()
def get_selected_rows(self):
"""获取所有选中行的数据"""
selected_rows = []
for row, checkbox in enumerate(self.checkboxes):
if checkbox.isChecked():
selected_rows.append(row)
return selected_rows
def on_download_finished2(self, success, message):
"""下载完成处理"""
if success:
self.progress_bar.setValue(0)
# 在进度条上显示百分比(可选,默认已显示)
self.progress_bar.setFormat(f"{0}%")
else:
self.progress_bar.setValue(0)
self.selected_rows.remove(self.selected_rows[0])
if len(self.selected_rows) > 0:
self.single = False
self.download_thread = DownloadThread(
bucket_name=bucket,
object_key="upload/order/" + self.data[self.selected_rows[0]][2],
local_path="./Download/" + self.data[self.selected_rows[0]][0],
endpoint=endpoint,
region=region
)
# 连接信号
self.download_thread.progress_updated.connect(self.update_progress)
self.download_thread.download_finished.connect(self.on_download_finished2)
self.download_thread.start()
else:
QMessageBox.information(
self,
"详情",
f"下载完成"
)
def on_download_finished(self, success, message):
"""下载完成处理"""
if success:
self.progress_bar.setValue(0)
# 在进度条上显示百分比(可选,默认已显示)
self.progress_bar.setFormat(f"{0}%")
QMessageBox.information(self, "下载完成", message)
else:
self.progress_bar.setValue(0)
QMessageBox.critical(self, "下载失败", message)
self.single = True
# 清理线程(防止内存泄漏)
self.download_thread.deleteLater()
self.download_thread = None
def on_action_button_clicked(self, row):
"""操作按钮的点击事件"""
# 获取该行的数据
if user_now == "admin":
# id_val = self.table.item(row, 0).text()
#
# response = requests.post(download_url, data={"id": self.data[row][-1], "name": self.data[row][0]}, stream=True)
#
# with open(id_val, 'wb') as f:
# for chunk in response.iter_content(chunk_size=8192):
# if chunk:
# f.write(chunk)
# 禁用按钮,防止重复点击
# 创建并启动下载线程
print("start thread")
if not os.path.exists("./Download"):
os.mkdir("./Download")
if self.single:
self.progress_bar.setValue(0)
self.single = False
self.download_thread = DownloadThread(
bucket_name=bucket,
object_key="upload/order/"+self.data[row][2],
local_path="./Download/"+self.data[row][0],
endpoint=endpoint,
region=region
)
# 连接信号
self.download_thread.progress_updated.connect(self.update_progress)
self.download_thread.download_finished.connect(self.on_download_finished)
self.download_thread.start()
else:
QMessageBox.information(
self,
"详情",
f"无下载权限"
)
class productInfoWindow(QMainWindow): class productInfoWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
...@@ -889,7 +1213,7 @@ class productInfoWindow(QMainWindow): ...@@ -889,7 +1213,7 @@ class productInfoWindow(QMainWindow):
page_list = [str(x) for x in range(1, pages+1)] page_list = [str(x) for x in range(1, pages+1)]
self.page_list_combo.addItems(page_list) self.page_list_combo.addItems(page_list)
self.page_list_combo.currentTextChanged.connect(self.update_page_info) self.page_list_combo.currentTextChanged.connect(self.update_page_info)
self.headers = ["id", "商品名称", "英文名称", "品牌", "分类名", "版本", "上传", "上传"] self.headers = ["id", "商品名称", "英文名称", "品牌", "分类名", "版本", "上传", "上传", "查看"]
self.station_code = {1: "设计", 2: "生产", 3: "售后", 4: "采购", 5: "品保"} self.station_code = {1: "设计", 2: "生产", 3: "售后", 4: "采购", 5: "品保"}
self.order_status_code = {1: "进行中", 2: "已完成", 0: "未开始"} self.order_status_code = {1: "进行中", 2: "已完成", 0: "未开始"}
# 创建模型和视图 # 创建模型和视图
...@@ -1109,7 +1433,7 @@ class productInfoWindow(QMainWindow): ...@@ -1109,7 +1433,7 @@ class productInfoWindow(QMainWindow):
for file_path in files: for file_path in files:
# 如果小于5M直接上传,大于5M开启线程上传 # 如果小于5M直接上传,大于5M开启线程上传
if os.path.getsize(file_path) < part_size: if os.path.getsize(file_path) < part_size:
self.upload_file(file_path,self.model.filtered_data[row][0], type_info, version_id) self.upload_file(file_path, self.model.filtered_data[row][0], type_info, version_id)
else: else:
self.add_progress_bar_and_button(file_path, self.model.filtered_data[row][0], type_info, version_id) self.add_progress_bar_and_button(file_path, self.model.filtered_data[row][0], type_info, version_id)
...@@ -1190,6 +1514,19 @@ class productInfoWindow(QMainWindow): ...@@ -1190,6 +1514,19 @@ class productInfoWindow(QMainWindow):
def on_value_changed(self, row, value): def on_value_changed(self, row, value):
print(self.model.filtered_data[row][-1][value]) print(self.model.filtered_data[row][-1][value])
def handle_download(self, row):
combo = self.combos[row]
version_id = -1
if combo:
value = combo.currentText()
version_id = self.model.filtered_data[row][-1][value]
response = requests.post(product_callback_url, data={"id": self.model.filtered_data[row][0], "product_version_id": version_id})
data = response.json()
res = process_data2(data)
dialog = TableDialog(self, res)
dialog.exec_() # 模态对话框
def add_operation_buttons(self, row): def add_operation_buttons(self, row):
version_list = self.model._filtered_data[row][-1] version_list = self.model._filtered_data[row][-1]
version_keys = list(version_list.keys()) version_keys = list(version_list.keys())
...@@ -1255,6 +1592,24 @@ class productInfoWindow(QMainWindow): ...@@ -1255,6 +1592,24 @@ class productInfoWindow(QMainWindow):
btn_widget2 btn_widget2
) )
btn_edit3 = QPushButton("查看")
btn_edit3.clicked.connect(lambda _, r=row: self.handle_download(r))
# 设置按钮样式
btn_edit3.setStyleSheet("background-color: #4CAF50; color: white;")
# 设置按钮大小
btn_edit3.setFixedSize(60, 25)
btn_widget3 = QWidget()
btn_layout3 = QHBoxLayout(btn_widget3)
btn_layout3.addWidget(btn_edit3)
btn_layout3.setContentsMargins(5, 2, 5, 2)
btn_layout3.setSpacing(5)
self.table_view.setIndexWidget(
self.model.index(row, 8),
btn_widget3
)
# 连接信号 # 连接信号
def nanoseconds_to_date(self, nano_seconds): def nanoseconds_to_date(self, nano_seconds):
timestamp = nano_seconds / 1000 timestamp = nano_seconds / 1000
......
...@@ -23,6 +23,7 @@ if version == "test": ...@@ -23,6 +23,7 @@ if version == "test":
product_callback_url = "http://uat.vue.emku.laidecloud.com/console/seller/getFiles.ajax" product_callback_url = "http://uat.vue.emku.laidecloud.com/console/seller/getFiles.ajax"
#获取上传文件列表 #获取上传文件列表
fileupload_url = "http://uat.vue.emku.laidecloud.com/console/productOrder/onupload.ajax" fileupload_url = "http://uat.vue.emku.laidecloud.com/console/productOrder/onupload.ajax"
download_url = "http://uat.vue.emku.laidecloud.com/console/productOrder/downloadFile.ajax"
else: else:
callback_url = "https://emku.laidecloud.com/console/productOrder/filePthSave.ajax" callback_url = "https://emku.laidecloud.com/console/productOrder/filePthSave.ajax"
...@@ -37,3 +38,5 @@ else: ...@@ -37,3 +38,5 @@ else:
# 获取上传文件列表 # 获取上传文件列表
fileupload_url = "https://emku.laidecloud.com/console/productOrder/onupload.ajax" fileupload_url = "https://emku.laidecloud.com/console/productOrder/onupload.ajax"
goods_callback_url = "https://emku.laidecloud.com/console/productOrder/goodsFilePthSave.ajax" goods_callback_url = "https://emku.laidecloud.com/console/productOrder/goodsFilePthSave.ajax"
download_url = "https://emku.laidecloud.com/console/productOrder/downloadFile.ajax"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment