Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
EMUAFactory
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mayinghao
EMUAFactory
Commits
9bc77bb3
Commit
9bc77bb3
authored
Apr 01, 2026
by
mayinghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加下载
parent
75dbfedd
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
364 additions
and
6 deletions
+364
-6
main.py
main.py
+361
-6
config.py
multipleThread/config.py
+3
-0
No files found.
main.py
View file @
9bc77bb3
...
@@ -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
...
...
multipleThread/config.py
View file @
9bc77bb3
...
@@ -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"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment