Perisian: Pycharm
Persekitaran: Python 3.7. 9 (Memandangkan pelanggan mungkin mempunyai sistem pengendalian yang berbeza, atas sebab keserasian)
Perpustakaan teknikal : permintaan, panda, Pyqt5, dsb. (lihat fail pergantungan untuk butiran)
Melalui analisis dan komunikasi dengan dokumen permintaan pelanggan, terdapat kira-kira keperluan berikut:
Serahkan data dalam kelompok kepada 3 antara muka berdasarkan "Atribusi Nombor Pesanan "
Memerlukan antara muka operasi GUI
Sokong log masuk jurujual yang berbeza
Secara umum Ia adalah dikatakan sebagai penyerahan data POST dan pembangunan GUI.
Bahagian ini terutamanya menggunakan teknologi perangkak Langkah-langkah yang kekal tidak berubah selama beribu-ribu tahun ialah menganalisis halaman web terlebih dahulu.
Ia didapati melalui tangkapan paket bahawa kata laluan adalah teks biasa, yang mengurangkan separuh kesukaran kemudian gunakan kata laluan yang betul untuk menganalisis pulangan selepas berjaya log masuk.
def login(self, username: str, password: str): """ 登录 """ url = "http://cloud.tiamaes.com:11349/erp/portal.bootstrap/SSOLoginAction/login.do" data = { "_tp_data": '{"parameters":{"userName":' + username + ',"pwd":' + password + '},"rowsets":{},"headers":{},"requestComponent":"0"}' } data = parse.urlencode(data).replace("+", "") resp = requests.post(url, headers=self.headers, data=data, verify=False) self.IDENTIFIER = resp.json()["headers"]["IDENTIFIER"] return self.IDENTIFIER
Saya mendapati bahawa selepas log masuk berjaya, parameter "PENGENALAN" akan dikembalikan Nilai ini adalah rentetan yang disulitkan , Saya tahu bahawa ini mesti berguna, jadi Tulis dahulu.
Memandangkan saya menggunakan akaun ujian, data yang diserahkan oleh akaun ini akan dipadamkan untuk tidak menyuntik terlalu banyak data tidak sah kepada orang lain, sebenarnya saya tidak akan lagi masukkannya di sini , dijelaskan dengan kod perniagaan.
Dapatkan maklumat kenderaan
Melalui analisis, didapati walaupun pelanggan telah memberikan beberapa maklumat kenderaan, masih banyak yang hilang maklumat yang memerlukan diri Isi semula. Melalui penangkapan paket, kami mendapati bahawa selepas memasukkan nombor kenderaan, permintaan Ajax akan dimulakan, dan maklumat lain dalam borang adalah data yang dikembalikan oleh permintaan Ajax.
def get_car_details(self, car_no: str, IDENTIFIER: str): """ 获取车辆信息 """ # print(self.IDENTIFIER) url = "http://cloud.tiamaes.com:11349/money/basis.inter/JwBusAction/getCacheJwBusByNo.do" data = { '_tp_data': '{"parameters": {"busNo": ' + str(car_no) + ', "dsName": "83"}, "rowsets": {}, "headers": {"IDENTIFIER": ' + IDENTIFIER + '}, "requestComponent": "0"}' } data = parse.urlencode(data).replace("+", "") resp = requests.post(url, headers=self.headers, data=data, verify=False) rows = resp.json()["rowsets"]["com.tp.basis.entity.entity.bus.BaJwBus"]["rows"][0] return rows
Dapatkan maklumat kakitangan
Saya tidak menemui maklumat kakitangan dalam borang melalui paket tangkap, tetapi saya menemuinya kemudian. Data yang berkaitan ditemui pada halaman.
Ini lebih menyusahkan, anda perlu menggunakan ungkapan biasa untuk memadankan data.
def get_personal_info(self, IDENTIFIER: str): """ 获取个人信息 """ url = "http://cloud.tiamaes.com:11349/money/money.action/CharteredAction/showDetail.do" data = { '_tp_data': '{"parameters":{"dsName":"83","method":"add","recId":"-1"},"rowsets":{},"headers":{"IDENTIFIER":' + IDENTIFIER + '},"requestComponent":"1"}' } data = parse.urlencode(data).replace("+", "") resp = requests.post(url, headers=self.headers, data=data, verify=False) json_data = eval(re.findall(r'<code>.*?"rows":\[(.*?)\]', resp.text)[0]) return json_data
Mulakan permintaan dan serahkan data
Dapatkan pengecam, maklumat kenderaan dan maklumat kakitangan yang dikembalikan melalui log masuk, dan selebihnya ialah untuk berkomunikasi dengan pelanggan Gabungkan data yang diberikan dan mulakan permintaan. Perlu diingat bahawa parameter permintaan perlu ditukar kepada pengekodan URL Parameter permintaan juga merupakan bahagian yang paling menyusahkan perangkak ini. Di sini kami menunjukkan kepada anda parameter yang perlu dihantar dalam permintaan.
Terdapat banyak parameter dan keperluan format adalah ketat Dalam keseluruhan proses pembangunan, penyahpepijatan di sini juga mengambil masa yang paling lama. Selepas penyahpepijatan, kod harus dipermudahkan Saya terlalu malas untuk menukar gabungan yang perlu digabungkan selepas penyahpepijatan, jadi bahagian ini agak berlebihan.
def submit_data(self, i: dict, IDENTIFIER: str): """ 众意数据提交 """ personal_info = self.get_personal_info(IDENTIFIER) # 获取个人信息 personal_info_data = str(personal_info).replace("'", '"') # 将personal_info转换为字符串 url = "http://cloud.tiamaes.com:11349/money/money.action/CharteredAction/saveForm.do" print(f'开始处理--{i["单号归属"]}--数据') memo = f'工单号{i["工单号"]}、餐费{i["餐费"]}、住宿{i["住宿"]}、过路过桥费{i["过路过桥费"]}、油费{i["油费"]}、备注{i["备注"]}' # 拼接备注信息 car_infos = self.get_car_details(str(i["车号"]), IDENTIFIER) # 获取车辆信息 pay_type = { "现金": "3", "转账": "2", "欠款": "1" } single_and_double = { "单程": "1", "双程": "2" } colType = pay_type[i["结账方式"]] # 获取结账方式编码 oddEven = single_and_double[i["单双程"]] # 获取单双程编码 now_date = datetime.datetime.now().date().strftime("%Y-%m-%d") # 获取当前日期 .......(此处省略) data["_tp_data"] = data["_tp_data"].replace('"dsName":"83"', '"dsName":"82"') data = parse.urlencode(data).replace("+", "") # 将字典转换成url编码 resp = requests.post(url, headers=self.headers, data=data, verify=False).json() order_id = resp["rowsets"]["com.tp.money.entity.basic.Chartered"]["rows"][0]["recNo"] # 获取订单编号 i["包车单号"] = order_id return data
Pembangunan GUI agak mudah jika anda tidak mahu mencantikkannya, pemalam asli Pyqt akan melakukannya di sini dan digunakan hanya Sesetengah pengetahuan menjadikan antara muka tanpa sempadan dan pengindahan yang sesuai.
Log Masuk
from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor from PyQt5.QtWidgets import (QFrame, QMessageBox, QGraphicsDropShadowEffect) from Ui import login_ui from Ui.submit_ui_main import MySubmitForm from submit import TransitSubmit class MyLogin(login_ui.Ui_LoginForm, QFrame): def __init__(self, submit: TransitSubmit): super().__init__() # self.IDENTIFIER = None # self.my_main_window = None self.setupUi(self) self.submit = submit # 设置无边框模式 self.setWindowFlag(Qt.FramelessWindowHint) # 将界面设置为无框 self.setAttribute(Qt.WA_TranslucentBackground) # 将界面属性设置为半透明 self.shadow = QGraphicsDropShadowEffect() # 设定一个阴影,半径为10,颜色为#444444,定位为0,0 self.shadow.setBlurRadius(10) self.shadow.setColor(QColor("#444444")) self.shadow.setOffset(0, 0) self.frame.setGraphicsEffect(self.shadow) # 为frame设定阴影效果 # ------------------------------------------------ self.show() self.pushButton_3.clicked.connect(self.close) # 关闭按钮 self.pushButton_login.clicked.connect(self.do_login) # 登录按钮 # 以下是控制窗口移动的代码 def mousePressEvent(self, event): # 鼠标左键按下时获取鼠标坐标,按下右键取消 if event.button() == Qt.LeftButton: self.m_flag = True self.m_Position = event.globalPos() - self.pos() event.accept() elif event.button() == Qt.RightButton: self.m_flag = False def mouseMoveEvent(self, QMouseEvent): # 鼠标在按下左键的情况下移动时,根据坐标移动界面 if Qt.LeftButton and self.m_flag: self.move(QMouseEvent.globalPos() - self.m_Position) QMouseEvent.accept() def mouseReleaseEvent(self, QMouseEvent): # 鼠标按键释放时,取消移动 self.m_flag = False # 登录事件 def do_login(self): username = self.lineEdit_username.text() password = self.lineEdit_password.text() if not username or not password: QMessageBox.warning(self, '警告', '用户名或密码不能为空', QMessageBox.Yes) return else: IDENTIFIER = self.submit.login(username, password) if not IDENTIFIER: QMessageBox.warning(self, '警告', '用户名或密码错误', QMessageBox.Yes) return self.hide() # 隐藏登录界面 my_submit_form = MySubmitForm(self.submit, IDENTIFIER) my_submit_form.exec_() # 显示主界面
Operasi Perniagaan
class MySubmitForm(submitform_ui.Ui_Dialog_Submit, QDialog): def __init__(self, submit: TransitSubmit, IDENTIFIER: str): super().__init__() ...... self.setupUi(self) ...... self.progressBar.hide() # 关闭进度条显示 self.setWindowFlags(Qt.FramelessWindowHint) # 无边框 self.setAttribute(Qt.WA_TranslucentBackground) # 设置窗口透明 self.pushButton_mini.clicked.connect(self.showMinimized) # 实现最小化 self.pushButton_close.clicked.connect(self.close) # 实现关闭功能 ...... self.show() # 实现鼠标拖拽功能 def mousePressEvent(self, event): self.pressX = event.x() # 记录鼠标按下的时候的坐标 self.pressY = event.y() def mouseMoveEvent(self, event): x = event.x() y = event.y() # 获取移动后的坐标 moveX = x - self.pressX moveY = y - self.pressY # 计算移动了多少 positionX = self.frameGeometry().x() + moveX positionY = self.frameGeometry().y() + moveY # 计算移动后主窗口在桌面的位置 self.move(positionX, positionY) # 移动主窗口 ......
Mari bercakap lebih lanjut di sini Pada mulanya, saya menggunakan QFrame yang sama seperti log masuk, tetapi ia tidak mempunyai kaedah exec() dan ia tidak boleh muncul selepas log masuk berjaya. . Mungkin juga pengetahuan saya terhad dan saya tidak dapat melakukannya. Dengan menganalisis kod sumber, saya mendapati bahawa QDialog mempunyai kaedah ini untuk mencapai pop timbul Kemudian, saya menukarnya dan menggunakan QDialog untuk mencipta antara muka tanpa sempadan.
Saya tidak akan bercakap banyak tentang pembungkusan yang lain Terdapat banyak tutorial di Internet Apa yang saya gunakan di sini ialah pembungkusan D, pemampatan upx, dan ikon yang telah diubah .
Atas ialah kandungan terperinci Bagaimana untuk memasukkan data sistem ERP secara automatik dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!