上传文件至 /
This commit is contained in:
parent
609a2d8254
commit
f60bd9f0da
|
@ -0,0 +1,258 @@
|
|||
import sys
|
||||
import requests
|
||||
import json
|
||||
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||
QLabel, QLineEdit, QPushButton, QTextEdit, QMessageBox,
|
||||
QComboBox, QDateEdit, QFileDialog, QGroupBox)
|
||||
from PyQt5.QtCore import Qt, QDate
|
||||
from PyQt5.QtGui import QIntValidator
|
||||
|
||||
|
||||
class ProjectAddWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setWindowTitle("新增项目")
|
||||
self.setGeometry(100, 100, 650, 900)
|
||||
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
# 主窗口部件
|
||||
central_widget = QWidget()
|
||||
self.setCentralWidget(central_widget)
|
||||
layout = QVBoxLayout()
|
||||
|
||||
# 1. 基本信息分组
|
||||
basic_info_group = QGroupBox("基本信息")
|
||||
basic_layout = QVBoxLayout()
|
||||
|
||||
# 项目名称
|
||||
self.project_name_input = self.create_label_input(basic_layout, "项目名称*:", QLineEdit())
|
||||
|
||||
# 项目经理ID
|
||||
self.manager_id_input = self.create_label_input(basic_layout, "项目经理ID*:", QLineEdit())
|
||||
|
||||
# 项目状态
|
||||
status_layout = QHBoxLayout()
|
||||
status_layout.addWidget(QLabel("项目状态:"))
|
||||
self.status_combo = QComboBox()
|
||||
self.status_combo.addItems(["待施工 (0)", "施工中 (1)", "已完工 (2)", "已审核 (3)", "已验收 (4)"])
|
||||
status_layout.addWidget(self.status_combo)
|
||||
basic_layout.addLayout(status_layout)
|
||||
|
||||
# 项目规模
|
||||
self.scale_input = self.create_label_input(basic_layout, "项目规模:", QLineEdit())
|
||||
|
||||
# 开始日期
|
||||
start_date_layout = QHBoxLayout()
|
||||
start_date_layout.addWidget(QLabel("开始日期:"))
|
||||
self.start_date_input = QDateEdit()
|
||||
self.start_date_input.setCalendarPopup(True)
|
||||
self.start_date_input.setDate(QDate.currentDate())
|
||||
self.start_date_input.setSpecialValueText("未设置")
|
||||
self.start_date_input.setMinimumDate(QDate(1900, 1, 1))
|
||||
start_date_layout.addWidget(self.start_date_input)
|
||||
basic_layout.addLayout(start_date_layout)
|
||||
|
||||
# 结束日期
|
||||
end_date_layout = QHBoxLayout()
|
||||
end_date_layout.addWidget(QLabel("结束日期:"))
|
||||
self.end_date_input = QDateEdit()
|
||||
self.end_date_input.setCalendarPopup(True)
|
||||
self.end_date_input.setDate(QDate.currentDate())
|
||||
self.end_date_input.setSpecialValueText("未设置")
|
||||
self.end_date_input.setMinimumDate(QDate(1900, 1, 1))
|
||||
end_date_layout.addWidget(self.end_date_input)
|
||||
basic_layout.addLayout(end_date_layout)
|
||||
|
||||
# 工期
|
||||
self.duration_input = self.create_label_input(basic_layout, "工期(天):", QLineEdit())
|
||||
self.duration_input.setValidator(QIntValidator(0, 9999))
|
||||
|
||||
# 项目封面
|
||||
self.cover_url = ""
|
||||
cover_layout = QHBoxLayout()
|
||||
cover_layout.addWidget(QLabel("项目封面:"))
|
||||
self.cover_label = QLabel("未选择封面图")
|
||||
self.cover_label.setStyleSheet("color: #666; font-style: italic;")
|
||||
cover_layout.addWidget(self.cover_label)
|
||||
self.select_cover_btn = QPushButton("选择图片")
|
||||
self.select_cover_btn.clicked.connect(self.select_cover_image)
|
||||
cover_layout.addWidget(self.select_cover_btn)
|
||||
basic_layout.addLayout(cover_layout)
|
||||
|
||||
basic_info_group.setLayout(basic_layout)
|
||||
layout.addWidget(basic_info_group)
|
||||
|
||||
# 2. 委托方信息分组
|
||||
client_group = QGroupBox("委托方信息")
|
||||
client_layout = QVBoxLayout()
|
||||
|
||||
self.client_input = self.create_label_input(client_layout, "委托单位:", QLineEdit())
|
||||
self.client_contact_input = self.create_label_input(client_layout, "联系人:", QLineEdit())
|
||||
self.client_phone_input = self.create_label_input(client_layout, "联系电话:", QLineEdit())
|
||||
|
||||
client_group.setLayout(client_layout)
|
||||
layout.addWidget(client_group)
|
||||
|
||||
# 3. 检查方信息分组
|
||||
inspection_group = QGroupBox("检查方信息")
|
||||
inspection_layout = QVBoxLayout()
|
||||
|
||||
self.inspection_unit_input = self.create_label_input(inspection_layout, "检查单位:", QLineEdit())
|
||||
self.inspection_contact_input = self.create_label_input(inspection_layout, "联系人:", QLineEdit())
|
||||
self.inspection_phone_input = self.create_label_input(inspection_layout, "联系电话:", QLineEdit())
|
||||
|
||||
inspection_group.setLayout(inspection_layout)
|
||||
layout.addWidget(inspection_group)
|
||||
|
||||
# 4. 风场信息分组
|
||||
farm_group = QGroupBox("风场信息")
|
||||
farm_layout = QVBoxLayout()
|
||||
|
||||
self.farm_name_input = self.create_label_input(farm_layout, "风场名称*:", QLineEdit())
|
||||
self.farm_address_input = self.create_label_input(farm_layout, "风场地址:", QLineEdit())
|
||||
self.turbine_model_input = self.create_label_input(farm_layout, "风机型号:", QLineEdit())
|
||||
|
||||
farm_group.setLayout(farm_layout)
|
||||
layout.addWidget(farm_group)
|
||||
|
||||
# 5. 项目团队分组
|
||||
team_group = QGroupBox("项目团队")
|
||||
team_layout = QVBoxLayout()
|
||||
|
||||
self.team_leader_input = self.create_label_input(team_layout, "施工组长ID:", QLineEdit())
|
||||
self.constructors_input = self.create_label_input(team_layout, "施工人员ID:", QLineEdit())
|
||||
self.constructors_input.setPlaceholderText("多人用英文逗号分隔")
|
||||
self.quality_officer_input = self.create_label_input(team_layout, "质量员ID:", QLineEdit())
|
||||
self.auditor_input = self.create_label_input(team_layout, "安全员ID:", QLineEdit())
|
||||
|
||||
team_group.setLayout(team_layout)
|
||||
layout.addWidget(team_group)
|
||||
|
||||
# 提交按钮
|
||||
button_layout = QHBoxLayout()
|
||||
button_layout.addStretch()
|
||||
self.submit_btn = QPushButton("提交")
|
||||
self.submit_btn.setFixedWidth(100)
|
||||
self.submit_btn.clicked.connect(self.submit_data)
|
||||
button_layout.addWidget(self.submit_btn)
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
central_widget.setLayout(layout)
|
||||
|
||||
def create_label_input(self, layout, label_text, input_widget):
|
||||
"""创建标签和输入框的组合"""
|
||||
row_layout = QHBoxLayout()
|
||||
row_layout.addWidget(QLabel(label_text))
|
||||
row_layout.addWidget(input_widget)
|
||||
layout.addLayout(row_layout)
|
||||
return input_widget
|
||||
|
||||
def select_cover_image(self):
|
||||
options = QFileDialog.Options()
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "选择项目封面图", "",
|
||||
"图片文件 (*.jpg *.jpeg *.png *.gif);;所有文件 (*.*)",
|
||||
options=options
|
||||
)
|
||||
|
||||
if file_path:
|
||||
self.cover_url = file_path
|
||||
self.cover_label.setText(file_path.split('/')[-1])
|
||||
self.cover_label.setStyleSheet("color: #333; font-style: normal;")
|
||||
|
||||
def validate_inputs(self):
|
||||
if not self.project_name_input.text().strip():
|
||||
QMessageBox.warning(self, "输入错误", "项目名称不能为空!")
|
||||
return False
|
||||
if not self.farm_name_input.text().strip():
|
||||
QMessageBox.warning(self, "输入错误", "风场名称不能为空!")
|
||||
return False
|
||||
if not self.manager_id_input.text().strip():
|
||||
QMessageBox.warning(self, "输入错误", "项目经理ID不能为空!")
|
||||
return False
|
||||
return True
|
||||
|
||||
def submit_data(self):
|
||||
if not self.validate_inputs():
|
||||
return
|
||||
|
||||
# 构造请求数据
|
||||
project_data = {
|
||||
# 基本信息
|
||||
"projectName": self.project_name_input.text().strip(),
|
||||
"projectManagerId": self.manager_id_input.text().strip(),
|
||||
"status": self.status_combo.currentIndex(),
|
||||
"scale": self.scale_input.text().strip(),
|
||||
"startDate": self.start_date_input.date().toString(
|
||||
"yyyy-MM-dd") if not self.start_date_input.date().isNull() else "",
|
||||
"endDate": self.end_date_input.date().toString(
|
||||
"yyyy-MM-dd") if not self.end_date_input.date().isNull() else "",
|
||||
"duration": int(self.duration_input.text()) if self.duration_input.text().strip() else 0,
|
||||
"coverUrl": self.cover_url,
|
||||
|
||||
# 委托方信息
|
||||
"client": self.client_input.text().strip(),
|
||||
"clientContact": self.client_contact_input.text().strip(),
|
||||
"clientPhone": self.client_phone_input.text().strip(),
|
||||
|
||||
# 检查方信息
|
||||
"inspectionUnit": self.inspection_unit_input.text().strip(),
|
||||
"inspectionContact": self.inspection_contact_input.text().strip(),
|
||||
"inspectionPhone": self.inspection_phone_input.text().strip(),
|
||||
|
||||
# 风场信息
|
||||
"farmName": self.farm_name_input.text().strip(),
|
||||
"farmAddress": self.farm_address_input.text().strip(),
|
||||
"turbineModel": self.turbine_model_input.text().strip(),
|
||||
|
||||
# 项目团队
|
||||
"constructionTeamLeaderId": self.team_leader_input.text().strip(),
|
||||
"constructorIds": self.constructors_input.text().strip(),
|
||||
"qualityOfficerId": self.quality_officer_input.text().strip(),
|
||||
"auditorId": self.auditor_input.text().strip()
|
||||
}
|
||||
|
||||
# 清理空值
|
||||
project_data = {k: v for k, v in project_data.items() if v or isinstance(v, int)}
|
||||
|
||||
# 确认对话框
|
||||
reply = QMessageBox.question(
|
||||
self, '确认提交',
|
||||
'确定要提交这些项目信息吗?',
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No
|
||||
)
|
||||
|
||||
if reply == QMessageBox.No:
|
||||
return
|
||||
|
||||
# 提交数据
|
||||
url = "http://pms.dtyx.net:9158/project"
|
||||
headers = {
|
||||
"Authorization": "null",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, headers=headers, data=json.dumps(project_data))
|
||||
response.raise_for_status()
|
||||
|
||||
result = response.json()
|
||||
QMessageBox.information(
|
||||
self, "提交成功",
|
||||
f"项目信息提交成功!\n\n响应结果:\n{json.dumps(result, indent=2)}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
QMessageBox.critical(
|
||||
self, "提交失败",
|
||||
f"项目信息提交失败!\n\n错误信息:\n{str(e)}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
window = ProjectAddWindow()
|
||||
window.show()
|
||||
sys.exit(app.exec_())
|
|
@ -0,0 +1,117 @@
|
|||
import os
|
||||
import requests
|
||||
from tkinter import Tk, filedialog
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
|
||||
class AudioBatchUploader:
|
||||
def __init__(self):
|
||||
self.base_url = "http://pms.dtyx.net:9158"
|
||||
self.upload_endpoint = "/audio/upload-batch/{imageId}"
|
||||
self.image_id = "1f042a710e0a6367f22faedf5efd4116"
|
||||
|
||||
def select_audios(self) -> List[str]:
|
||||
"""打开文件选择对话框,让用户选择多个音频文件"""
|
||||
root = Tk()
|
||||
root.withdraw() # 隐藏主窗口
|
||||
|
||||
file_paths = filedialog.askopenfilenames(
|
||||
title="选择要上传的音频文件",
|
||||
filetypes=[("音频文件", "*.mp3 *.wav *.ogg *.m4a"), ("所有文件", "*.*")]
|
||||
)
|
||||
|
||||
return file_paths
|
||||
|
||||
def upload_audios(self, file_paths: List[str]) -> Dict:
|
||||
"""批量上传音频文件"""
|
||||
if not file_paths:
|
||||
print("没有选择任何文件!")
|
||||
return {"success": False, "msg": "没有选择任何文件"}
|
||||
|
||||
successful_uploads = 0
|
||||
failed_uploads = 0
|
||||
results = []
|
||||
|
||||
for file_path in file_paths:
|
||||
try:
|
||||
# 准备请求URL和headers
|
||||
url = f"{self.base_url}{self.upload_endpoint.format(imageId=self.image_id)}"
|
||||
headers = {"Authorization": None} # token为null
|
||||
|
||||
# 读取文件内容
|
||||
with open(file_path, 'rb') as f:
|
||||
files = {'file': (os.path.basename(file_path), f)}
|
||||
|
||||
# 发送请求
|
||||
response = requests.post(
|
||||
url=url,
|
||||
files=files,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
# 处理响应
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("success"):
|
||||
print(f"文件 {os.path.basename(file_path)} 上传成功!")
|
||||
successful_uploads += 1
|
||||
results.extend(result.get("data", []))
|
||||
else:
|
||||
print(f"文件 {os.path.basename(file_path)} 上传失败: {result.get('msg', '未知错误')}")
|
||||
failed_uploads += 1
|
||||
else:
|
||||
print(f"文件 {os.path.basename(file_path)} 上传失败,HTTP状态码: {response.status_code}")
|
||||
failed_uploads += 1
|
||||
|
||||
except Exception as e:
|
||||
print(f"文件 {os.path.basename(file_path)} 上传过程中发生异常: {str(e)}")
|
||||
failed_uploads += 1
|
||||
|
||||
print("\n上传完成!")
|
||||
print(f"成功: {successful_uploads} 个, 失败: {failed_uploads} 个")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"success_count": successful_uploads,
|
||||
"fail_count": failed_uploads,
|
||||
"results": results
|
||||
}
|
||||
|
||||
def run(self):
|
||||
"""运行上传程序"""
|
||||
print("=== 音频批量上传工具 ===")
|
||||
print(f"目标服务器: {self.base_url}")
|
||||
print(f"图片ID: {self.image_id}")
|
||||
print("\n请选择要上传的音频文件...")
|
||||
|
||||
# 选择文件
|
||||
audio_files = self.select_audios()
|
||||
|
||||
if not audio_files:
|
||||
print("未选择任何文件,程序退出。")
|
||||
return
|
||||
|
||||
print(f"\n已选择 {len(audio_files)} 个音频文件:")
|
||||
for file in audio_files:
|
||||
print(f"- {os.path.basename(file)}")
|
||||
|
||||
# 确认上传
|
||||
confirm = input("\n确认上传这些文件吗? (y/n): ").strip().lower()
|
||||
if confirm != 'y':
|
||||
print("上传已取消。")
|
||||
return
|
||||
|
||||
# 开始上传
|
||||
print("\n开始上传...")
|
||||
upload_result = self.upload_audios(audio_files)
|
||||
|
||||
# 显示上传结果详情
|
||||
if upload_result.get("success") and upload_result.get("results"):
|
||||
print("\n上传结果详情:")
|
||||
for result in upload_result["results"]:
|
||||
print(f"文件ID: {result.get('id')}, 保存路径: {result.get('filePath')}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uploader = AudioBatchUploader()
|
||||
uploader.run()
|
Loading…
Reference in New Issue