Commit b9307f2f authored by mayinghao's avatar mayinghao

产品管理页码

parent 695b7f6e
......@@ -4,7 +4,7 @@ import base64
from login import *
import uuid
import re
from PyQt5.QtWidgets import QMessageBox, QProgressBar, QTableWidget, QTableWidgetItem
from PyQt5.QtWidgets import QMessageBox, QProgressBar, QTableWidget, QTableWidgetItem, QDesktopWidget
import requests
import json
import datetime
......@@ -19,7 +19,7 @@ import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableView, QVBoxLayout,
QWidget, QPushButton, QHeaderView, QHBoxLayout,
QLabel, QFileDialog)
from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QThread
from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QThread, pyqtSignal
from PyQt5.QtGui import QColor
from cryptography.fernet import Fernet
from multipleThread.thread_upload import Upload_Thread
......@@ -40,10 +40,8 @@ login_url = 'https://uat.emku.laidecloud.com/console/pc/userLoginByToken.ajax'
order_info_url = "https://uat.emku.laidecloud.com/console/productOrder/experimentOrderList.ajax"
# order detail
order_detail_url = "https://uat.emku.laidecloud.com/console/productOrder/uploadorderdetail.ajax"
product_manager_url = "https://uat.emku.laidecloud.com/console/goods/goods_list.ajax"
product_callback_url = "https://uat.emku.laidecloud.com/console/seller/getFiles.ajax"
#获取上传文件列表
fileupload_url = "https://uat.emku.laidecloud.com/console/productOrder/onupload.ajax"
......@@ -67,6 +65,18 @@ def nanoseconds_to_date(nano_seconds):
return str_date
def process_data(data):
result = []
for j in data["obj"]["files"]:
result.append([j["info"], "生产资料", j['addTime']])
for j in data["obj"]["files1"]:
result.append([j["info"], "设计资料", j['addTime']])
for j in data["obj"]["files2"]:
result.append([j["info"], "Bom资料", j['addTime']])
return result
# 密码加密存储类
class PasswordManager:
def __init__(self, storage_file='data.json', key_file='secret.key'):
......@@ -276,7 +286,11 @@ class OrderDetail(QMainWindow):
self.table_filelist.setRowCount(0)
self.table_filelist.setRowCount(len(fileupload_list))
print(fileupload_list)
for row, file_info in enumerate(fileupload_list):
row_position = self.table_filelist.rowCount()+1
self.table_filelist.insertRow(row_position)
station_name = QTableWidgetItem(file_info[0])
file_item = QTableWidgetItem(file_info[1])
file_type =QTableWidgetItem(file_info[3])
......@@ -668,10 +682,10 @@ class DeviceTableModel_product(QAbstractTableModel):
"""根据厂商过滤数据"""
self.beginResetModel()
print(manufacturer)
if manufacturer == "所有客户企业":
if manufacturer == "所有品牌":
self._filtered_data = self._data.copy()
else:
self._filtered_data = [device for device in self._data if device[2] == manufacturer]
self._filtered_data = [device for device in self._data if device[3] == manufacturer]
print(self._filtered_data)
self.endResetModel()
......@@ -681,11 +695,28 @@ class DeviceTableModel_product(QAbstractTableModel):
# 导航页
class NavigatorPage(QWidget):
closeSignal = pyqtSignal()
def center(self):
# 获取屏幕尺寸和窗口尺寸
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
# 计算居中位置
x = (screen.width() - size.width()) // 2
y = (screen.height() - size.height()) // 2
# 移动窗口到居中位置
self.move(x, y)
def __init__(self):
super().__init__()
self.setWindowTitle("导航页")
self.setGeometry(600, 700, 300, 400)
#self.setGeometry(600, 700, 300, 400)
self.setFixedSize(300, 400) # 固定大小
self.equ = None
self.product = None
# 创建垂直布局
layout = QVBoxLayout()
self.setLayout(layout)
......@@ -711,13 +742,46 @@ class NavigatorPage(QWidget):
# 添加弹性空间使按钮靠上
layout.addStretch()
self.center()
def center(self):
# 获取屏幕尺寸和窗口尺寸
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
# 计算居中位置
x = (screen.width() - size.width()) // 2
y = (screen.height() - size.height()) // 2
# 移动窗口到居中位置
self.move(x, y)
def handle_close(self):
self.equ = None
print("close equ")
def handle_close2(self):
print("close product")
self.product = None
def button_clicked(self, button_num):
global token
if button_num == 0:
self.equ = EqipInfoWindow()
if self.equ is None:
self.equ = EqipInfoWindow()
self.equ.destroyed.connect(self.handle_close)
else:
self.equ.raise_()
self.equ.activateWindow()
elif button_num == 1:
self.equ = productInfoWindow()
if self.product is None:
self.product = productInfoWindow()
self.product.destroyed.connect(self.handle_close2)
else:
self.product.raise_()
self.product.activateWindow()
# headers = {'token': token,
# 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}
......@@ -751,10 +815,26 @@ class productInfoWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("订单信息管理")
self.setGeometry(100, 100, 1500, 655)
self.setGeometry(100, 100, 1500, 755)
# 每页订单数量
self.per_page_size = 10
self.progress_widgets = []
self.status_info = ""
# 为每个进程创建进度条
self.progress_bars = []
self.counter = 0
# 暂停按钮
self.buttons = []
# 线程数组
self.threads = []
self.uploads = []
self.send_data = 0
self.uuid_str = ''
self.oss_prefix = "upload/order/"
# 必须文件夹
if not os.path.exists("./upload_tag"):
os.mkdir("./upload_tag")
......@@ -771,7 +851,7 @@ class productInfoWindow(QMainWindow):
data1 = response.json()
product_info = data1["obj"]["pList"]["result"]
# 总订单数量
list_num = 200
pages = data1["obj"]["pList"]["pages"]
order_property = ["id", "goods_name", "en_name", "goods_brand", "gc"]
# 处理数据
......@@ -790,7 +870,7 @@ class productInfoWindow(QMainWindow):
self.devices = result
central_widget = QWidget()
main_layout = QVBoxLayout(central_widget)
self.main_layout = QVBoxLayout(central_widget)
self.filter_layout = QHBoxLayout()
self.filter_label = QLabel("筛选客户企业:")
......@@ -809,13 +889,13 @@ class productInfoWindow(QMainWindow):
self.refresh_button.setContentsMargins(0, 0, 60, 0)
self.filter_layout.addWidget(self.refresh_button)
self.refresh_button.clicked.connect(lambda: (self.update_page_info(1), self.page_list_combo.setCurrentIndex(0)))
main_layout.addLayout(self.filter_layout)
self.main_layout.addLayout(self.filter_layout)
# 获取所有品牌并去重,添加"所有品牌"选项
brands = list(set(device[2] for device in self.devices))
brands.insert(0, "所有客户企业")
brands = list(set(device[3] for device in self.devices))
brands.insert(0, "所有品牌")
self.brand_combo.addItems(brands)
self.brand_combo.currentTextChanged.connect(self.filter_devices)
page_list = [str(x) for x in range(1, self.get_total_page(list_num)+1)]
page_list = [str(x) for x in range(1, pages+1)]
self.page_list_combo.addItems(page_list)
self.page_list_combo.currentTextChanged.connect(self.update_page_info)
self.headers = ["id", "商品名称", "英文名称", "品牌", "分类名", "上传", "上传"]
......@@ -839,9 +919,27 @@ class productInfoWindow(QMainWindow):
# 布局
main_layout.addWidget(self.table_view)
self.main_layout.addWidget(self.table_view)
self.status_label = QLabel()
main_layout.addWidget(self.status_label)
self.table_filelist = QTableWidget()
self.table_filelist.setColumnCount(4)
self.table_filelist.setHorizontalHeaderLabels(["商品名称", "文件名", "类型", "上传日期"])
self.table_filelist.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.table_filelist.setSortingEnabled(True)
# 设置所有单元格默认居中对齐
header = self.table_filelist.horizontalHeader()
header.setDefaultSectionSize(290)
header.setSectionResizeMode(QHeaderView.Interactive) # 允许调整列宽
# header.setSectionResizeMode(QHeaderView.Stretch) # 所有列
header.setDefaultAlignment(Qt.AlignCenter)
# header.setSectionsMovable(True) # 允许拖动列顺序
self.main_layout.addWidget(self.table_filelist)
self.main_layout.addWidget(self.status_label)
time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
info_append = f"{time_str} 第1页\n"
self.status_label.setText(info_append)
......@@ -849,11 +947,183 @@ class productInfoWindow(QMainWindow):
self.show()
def closeEvent(self, event):
self.destroyed.emit()
event.accept()
def changeProcessbar(self, value):
if value[1] == 100:
data = self.progress_widgets[value[0]]
data["widget"].deleteLater()
time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
info_append = f"{time_str} {value[2]}上传成功\n"
self.status_info += info_append
#self.file_label.setText(self.status_info)
#self.update_table_filelist()
else:
self.progress_bars[value[0]].setValue(value[1])
def add_progress_bar_and_button(self, file_path, order_id, type_info):
# 创建水平布局
widget = QWidget()
h_layout = QVBoxLayout(widget)
# 创建进度条
progress_bar = QProgressBar()
progress_bar.setRange(0, 100)
progress_bar.setValue(0)
# 创建按钮
#button = QPushButton(f"上传")
status_label = QLabel(f"正在上传{file_path}")
# 将部件添加到水平布局
h_layout.addWidget(progress_bar)
#h_layout.addWidget(button)
h_layout.addWidget(status_label)
# 将水平布局添加到主布局
self.main_layout.insertWidget(self.main_layout.count()-1, widget)
# 存储部件引用
self.progress_bars.append(progress_bar)
current_index = len(self.progress_widgets)
self.progress_widgets.append({"widget": widget, "progess_bar": progress_bar, "label": status_label, "index": current_index})
#self.buttons.append(button)
thread = QThread()
upload = Upload_Thread(self.counter, order_id, type_info, token)
upload.filename = file_path
upload.moveToThread(thread)
upload.updateSignal.connect(self.changeProcessbar)
upload.finishSignal.connect(self.update_table_filelist)
self.uploads.append(upload)
self.threads.append(thread)
thread.started.connect(self.uploads[-1].run)
thread.start()
#button.clicked.connect(lambda checked, idx=self.counter: upload.resume_thread())
print(self.counter)
# 增加计数器
self.counter += 1
def update_table_filelist(self, fileupload_list, _id):
file_list = [x for x in self.devices if x[0] == _id]
key = file_list[0][1]
fileupload_list = sorted(fileupload_list, key=lambda x: x[2], reverse=True)
for row, file_info in enumerate(fileupload_list):
row_position = self.table_filelist.rowCount()
self.table_filelist.insertRow(row_position)
good_name = QTableWidgetItem(key)
file_item = QTableWidgetItem(file_info[0])
file_type = QTableWidgetItem(file_info[1])
create_time = QTableWidgetItem(nanoseconds_to_date(file_info[2]))
good_name.setTextAlignment(Qt.AlignCenter)
file_item.setTextAlignment(Qt.AlignCenter)
create_time.setTextAlignment(Qt.AlignCenter)
file_type.setTextAlignment(Qt.AlignCenter)
self.table_filelist.setItem(row_position, 0, good_name)
self.table_filelist.setItem(row_position, 1, file_item)
self.table_filelist.setItem(row_position, 2, file_type)
self.table_filelist.setItem(row_position, 3, create_time)
print("finished")
def upload_file(self, filename, order_id, type_info):
# 显示上传进度条
self.send_data = 0
key = filename.split('/')[-1]
self.uuid_str = str(uuid.uuid4())
extension = key.split(".")[-1]
oss_key = self.oss_prefix + self.uuid_str+"."+extension
print(oss_key)
parts = []
upload_id = bucket.init_multipart_upload(oss_key).upload_id
if os.path.exists(filename):
total_size = os.path.getsize(filename)
self.total_size = total_size
self.leftBytes = total_size % part_size
print(total_size)
# 小于5M直接上传
if total_size <= part_size:
with open(filename, "rb") as fileobj:
data = fileobj.read()
bucket.put_object(oss_key, data)
else:
circle = total_size // part_size
# 最后一包数据
left_bytes = total_size % part_size
if left_bytes != 0:
circle += 1
# 逐个上传分片。
with open(filename, 'rb') as fileobj:
part_number = 1
offset = 0
while offset < total_size:
num_to_upload = min(part_size, total_size - offset)
# 全局part_number冲突导致 setText不能正常显示,去掉恢复正常
print(f'正在上传第{part_number}/{circle}个分片包')
self.file_label.setText(f'正在上传第{part_number}/{circle}个分片包')
self.file_label.repaint()
# 调用SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。
result = bucket.upload_part(oss_key, upload_id, part_number,
SizedFileAdapter(fileobj, num_to_upload),progress_callback=self.upload_callback
)
parts.append(PartInfo(part_number, result.etag))
offset += num_to_upload
part_number += 1
# 完成分片上传。
# 如需在完成分片上传时设置相关Headers,请参考如下示例代码。
headers = dict()
# 设置文件访问权限ACL。此处设置为OBJECT_ACL_PRIVATE,表示私有权限。
# headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE
bucket.complete_multipart_upload(oss_key, upload_id, parts, headers=headers)
#self.file_label.setText(f"{filename}上传完成")
datas = {"id": str(order_id), "name": self.uuid_str+"."+extension, "path": name_prefix, "info": key, "type": type_info}
headers = {'token': token,
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}
if type_info >= 12:
callback_url = goods_callback_url
# try:
print(datas)
print(callback_url)
response = requests.post(callback_url, data=datas, headers=headers)
res = response.json()
if res["obj"] == "保存成功":
response = requests.post(product_callback_url, data={"id": order_id}, headers=headers)
data = response.json()
time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
info_append = f"{time_str} {filename}上传成功\n"
self.status_info += info_append
res=process_data(data)
self.update_table_filelist(res, order_id)
def handle_bom(self, row, type_info):
# 上传文件逻辑
files, _ = QFileDialog.getOpenFileNames(
self,
"添加文件",
"", # 默认目录
"All Files (*);;Text Files (*.txt);;Python Files (*.py)"
)
if files:
for file_path in files:
# 如果小于5M直接上传,大于5M开启线程上传
if os.path.getsize(file_path) < part_size:
self.upload_file(file_path,self.devices[row][0], type_info)
else:
self.add_progress_bar_and_button(file_path, self.devices[row][0], type_info)
# 更新列表信息
def update_page_info(self, page_num):
page_select_num = int(page_num)
start = (page_select_num-1)*self.per_page_size
datas = {"start": str(start), "draw": str(page_select_num), "length": str(self.per_page_size)}
datas = {"currentPage": str(page_select_num)}
headers = {'token': token,
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}
......@@ -886,8 +1156,8 @@ class productInfoWindow(QMainWindow):
self.status_label.setText(info_append)
# 更新品牌列表
brands = list(set(device[2] for device in self.devices))
brands.insert(0, "所有客户企业")
brands = list(set(device[3] for device in self.devices))
brands.insert(0, "所有品牌")
self.brand_combo.clear()
self.brand_combo.addItems(brands)
self.brand_combo.currentTextChanged.connect(self.filter_devices)
......@@ -914,9 +1184,11 @@ class productInfoWindow(QMainWindow):
for row in range(self.model.rowCount()):
self.add_operation_buttons(row)
def add_operation_buttons(self, row):
# 创建操作按钮
btn_edit = QPushButton("生产资料")
btn_edit.clicked.connect(lambda _, r=row: self.handle_bom(r, 12))
# 设置按钮样式
btn_edit.setStyleSheet("background-color: #4CAF50; color: white;")
......@@ -938,7 +1210,7 @@ class productInfoWindow(QMainWindow):
)
btn_edit2 = QPushButton("设计资料")
btn_edit2.clicked.connect(lambda _, r=row: self.handle_bom(r, 13))
# 设置按钮样式
btn_edit2.setStyleSheet("background-color: #4CAF50; color: white;")
......@@ -956,8 +1228,6 @@ class productInfoWindow(QMainWindow):
)
# 连接信号
btn_edit.clicked.connect(lambda _, r=row: self.edit_device(r))
def nanoseconds_to_date(self, nano_seconds):
timestamp = nano_seconds / 1000
str_date = datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d %H-%M-%S")
......@@ -1027,7 +1297,15 @@ class productInfoWindow(QMainWindow):
class EqipInfoWindow(QMainWindow):
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
super().__init__()
self.setWindowTitle("订单信息管理")
self.setGeometry(100, 100, 1500, 655)
......@@ -1136,6 +1414,10 @@ class EqipInfoWindow(QMainWindow):
self.show()
def closeEvent(self, event):
self.destroyed.emit()
event.accept()
# 更新列表信息
def update_page_info(self, page_num):
page_select_num = int(page_num)
......
# -*- coding: utf-8 -*-
import datetime
import time
import requests
from PyQt5.QtCore import QThread, pyqtSignal, QWaitCondition, QMutex, QObject, pyqtSlot
import os.path
......@@ -8,6 +11,27 @@ from oss2 import SizedFileAdapter
import uuid
from oss2.models import PartInfo
from .config import *
product_callback_url = "https://uat.emku.laidecloud.com/console/seller/getFiles.ajax"
def nanoseconds_to_date(nano_seconds):
timestamp = nano_seconds/ 1000
utc_time = datetime.datetime.utcfromtimestamp(timestamp)
beijing_time = utc_time + datetime.timedelta(hours=8)
str_date=beijing_time.strftime("%Y-%m-%d %H:%M:%S")
return str_date
def process_data(data):
result = []
for j in data["obj"]["files"]:
result.append([j["info"], "生产资料", j['addTime']])
for j in data["obj"]["files1"]:
result.append([j["info"], "设计资料", j['addTime']])
for j in data["obj"]["files2"]:
result.append([j["info"], "Bom资料", j['addTime']])
print(result)
return result
# 定义一个线程类
......@@ -15,7 +39,7 @@ class Upload_Thread(QObject):
#自定义信号声明
# 使用自定义信号和UI主线程通讯,参数是发送信号时附带参数的数据类型,可以是str、int、list等
finishSignal = pyqtSignal()
finishSignal = pyqtSignal(list, int)
updateSignal = pyqtSignal(tuple)
def __init__(self, thread_num=0, order_id=None, type_info=None, token=""):
......@@ -153,13 +177,16 @@ class Upload_Thread(QObject):
datas = {"id": str(self.order_id), "name": self.uuid_str + "." + extension, "path": name_prefix, "info": key,
"type": self.type_info}
print(f"datas {datas}")
headers = {'token': self.token,
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}
try:
response = requests.post(callback_url, data=datas,headers=headers)
res = response.json()
print(res["obj"])
self.finishSignal.emit()
except Exception as e:
print("wrong")
if self.type_info >= 12:
callback_url = goods_callback_url
response = requests.post(callback_url, data=datas,headers=headers)
res = response.json()
print(res["obj"])
response = requests.post(product_callback_url, data={"id": self.order_id}, headers=headers)
data = response.json()
res = process_data(data)
self.finishSignal.emit(res, self.order_id)
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