scd_zhijian_old.py 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. # -*- coding: utf-8 -*-
  2. # Form implementation generated from reading ui file '.\ui文件\杀虫灯质检工具.ui'
  3. #
  4. # Created by: PyQt5 UI code generator 5.15.4
  5. #
  6. # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  7. # run again. Do not edit this file unless you know what you are doing.
  8. # pyinstaller -n "杀虫灯检验工具(v3.2)" -D -w f:\image_down_code\scd_zhijian.py -i .\LOGO.ico
  9. from PyQt5 import QtCore, QtGui, QtWidgets
  10. import os
  11. import sys
  12. import re
  13. import ast
  14. from urllib import parse
  15. import json
  16. import time
  17. import datetime
  18. import requests
  19. import uuid
  20. import pymongo
  21. import pymysql
  22. from xlrd import open_workbook
  23. from xlsxwriter.workbook import Workbook
  24. save_filename = ""
  25. pwd_str = "yf6021"
  26. toji_format = {
  27. 'font_name' : '宋体',
  28. 'font_size': 14,
  29. 'font_color': 'black',
  30. 'text_wrap': True,
  31. 'bold': False,
  32. 'fg_color': '92D050',
  33. 'align': 'center',
  34. 'valign': 'vcenter',
  35. 'border': 1,
  36. 'top': 1,
  37. 'left': 1,
  38. 'right': 1,
  39. 'bottom': 1
  40. }
  41. title_format = {
  42. 'font_name' : '宋体',
  43. 'font_size': 12,
  44. 'bold': True,
  45. 'align': 'center',
  46. 'valign': 'vcenter',
  47. 'border': 1,
  48. 'top': 1,
  49. 'left': 1,
  50. 'right': 1,
  51. 'bottom': 1
  52. }
  53. merge_title_format = {
  54. 'font_name' : '宋体',
  55. 'font_size': 26,
  56. 'bold': True,
  57. 'align': 'center',
  58. 'valign': 'vcenter',
  59. "fg_color": "8DB4E2",
  60. 'border': 1,
  61. 'top': 1,
  62. 'left': 1,
  63. 'right': 1,
  64. 'bottom': 1
  65. }
  66. explain_formal = {
  67. 'font_name' : '宋体',
  68. 'font_size': 11,
  69. 'font_color': 'black',
  70. 'text_wrap': True,
  71. 'align': 'justify',
  72. 'valign': 'vcenter',
  73. 'border': 1,
  74. 'top': 1,
  75. 'left': 1,
  76. 'right': 1,
  77. 'bottom': 1
  78. }
  79. formal_format = {
  80. 'font_name' : '宋体',
  81. 'font_size': 11,
  82. 'font_color': 'black',
  83. 'fg_color': '77E88C',
  84. 'text_wrap': True,
  85. 'align': 'center',
  86. 'valign': 'vcenter',
  87. 'border': 1,
  88. 'top': 1,
  89. 'left': 1,
  90. 'right': 1,
  91. 'bottom': 1
  92. }
  93. common_format = {
  94. 'font_name' : '宋体',
  95. 'font_size': 11,
  96. 'font_color': 'black',
  97. "fg_color": 'E7EC73',
  98. 'text_wrap': True,
  99. 'align': 'center',
  100. 'valign': 'vcenter',
  101. 'border': 1,
  102. 'top': 1,
  103. 'left': 1,
  104. 'right': 1,
  105. 'bottom': 1
  106. }
  107. error_format = {
  108. 'font_name' : '宋体',
  109. 'font_size': 11,
  110. 'font_color': 'black',
  111. "fg_color": 'F4746A',
  112. 'text_wrap': True,
  113. 'align': 'center',
  114. 'valign': 'vcenter',
  115. 'border': 1,
  116. 'top': 1,
  117. 'left': 1,
  118. 'right': 1,
  119. 'bottom': 1
  120. }
  121. class Ui_MainWindow(object):
  122. """GUI界面"""
  123. def setupUi(self, MainWindow):
  124. MainWindow.setObjectName("MainWindow")
  125. MainWindow.resize(701, 644)
  126. font = QtGui.QFont()
  127. font.setFamily("Arial")
  128. font.setPointSize(12)
  129. MainWindow.setFont(font)
  130. icon = QtGui.QIcon("logo.ico")
  131. MainWindow.setWindowIcon(icon)
  132. self.centralwidget = QtWidgets.QWidget(MainWindow)
  133. self.centralwidget.setObjectName("centralwidget")
  134. self.pageTitleLabel = QtWidgets.QLabel(self.centralwidget)
  135. self.pageTitleLabel.setGeometry(QtCore.QRect(139, 50, 429, 42))
  136. font = QtGui.QFont()
  137. font.setFamily("楷体")
  138. font.setPointSize(28)
  139. self.pageTitleLabel.setFont(font)
  140. self.pageTitleLabel.setTextFormat(QtCore.Qt.AutoText)
  141. self.pageTitleLabel.setObjectName("pageTitleLabel")
  142. self.inputFileLabel = QtWidgets.QLabel(self.centralwidget)
  143. self.inputFileLabel.setGeometry(QtCore.QRect(180, 130, 121, 21))
  144. self.inputFileLabel.setObjectName("inputFileLabel")
  145. self.inputFileEdit = QtWidgets.QLineEdit(self.centralwidget)
  146. self.inputFileEdit.setGeometry(QtCore.QRect(310, 130, 151, 21))
  147. self.inputFileEdit.setFocusPolicy(QtCore.Qt.NoFocus)
  148. font = QtGui.QFont()
  149. font.setFamily("Arial")
  150. font.setPointSize(8)
  151. self.inputFileEdit.setFont(font)
  152. self.inputFileEdit.setObjectName("inputFileEdit")
  153. self.inputFileTool = QtWidgets.QToolButton(self.centralwidget)
  154. self.inputFileTool.setGeometry(QtCore.QRect(470, 130, 71, 21))
  155. font = QtGui.QFont()
  156. font.setFamily("Arial")
  157. font.setPointSize(10)
  158. self.inputFileTool.setFont(font)
  159. self.inputFileTool.setObjectName("inputFileTool")
  160. self.savePathLabel = QtWidgets.QLabel(self.centralwidget)
  161. self.savePathLabel.setGeometry(QtCore.QRect(180, 170, 121, 21))
  162. self.savePathLabel.setObjectName("savePathLabel")
  163. self.savePathEdit = QtWidgets.QLineEdit(self.centralwidget)
  164. self.savePathEdit.setGeometry(QtCore.QRect(310, 170, 151, 21))
  165. self.savePathEdit.setFocusPolicy(QtCore.Qt.NoFocus)
  166. font = QtGui.QFont()
  167. font.setFamily("Arial")
  168. font.setPointSize(8)
  169. self.savePathEdit.setFont(font)
  170. self.savePathEdit.setObjectName("savePathEdit")
  171. self.savePathTool = QtWidgets.QToolButton(self.centralwidget)
  172. self.savePathTool.setGeometry(QtCore.QRect(470, 170, 71, 21))
  173. font = QtGui.QFont()
  174. font.setFamily("Arial")
  175. font.setPointSize(10)
  176. self.savePathTool.setFont(font)
  177. self.savePathTool.setObjectName("savePathTool")
  178. self.startTimeLabel = QtWidgets.QLabel(self.centralwidget)
  179. self.startTimeLabel.setGeometry(QtCore.QRect(180, 210, 121, 21))
  180. self.startTimeLabel.setObjectName("startTimeLabel")
  181. self.startTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
  182. self.startTimeEdit.setGeometry(QtCore.QRect(310, 210, 151, 21))
  183. self.startTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2025, 12, 31), QtCore.QTime(23, 59, 59)))
  184. self.startTimeEdit.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2023, 1, 1), QtCore.QTime(1, 0, 0)))
  185. self.startTimeEdit.setObjectName("startTimeEdit")
  186. self.endTimeLabel = QtWidgets.QLabel(self.centralwidget)
  187. self.endTimeLabel.setGeometry(QtCore.QRect(180, 250, 121, 21))
  188. self.endTimeLabel.setObjectName("endTimeLabel")
  189. self.endTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
  190. self.endTimeEdit.setGeometry(QtCore.QRect(310, 250, 151, 21))
  191. self.endTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2025, 12, 31), QtCore.QTime(23, 59, 59)))
  192. self.endTimeEdit.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2023, 1, 1), QtCore.QTime(1, 0, 0)))
  193. self.endTimeEdit.setObjectName("endTimeEdit")
  194. self.platLabel = QtWidgets.QLabel(self.centralwidget)
  195. self.platLabel.setGeometry(QtCore.QRect(180, 290, 121, 21))
  196. self.platLabel.setObjectName("dianjiLabel")
  197. self.platBox = QtWidgets.QComboBox(self.centralwidget)
  198. self.platBox.setGeometry(QtCore.QRect(310, 290, 151, 21))
  199. self.platBox.addItems(['大数据平台','四情平台'])
  200. font = QtGui.QFont()
  201. font.setFamily("Arial")
  202. font.setPointSize(11)
  203. self.platBox.setFont(font)
  204. self.platBox.setObjectName("platBox")
  205. self.stm8vsLabel = QtWidgets.QLabel(self.centralwidget)
  206. self.stm8vsLabel.setGeometry(QtCore.QRect(180, 330, 121, 21))
  207. self.stm8vsLabel.setObjectName("stm8vsLabel")
  208. self.stm8vsEdit = QtWidgets.QLineEdit(self.centralwidget)
  209. self.stm8vsEdit.setGeometry(QtCore.QRect(310, 330, 151, 21))
  210. font = QtGui.QFont()
  211. font.setFamily("Arial")
  212. font.setPointSize(11)
  213. self.stm8vsEdit.setFont(font)
  214. self.stm8vsEdit.setObjectName("stm8vsEdit")
  215. self.dverLabel = QtWidgets.QLabel(self.centralwidget)
  216. self.dverLabel.setGeometry(QtCore.QRect(180, 370, 121, 21))
  217. self.dverLabel.setObjectName("dverLabel")
  218. self.dverEdit = QtWidgets.QLineEdit(self.centralwidget)
  219. self.dverEdit.setGeometry(QtCore.QRect(310, 370, 151, 21))
  220. font = QtGui.QFont()
  221. font.setFamily("Arial")
  222. font.setPointSize(11)
  223. self.dverEdit.setFont(font)
  224. self.dverEdit.setObjectName("dverEdit")
  225. self.orderLabel = QtWidgets.QLabel(self.centralwidget)
  226. self.orderLabel.setGeometry(QtCore.QRect(180, 410, 121, 21))
  227. self.orderLabel.setObjectName("dverLabel")
  228. self.orderEdit = QtWidgets.QLineEdit(self.centralwidget)
  229. self.orderEdit.setGeometry(QtCore.QRect(310, 410, 151, 21))
  230. font = QtGui.QFont()
  231. font.setFamily("Arial")
  232. font.setPointSize(11)
  233. self.orderEdit.setFont(font)
  234. self.orderEdit.setObjectName("dverEdit")
  235. self.pushButton = QtWidgets.QPushButton(self.centralwidget)
  236. self.pushButton.setGeometry(QtCore.QRect(300, 450, 111, 41))
  237. self.pushButton.setObjectName("pushButton")
  238. self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
  239. self.progressBar.setGeometry(QtCore.QRect(130, 510, 491, 31))
  240. self.progressBar.setProperty("value", 0)
  241. self.progressBar.setVisible(False)
  242. self.progressBar.setObjectName("progressBar")
  243. MainWindow.setCentralWidget(self.centralwidget)
  244. self.retranslateUi(MainWindow)
  245. self.inputFileTool.clicked.connect(self.input_file_path)
  246. self.savePathTool.clicked.connect(self.out_save_location)
  247. self.pushButton.clicked.connect(self.on_click)
  248. QtCore.QMetaObject.connectSlotsByName(MainWindow)
  249. def retranslateUi(self, MainWindow):
  250. _translate = QtCore.QCoreApplication.translate
  251. MainWindow.setWindowTitle(_translate("MainWindow", "杀虫灯质检工具"))
  252. self.savePathTool.setText(_translate("MainWindow", "选择文件夹"))
  253. self.inputFileTool.setText(_translate("MainWindow", "选择文件"))
  254. self.pageTitleLabel.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-weight:600; color:#3a45aa;\">云飞杀虫灯设备质检工具</span></p></body></html>"))
  255. self.savePathLabel.setText(_translate("MainWindow", "|输出文件位置:"))
  256. self.inputFileLabel.setText(_translate("MainWindow", "|输入文件位置:"))
  257. self.startTimeLabel.setText(_translate("MainWindow", "|开始时间:"))
  258. self.endTimeLabel.setText(_translate("MainWindow", "|结束时间:"))
  259. self.platLabel.setText(_translate("MainWindow", "|检验平台:"))
  260. self.stm8vsLabel.setText(_translate("MainWindow", "|主板版本号:"))
  261. self.dverLabel.setText(_translate("MainWindow", "|联网模块版本号:"))
  262. self.orderLabel.setText(_translate("MainWindow", "|任务单号:"))
  263. self.pushButton.setText(_translate("MainWindow", "开始导出"))
  264. def input_file_path(self):
  265. file_path = QtWidgets.QFileDialog.getOpenFileName(None,"选取文件","./","All Files (*.xlsx;*.xls);;Text Files (*.txt)")
  266. self.inputFileEdit.setText(file_path[0])
  267. self.inputFileEdit.setStyleSheet("color:black;")
  268. def out_save_location(self):
  269. fname = QtWidgets.QFileDialog.getExistingDirectory(None, '选取文件夹', './')
  270. self.savePathEdit.setText(fname)
  271. self.savePathEdit.setStyleSheet("color:black;")
  272. def on_click(self):
  273. file_path = self.inputFileEdit.text()
  274. save_path = self.savePathEdit.text()
  275. start_time = self.startTimeEdit.dateTime().toPyDateTime()
  276. end_time = self.endTimeEdit.dateTime().toPyDateTime()
  277. set_plat = self.platBox.currentText()
  278. set_stm8vs = self.stm8vsEdit.text()
  279. set_dver = self.dverEdit.text()
  280. set_order = self.orderEdit.text()
  281. if not all ([file_path,save_path,start_time,end_time,set_stm8vs,set_dver,set_order]):
  282. QtWidgets.QMessageBox.information(None, "提示", "选项未填写完整")
  283. elif end_time < start_time:
  284. QtWidgets.QMessageBox.information(None, "提示", "结束日期应在开始日期之后")
  285. else:
  286. xls = open_workbook(file_path)
  287. sheet_object = xls.sheets()[0]
  288. ncols = sheet_object.ncols
  289. read_dict = {}
  290. for i in range(ncols):
  291. col_value = sheet_object.col_values(i)
  292. read_dict[col_value[0]] = col_value[1:]
  293. device_list = read_dict.get("设备ID")
  294. if device_list:
  295. self.inputFileTool.setEnabled(False)
  296. self.savePathTool.setEnabled(False)
  297. self.startTimeEdit.setEnabled(False)
  298. self.endTimeEdit.setEnabled(False)
  299. self.platBox.setEnabled(False)
  300. self.stm8vsEdit.setEnabled(False)
  301. self.dverEdit.setEnabled(False)
  302. self.orderEdit.setEnabled(False)
  303. self.pushButton.setEnabled(False)
  304. self.pushButton.setText("执行中...")
  305. self.runThread = SCDThread(device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_dver,set_order)
  306. self.runThread.proess_signal.connect(self.set_progressbar_value)
  307. self.runThread.start()
  308. self.progressBar.setVisible(True)
  309. else:
  310. QtWidgets.QMessageBox.information(None, "提示", "输入文件无'设备ID'列或该列无数据")
  311. def set_progressbar_value(self, value):
  312. self.progressBar.setValue(value)
  313. if value == 100:
  314. QtWidgets.QMessageBox.information(None, "提示", "文件导出完毕!导出文件名:\n{}".format(save_filename))
  315. self.inputFileTool.setEnabled(True)
  316. self.inputFileEdit.setText("")
  317. self.savePathTool.setEnabled(True)
  318. self.savePathEdit.setText("")
  319. self.startTimeEdit.setEnabled(True)
  320. self.endTimeEdit.setEnabled(True)
  321. self.platBox.setEnabled(True)
  322. self.stm8vsEdit.setEnabled(True)
  323. self.stm8vsEdit.setText("")
  324. self.dverEdit.setEnabled(True)
  325. self.dverEdit.setText("")
  326. self.orderEdit.setEnabled(True)
  327. self.orderEdit.setText("")
  328. self.pushButton.setEnabled(True)
  329. self.pushButton.setText("开始导出")
  330. self.progressBar.setVisible(False)
  331. self.progressBar.setValue(0)
  332. return
  333. class SCDThread(QtCore.QThread):
  334. """涉及进度条需主界面动态执行GUI,线程执行业务逻辑,避免主页面卡死"""
  335. proess_signal = QtCore.pyqtSignal(int)
  336. def __init__(self,device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_dver,set_order):
  337. super(SCDThread, self).__init__()
  338. self.device_list = device_list
  339. self.save_path = save_path
  340. self.start_time = time.mktime(start_time.timetuple())
  341. self.end_time = time.mktime(end_time.timetuple())
  342. self.start_time_str = start_time.strftime("%y-%m-%d %H:%M:%S")
  343. self.end_time_str = end_time.strftime("%y-%m-%d %H:%M:%S")
  344. self.set_plat = set_plat
  345. self.set_stm8vs = set_stm8vs
  346. self.set_dver = set_dver
  347. self.set_order = set_order
  348. self.user = parse.quote_plus("root")
  349. self.passwd = parse.quote_plus("yfkj@6020")
  350. self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
  351. self.db = self.myclient.smartfarming
  352. self.device_collection = self.db.sa_device
  353. self.scd_collection = self.db.sa_device_scd_data
  354. self.config = {
  355. 'host': '120.27.222.26',
  356. 'port': 3306,
  357. 'user': 'yfwlw',
  358. 'password': 'sql_yfkj_6019',
  359. 'db': 'yfwlw',
  360. 'charset': 'utf8mb4',
  361. 'cursorclass': pymysql.cursors.DictCursor,
  362. }
  363. self.connection = pymysql.connect(**self.config)
  364. self.cursor = self.connection.cursor()
  365. def mongo_ping(self):
  366. """mongo-ping预防连接失效"""
  367. try:
  368. self.myclient.admin.command('ping')
  369. except: # "ConnectionFailure"
  370. self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
  371. self.db = self.myclient.smartfarming
  372. self.device_collection = self.db.sa_device
  373. self.scd_collection = self.db.sa_device_scd_data
  374. def sql_ping(self):
  375. """mysql-ping 预防连接失效"""
  376. try:
  377. self.connection.ping()
  378. except:
  379. self.connection = pymysql.connect(**self.config)
  380. self.cursor = self.connection.cursor()
  381. def __time_dif(self,checkdatetime):
  382. """计算时间差"""
  383. nowdatetime = datetime.datetime.now()
  384. checkdatetime = datetime.datetime.strptime(checkdatetime, "%Y-%m-%d %H:%M:%S")
  385. timedif = checkdatetime - nowdatetime
  386. return timedif.days
  387. def device_their_platform(self,shortId):
  388. """确定设备所在平台已经完整设备号"""
  389. self.mongo_ping()
  390. self.sql_ping()
  391. regex = re.compile('.*{}$'.format(shortId))
  392. bd_device_dict = self.device_collection.find_one(
  393. filter = {"device_id":regex,"device_type_id":2},
  394. projection = {'_id': 0},
  395. sort = [('uptime', pymongo.DESCENDING)]
  396. )
  397. device_sql = "SELECT * FROM AppInfoManage_scdstatus WHERE equip_id_id LIKE '%{}' ORDER BY upl_time DESC LIMIT 1;".format(shortId)
  398. self.cursor.execute(device_sql)
  399. sq_device_dict = self.cursor.fetchone()
  400. if bd_device_dict and sq_device_dict:
  401. bd_upltime = bd_device_dict["uptime"]
  402. sq_upltime = time.mktime(sq_device_dict["upl_time"].timetuple())
  403. if bd_upltime >= sq_upltime:
  404. d_id = bd_device_dict["id"]
  405. deviceId = bd_device_dict["device_id"]
  406. platform = "大数据平台"
  407. else:
  408. d_id = ""
  409. deviceId = sq_device_dict["equip_id_id"]
  410. platform = "四情平台"
  411. elif bd_device_dict and not sq_device_dict:
  412. d_id = bd_device_dict["id"]
  413. deviceId = bd_device_dict["device_id"]
  414. platform = "大数据平台"
  415. return d_id,deviceId,platform
  416. elif not bd_device_dict and sq_device_dict:
  417. d_id = ""
  418. deviceId = sq_device_dict["equip_id_id"]
  419. platform = "四情平台"
  420. else:
  421. d_id = ""
  422. deviceId = "平台无此设备"
  423. platform = "未知"
  424. return d_id,deviceId,platform
  425. def sim_info(self,iccid):
  426. """查询卡信息"""
  427. url = "http://8.136.98.49:10001/iotcard/platsimview/inquiries/"
  428. try:
  429. response = requests.request("POST", url, data={"iccid":iccid})
  430. except:
  431. return [0,"查询卡信息异常稍后重试"]
  432. else:
  433. res_data = json.loads(response.text)
  434. if res_data["msg"]=="success" and res_data["data"]:
  435. expiry_date = res_data["data"]["expiry_date"]
  436. if expiry_date == "未知":
  437. return [0,"未查询到卡信息"]
  438. elif expiry_date == "未激活":
  439. return [3, "未激活"]
  440. else:
  441. time_difference = self.__time_dif(expiry_date)
  442. if time_difference < 30:
  443. return [0,"有效期剩余{}天".format(time_difference)]
  444. elif time_difference >= 181:
  445. return [1,"有效期剩余{}天".format(time_difference)]
  446. else:
  447. return [2,"有效期剩余{}天".format(time_difference)]
  448. else:
  449. return [0,"查询无结果"]
  450. def __bigdata_verify(self,data_cursor,proess):
  451. """获取大数据平台查询结果"""
  452. ds_verify,ct_verify,cv_verify,bv_verify,rps_verify = [1,"合格"],[0,"无电击数据"],[0,"不存在充电状态"],[1,"合格"],[0,"无雨控数据"]
  453. tt_verify,stm8vs_verify,dver_verify,lng_verify,lat_verify = [1,"合格"],[1,self.set_stm8vs],[1,self.set_dver],[1,"合格"],[1,"合格"]
  454. ws_list, ws_count = [],0
  455. iccid = ""
  456. # 开关机状态
  457. open_close_device = {
  458. "open": 0,
  459. "close": 0
  460. }
  461. # 电击次数
  462. dianji = {
  463. "count": 0,
  464. "single_count_gte": False
  465. }
  466. # 充电电压
  467. chongdian_dianya = []
  468. # 电池电压
  469. dianchi_dianya = []
  470. # 雨控保护
  471. yukong_protect = {
  472. "count": 0,
  473. "datetime": []
  474. }
  475. # 光控定时时长
  476. guangkong = []
  477. for index,i in enumerate(data_cursor):
  478. addtime = i["addtime"]
  479. data_strftime = datetime.datetime.fromtimestamp(addtime).strftime("%Y-%m-%d %H:%M:%S")
  480. device_data = i["device_data"]
  481. device_data = ast.literal_eval(device_data)
  482. # 设备开关机
  483. open_close = device_data.get("ds","0")
  484. if open_close == "0":
  485. open_close_device["close"] += 1
  486. if open_close == "1":
  487. open_close_device["open"] += 1
  488. # 工作状态
  489. ws = device_data.get("ws","0")
  490. ws_list.append(ws)
  491. if ws == "1":
  492. ws_count += 1
  493. elif ws == "2":
  494. # 在工作状态 充电电压
  495. chongdian_dianya.append(float(device_data.get("cv","0")))
  496. # 电池电压
  497. dianchi_dianya.append(float(device_data.get("bv","0")))
  498. # 电击次数
  499. dianji_count = int(device_data.get("ct","0"))
  500. dianji['count'] += dianji_count
  501. # 雨控保护
  502. if device_data.get("rps","0") == "1":
  503. yukong_protect["count"] += 1
  504. yukong_protect["datetime"].append(data_strftime)
  505. # 光控定时时长
  506. if device_data.get("ts","0") == "0":
  507. guangkong.append(int(device_data.get("tt","0")))
  508. # 主板代码版本号 (不用展示)
  509. if device_data.get("stm8vs","0") != self.set_stm8vs:
  510. stm8vs_verify[0],stm8vs_verify[1] = 0, device_data.get("stm8vs","0")
  511. # SIM 卡卡号
  512. if device_data.get("iccid",""):
  513. iccid = device_data.get("iccid","")
  514. # 4G 物联网模块代码版本号
  515. if device_data.get("dver","0") != self.set_dver:
  516. dver_verify[0],dver_verify[1] = 0, device_data.get("dver","0")
  517. # 经纬度
  518. if float(device_data.get("lng","0")) < 113.7536111 and float(device_data.get("lng","0")) > 113.7869444:
  519. lng_verify[0],lng_verify[1] = 0, data_strftime+"超出范围"
  520. if float(device_data.get("lat","0")) < 35.0125 and float(device_data.get("lat","0")) > 35.0458333:
  521. lat_verify[0],lat_verify[1] = 0, data_strftime+"超出范围"
  522. prosee = proess + ((index+1)/data_cursor.count()*(1/len(self.device_list))*100)
  523. if int(prosee) == 100:
  524. self.proess_signal.emit(99)
  525. else:
  526. self.proess_signal.emit(int(prosee))
  527. # 开关机状态 确认 设备开关均为开机
  528. if open_close_device["open"] != 0 and open_close_device["close"] == 0:
  529. ds_verify = [1, f'{str(open_close_device["open"])}条数据均为开机']
  530. else:
  531. ds_verify = [0, f'{str(open_close_device["open"])}条数据为开机, {str(open_close_device["close"])}条数据为关机']
  532. # 工作状态
  533. if "0" in ws_list:
  534. if "1" in ws_list:
  535. if "2" in ws_list:
  536. stamp_diff = self.end_time - self.start_time
  537. day_diff = round(stamp_diff / (12*60*60))
  538. if day_diff <= 1:
  539. low_limit, high_limit = 20, 30
  540. else:
  541. low_limit, high_limit = 20*day_diff, 30*day_diff
  542. if ws_count>low_limit and ws_count<high_limit:
  543. ws_verify=[1,"理论数据量区间({},{}),实际工作状态数据量为{}".format(low_limit,high_limit,ws_count)]
  544. else:
  545. ws_verify=[0,"理论数据量区间({},{}),实际工作状态数据量为{}".format(low_limit,high_limit,ws_count)]
  546. else:
  547. ws_verify=[0,"缺少充电状态"]
  548. else:
  549. ws_verify=[0,"缺少工作状态"]
  550. else:
  551. ws_verify=[0,"缺少待机状态"]
  552. # 电击次数
  553. if not dianji["single_count_gte"]:
  554. ct_verify = [1, f'击杀总数:{str(dianji["count"])},且单条数据均没有超1000']
  555. else:
  556. ct_verify = [0, f'击杀总数:{str(dianji["count"])},均在单条数据超1000情况']
  557. # 充电电压
  558. if chongdian_dianya:
  559. chong_max = max(chongdian_dianya)
  560. chong_min = max(chongdian_dianya)
  561. if chong_max < 23 and chong_min > 7:
  562. cv_verify = [1, f"最小电压值:{str(chong_min)} 最大电压值:{str(chong_max)}"]
  563. else:
  564. cv_verify = [0, f"最小电压值:{str(chong_min)} 最大电压值:{str(chong_max)}"]
  565. else:
  566. cv_verify = [0, "不存在充电状态"]
  567. # 电池电压
  568. if dianchi_dianya:
  569. dian_max = max(dianchi_dianya)
  570. dian_min = min(dianchi_dianya)
  571. if dian_max < 15 and dian_min > 12:
  572. bv_verify = [1, f"最小电压值:{str(dian_min)} 最大电压值:{str(dian_max)}"]
  573. else:
  574. bv_verify = [0, f"最小电压值:{str(dian_min)} 最大电压值:{str(dian_max)}"]
  575. else:
  576. bv_verify = [0, "不存在充电状态"]
  577. # 雨控保护
  578. if yukong_protect["count"] > 0:
  579. rps_verify = [1, f'上报{str(yukong_protect["count"])}条雨控数据首条雨控时间:{yukong_protect["datetime"][0]}']
  580. # 光控定时时长
  581. guangkong_count = list(set(guangkong))
  582. if len(guangkong_count) == 1 and 4 in guangkong_count:
  583. tt_verify = [1, '光控定时时长为4小时']
  584. else:
  585. tt_verify = [0, '光控定时时长异常']
  586. if iccid:
  587. sim_verify = self.sim_info(iccid)
  588. else:
  589. sim_verify = [0,"数据内无iccid"]
  590. return [
  591. ds_verify, # 开关机状态
  592. ws_verify, # 工作状态
  593. ct_verify, # 电击次数
  594. cv_verify, # 充电电压
  595. bv_verify, # 电池电压
  596. rps_verify, # 雨控保护
  597. tt_verify, # 光控定时时长
  598. stm8vs_verify, # 主板代码版本号
  599. sim_verify, # SIM 卡卡号
  600. dver_verify, # 4G 物联网模块代码版本号
  601. lng_verify, # 经度
  602. lat_verify # 纬度
  603. ]
  604. def __siqing_verify(self,data_result,status_result,proess):
  605. """获取四情平台查询结果"""
  606. ds_verify,ct_verify,cv_verify,bv_verify,rps_verify = [1,"合格"],[0,"无电击数据"],[0,"不存在充电状态"],[1,"合格"],[0,"无雨控数据"]
  607. tt_verify,stm8vs_verify,dver_verify,lng_verify,lat_verify = [1,"合格"],[1,self.set_stm8vs],[1,self.set_dver],[1,"合格"],[1,"合格"]
  608. ws_list,ws_count = [],0
  609. iccid = ""
  610. for i in status_result:
  611. data_strftime = i["upl_time"].strftime("%Y-%m-%d %H:%M:%S")
  612. device_data = i["scd_status"]
  613. device_data = ast.literal_eval(device_data)
  614. if device_data.get("stm8vs","0") != self.set_stm8vs:
  615. stm8vs_verify[0],stm8vs_verify[1] = 0, device_data.get("stm8vs","0")
  616. if device_data.get("iccid",""):
  617. iccid = device_data.get("iccid","")
  618. if device_data.get("dver","0") != self.set_dver:
  619. dver_verify[0],dver_verify[1] = 0, device_data.get("dver","0")
  620. # 开关机状态
  621. open_close_device = {
  622. "open": 0,
  623. "close": 0
  624. }
  625. # 电击次数
  626. dianji = {
  627. "count": 0,
  628. "single_count_gte": False
  629. }
  630. # 充电电压
  631. chongdian_dianya = []
  632. # 电池电压
  633. dianchi_dianya = []
  634. # 雨控保护
  635. yukong_protect = {
  636. "count": 0,
  637. "datetime": []
  638. }
  639. # 光控定时时长
  640. guangkong = []
  641. for index,i in enumerate(data_result):
  642. data_strftime = i["upl_time"].strftime("%Y-%m-%d %H:%M:%S")
  643. device_data = i["scd_data"]
  644. device_data = ast.literal_eval(device_data)
  645. # 设备开关机
  646. open_close = device_data.get("ds","0")
  647. if open_close == "0":
  648. open_close_device["close"] += 1
  649. if open_close == "1":
  650. open_close_device["open"] += 1
  651. # 工作状态
  652. ws = device_data.get("ws","0")
  653. ws_list.append(ws)
  654. if ws == "1":
  655. ws_count += 1
  656. elif ws == "2":
  657. chongdian_dianya.append(device_data.get("cv",0)/1000)
  658. dianchi_dianya.append(float(device_data.get("bv",0)/1000))
  659. # 电击次数
  660. dianji_count = int(device_data.get("ct","0"))
  661. dianji['count'] += dianji_count
  662. # 雨控保护
  663. if device_data.get("rps","0") == "1":
  664. yukong_protect["count"] += 1
  665. yukong_protect["datetime"].append(data_strftime)
  666. # 光控定时时长
  667. if device_data.get("ts","0") == "0":
  668. guangkong.append(int(device_data.get("tt","0")))
  669. # 经纬度
  670. if float(device_data.get("lng","0")) < 113.7536111 and float(device_data.get("lng","0")) > 113.7869444:
  671. lng_verify[0],lng_verify[1] = 0, data_strftime+"超出范围"
  672. if float(device_data.get("lat","0")) < 35.0125 and float(device_data.get("lat","0")) > 35.0458333:
  673. lat_verify[0],lat_verify[1] = 0, data_strftime+"超出范围"
  674. prosee = proess + ((index+1)/len(data_result)*(1/len(self.device_list))*100)
  675. if int(prosee) == 100:
  676. self.proess_signal.emit(99)
  677. else:
  678. self.proess_signal.emit(int(prosee))
  679. # 开关机状态 确认 设备开关均为开机
  680. if open_close_device["open"] != 0 and open_close_device["close"] == 0:
  681. ds_verify = [1, f'{str(open_close_device["open"])}条数据均为开机']
  682. else:
  683. ds_verify = [0, f'{str(open_close_device["open"])}条数据为开机, {str(open_close_device["close"])}条数据为关机']
  684. # 电击次数
  685. if not dianji["single_count_gte"]:
  686. ct_verify = [1, f'击杀总数:{str(dianji["count"])},且单条数据均没有超1000']
  687. else:
  688. ct_verify = [0, f'击杀总数:{str(dianji["count"])},均在单条数据超1000情况']
  689. # 充电电压
  690. if chongdian_dianya:
  691. chong_max = max(chongdian_dianya)
  692. chong_min = max(chongdian_dianya)
  693. if chong_max < 23 and chong_min > 7:
  694. cv_verify = [1, f"最小电压值:{str(chong_min)} 最大电压值:{str(chong_max)}"]
  695. else:
  696. cv_verify = [0, f"最小电压值:{str(chong_min)} 最大电压值:{str(chong_max)}"]
  697. else:
  698. cv_verify = [0, "不存在充电状态"]
  699. # 电池电压
  700. if dianchi_dianya:
  701. dian_max = max(dianchi_dianya)
  702. dian_min = min(dianchi_dianya)
  703. if dian_max < 15 and dian_min > 12:
  704. bv_verify = [1, f"最小电压值:{str(dian_min)} 最大电压值:{str(dian_max)}"]
  705. else:
  706. bv_verify = [0, f"最小电压值:{str(dian_min)} 最大电压值:{str(dian_max)}"]
  707. else:
  708. bv_verify = [0, "电池电压异常"]
  709. # 雨控保护
  710. if yukong_protect["count"] > 0:
  711. rps_verify = [1, f'上报{str(yukong_protect["count"])}']
  712. # 光控定时时长
  713. guangkong_count = list(set(guangkong))
  714. if len(guangkong_count) == 1 and 4 in guangkong_count:
  715. tt_verify = [1, '光控定时时长为4小时']
  716. else:
  717. tt_verify = [0, '光控定时时长异常']
  718. # 工作状态
  719. if "0" in ws_list:
  720. if "1" in ws_list:
  721. if "2" in ws_list:
  722. stamp_diff = self.end_time - self.start_time
  723. day_diff = round(stamp_diff / (12*60*60))
  724. if day_diff <= 1:
  725. low_limit, high_limit = 20, 30
  726. else:
  727. low_limit, high_limit = 20*day_diff, 30*day_diff
  728. if ws_count>low_limit and ws_count<high_limit:
  729. ws_verify=[1,"理论数据量区间({},{}),实际工作状态数据量为{}".format(low_limit,high_limit,ws_count)]
  730. else:
  731. ws_verify=[0,"理论数据量区间({},{}),实际工作状态数据量为{}".format(low_limit,high_limit,ws_count)]
  732. else:
  733. ws_verify=[0,"缺少充电状态"]
  734. else:
  735. ws_verify=[0,"缺少工作状态"]
  736. else:
  737. ws_verify=[0,"缺少待机状态"]
  738. if iccid:
  739. sim_verify = self.sim_info(iccid)
  740. else:
  741. sim_verify = [0,"数据内无iccid"]
  742. return [
  743. ds_verify, # 开关机状态
  744. ws_verify, # 工作状态
  745. ct_verify, # 电击次数
  746. cv_verify, # 充电电压
  747. bv_verify, # 电池电压
  748. rps_verify, # 雨控保护
  749. tt_verify, # 光控定时时长
  750. stm8vs_verify, # 主板代码版本号
  751. sim_verify,
  752. dver_verify,
  753. lng_verify,
  754. lat_verify
  755. ]
  756. def run(self):
  757. """主业务逻辑,涉及进度条不能模块化,慢慢捋"""
  758. proess = 0
  759. now_time = datetime.datetime.now()
  760. global save_filename
  761. save_filename = self.set_order + "_" + now_time.strftime("%m%d") + "杀虫灯检验.xlsx"
  762. save_path = os.path.join(self.save_path,save_filename)
  763. workbook = Workbook(save_path)
  764. worksheet = workbook.add_worksheet()
  765. worksheet.set_row(0, 50)
  766. worksheet.set_row(1, 37.5)
  767. worksheet.set_row(2, 30)
  768. worksheet.set_row(3, 100)
  769. for i in range(len(self.device_list)):
  770. worksheet.set_row(i+4, 30)
  771. worksheet.set_column(0, 16, 24)
  772. toji_style = workbook.add_format(toji_format)
  773. title_style = workbook.add_format(title_format)
  774. explain_style = workbook.add_format(explain_formal)
  775. formal_style = workbook.add_format(formal_format)
  776. error_style = workbook.add_format(error_format)
  777. common_style = workbook.add_format(common_format)
  778. merge_title_style = workbook.add_format(merge_title_format)
  779. worksheet.merge_range('A1:Q1',"物联网杀虫灯在线检验原始表格",merge_title_style)
  780. title_data = [
  781. "文档ID","完整设备ID","开关机状态","工作状态","电击次数","充电电压","电池电压","雨控保护","光控定时时长",
  782. "主板版本号","物联网卡有效期","联网模块版本号","经度坐标","纬度坐标","数据来源","单机判定","批判定"]
  783. worksheet.write_row(row = 2 ,col = 0, data = title_data,cell_format=title_style)
  784. explain_data = [
  785. "/",
  786. "/",
  787. "合格条件(绿色):\n查询时间内,设备开关均为开机",
  788. "合格条件(绿色):\n1.查询时间内,存在待机、充电、工作三个类型的工作状态;\n2.单周期内工作状态的数据量大于(20,30)区间内",
  789. "合格条件(绿色):\n查询时间内,存在击杀数据且单次上报击虫数小于1000",
  790. "合格条件(绿色):\n1.存在充电状态;\n2.充电状态下电压值在7-23v之间",
  791. "合格条件(绿色):\n查询时间内上报数据电池电压不能等于12v,也不能大于15v",
  792. "合格条件(绿色):\n查询时间内存在雨控即雨控上报数据量大于0",
  793. "合格条件(绿色):\n1.必须是光控模式\n2.工作时长配置为4小时",
  794. "合格条件(绿色):\n数据上报主板版本号和输入主板版本号一致",
  795. "合格条件(绿色):剩余有效期大于等于181天\n可接受(黄色):大于等于30天,小于181天\n不合格(红色):小于30天或查询异常。",
  796. "合格条件(绿色):\n数据上报联网模块版本号和输入联网模块版本号一致",
  797. "合格条件(绿色):\n113°46′13″±60″范围内,转为十进度为:(113.7536111,113.7869444)区间内",
  798. "合格条件(绿色):\n35°1′45″±60″范围内,转为十进度为:(35.0125,35.0458333)区间内",
  799. "合格条件(绿色):\n输入校验平台和设备所在平台一致",
  800. "合格条件(绿色):\n所有单项检测合格即为单机判定合格",
  801. "合格条件(绿色):\n1.总量大于5台,单机合格量需>=5,不合格允许CF两列出现异常;\n2.若不超5台要求单机判定全部合格。"
  802. ]
  803. worksheet.write_row(row = 3 ,col = 0, data = explain_data,cell_format=explain_style)
  804. formal_counts = 0
  805. verify_list = []
  806. for index,shortId in enumerate(self.device_list):
  807. if isinstance(shortId,int) or isinstance(shortId, float):
  808. shortId = str(int(shortId))
  809. else:
  810. shortId = shortId.strip()
  811. d_id,deviceId,platform = self.device_their_platform(shortId)
  812. worksheet.write(index+4,0,shortId,formal_style)
  813. if platform == "大数据平台":
  814. try:
  815. worksheet.write(index+4,1,deviceId,formal_style)
  816. if platform==self.set_plat:
  817. worksheet.write(index+4,14,platform,formal_style)
  818. else:
  819. worksheet.write(index+4,14,platform,error_style)
  820. self.mongo_ping()
  821. data_cursor = self.scd_collection.find({"device_id":d_id,'addtime': {"$gte":self.start_time ,"$lte":self.end_time}})
  822. data_counts = data_cursor.count()
  823. if data_counts == 0:
  824. for i in range(2,14):
  825. worksheet.write(index+4,i,"搜索时间内无数据",error_style)
  826. worksheet.write(index+4,15,"不合格",error_style)
  827. danji_verify = []
  828. for i in range(12):
  829. danji_verify.append(0)
  830. verify_list.append(danji_verify)
  831. else:
  832. verify_data = self.__bigdata_verify(data_cursor,proess)
  833. danji_verify = []
  834. for clo_index, verify_ in enumerate(verify_data):
  835. danji_verify.append(verify_[0])
  836. if verify_[0] == 0:
  837. worksheet.write(index+4,clo_index+2,verify_[1],error_style)
  838. elif verify_[0] == 1:
  839. worksheet.write(index+4,clo_index+2,verify_[1],formal_style)
  840. else:
  841. worksheet.write(index+4,clo_index+2,verify_[1],common_style)
  842. if 0 in danji_verify:
  843. worksheet.write(index+4,15,"不合格",error_style)
  844. else:
  845. formal_counts += 1
  846. worksheet.write(index+4,15,"合格",formal_style)
  847. verify_list.append(danji_verify)
  848. except Exception as e:
  849. print(e)
  850. elif platform == "四情平台":
  851. worksheet.write(index+4,1,deviceId,formal_style)
  852. if platform==self.set_plat:
  853. worksheet.write(index+4,14,platform,formal_style)
  854. else:
  855. worksheet.write(index+4,14,platform,error_style)
  856. self.sql_ping()
  857. data_sql = "SELECT * FROM AppInfoManage_scddata WHERE equip_id_id='{}' AND upl_time BETWEEN '{}' AND '{}';".format(deviceId,self.start_time_str,self.end_time_str)
  858. self.cursor.execute(data_sql)
  859. data_result = self.cursor.fetchall()
  860. status_sql = "SELECT * FROM AppInfoManage_scdstatus_all WHERE equip_id_id='{}' AND upl_time BETWEEN '{}' AND '{}';".format(deviceId,self.start_time_str,self.end_time_str)
  861. self.cursor.execute(status_sql)
  862. status_result = self.cursor.fetchall()
  863. if len(data_result) == 0 or len(status_result) == 0:
  864. for i in range(2,14):
  865. worksheet.write(index+4,i,"搜索时间内无数据",error_style)
  866. worksheet.write(index+4,15,"不合格",error_style)
  867. danji_verify = []
  868. for i in range(12):
  869. danji_verify.append(0)
  870. verify_list.append(danji_verify)
  871. else:
  872. verify_data = self.__siqing_verify(data_result,status_result,proess)
  873. danji_verify = []
  874. for clo_index, verify_ in enumerate(verify_data):
  875. danji_verify.append(verify_[0])
  876. if verify_[0] == 0:
  877. worksheet.write(index+4,clo_index+2,verify_[1],error_style)
  878. elif verify_[0] == 1:
  879. worksheet.write(index+4,clo_index+2,verify_[1],formal_style)
  880. else:
  881. worksheet.write(index+4,clo_index+2,verify_[1],common_style)
  882. if 0 in danji_verify:
  883. worksheet.write(index+4,15,"不合格",error_style)
  884. else:
  885. formal_counts += 1
  886. worksheet.write(index+4,15,"合格",formal_style)
  887. verify_list.append(danji_verify)
  888. else:
  889. danji_verify = []
  890. for i in range(12):
  891. danji_verify.append(0)
  892. verify_list.append(danji_verify)
  893. worksheet.write(index+4,1,deviceId,error_style)
  894. worksheet.write(index+4,14,platform,error_style)
  895. proess = (index+1)/len(self.device_list) * 100
  896. if int(proess) == 100:
  897. self.proess_signal.emit(99)
  898. else:
  899. self.proess_signal.emit(int(proess))
  900. toji_data = [
  901. "任务单号",self.set_order,"检验时间",'{}\n{}'.format(self.start_time_str,self.end_time_str),
  902. "检验数量",len(self.device_list),"合格数",formal_counts,"检验平台",self.set_plat,
  903. "主板版本",self.set_stm8vs,"联网版本",self.set_dver,"报告日期",now_time.strftime("%y-%m-%d %H:%M:%S"),""
  904. ]
  905. worksheet.write_row(row = 1 ,col = 0, data = toji_data,cell_format=toji_style)
  906. # 批判定
  907. if len(self.device_list) > 5:
  908. batch_verify = [1,"设备量超5台,单机合格数量存在5台及以上,排除CF两列后其他列均合格"]
  909. if formal_counts >= 5:
  910. for danji_data in verify_list:
  911. for index,element_data in enumerate(danji_data):
  912. if index == 1 or index == 3:
  913. pass
  914. else:
  915. if element_data == 0:
  916. batch_verify = [0,"设备量超5台,单机合格数量存在5台及以上,排除CF两列后其他列出现异常"]
  917. else:
  918. batch_verify = [0,"设备量超5台,单机合格数量不足5台"]
  919. else:
  920. if formal_counts == len(self.device_list):
  921. batch_verify = [1,"设备量不超5台,单机判定全部合格"]
  922. else:
  923. batch_verify = [0,"设备量不超5台,单机判定存在不合格"]
  924. worksheet.merge_range(f"Q5:Q{str(len(self.device_list) + 4)}",batch_verify[1],formal_style if batch_verify[0]==1 else error_style)
  925. worksheet.protect(pwd_str)
  926. workbook.close()
  927. self.cursor.close()
  928. self.connection.close()
  929. self.myclient.close()
  930. self.proess_signal.emit(100)
  931. if __name__== "__main__":
  932. QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
  933. QtGui.QGuiApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
  934. app = QtWidgets.QApplication(sys.argv)
  935. MainWindow = QtWidgets.QMainWindow()
  936. ui = Ui_MainWindow()
  937. ui.setupUi(MainWindow)
  938. MainWindow.show()
  939. sys.exit(app.exec_())