SHBuffMain.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. import sys
  2. from stringprep import in_table_c11
  3. from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QTabWidget, \
  4. QLabel, QLineEdit, QTextEdit, QFormLayout, QMessageBox, QTreeWidget, QTreeWidgetItem, QDialog, \
  5. QVBoxLayout as QDialogVBoxLayout, QLineEdit as QDialogLineEdit, QDialogButtonBox, QCheckBox, QComboBox
  6. from PyQt6.QtCore import Qt
  7. import requests as req
  8. import time, random, numpy as np
  9. import threading
  10. import asyncio
  11. import json
  12. from PyQt6.QtWidgets import QFileDialog
  13. from PyQt6.QtCore import pyqtSignal, QObject, pyqtSlot
  14. import sqlite3
  15. import time
  16. from datetime import datetime
  17. class MainWindow(QMainWindow):
  18. def __init__(self):
  19. super().__init__()
  20. # todo 为了测试 page_size = 1
  21. self.getToBuyUrl = 'https://buff.163.com/api/market/goods/sell_order?game=csgo&allow_epay=1&allow_tradable_cooldown=1&page_num=1&page_size=1&sort_by=price.asc&goods_id='
  22. self.buyGoodsUrl = 'https://buff.163.com/api/market/goods/buy'
  23. # self.getToBuyUrl = 'https://buff.163.com/api/market/goods/sell_order?game=csgo&allow_epay=1&allow_tradable_cooldown=1&page_num=1&page_size=95&sort_by=price.asc&goods_id='
  24. self.fbjUrl= 'https://buff.163.com/api/market/bill_order/ask_seller_to_send_offer'
  25. self.my_headers = {
  26. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
  27. "Host": "buff.163.com",
  28. "Referer": "https://buff.163.com/market/?game=csgo",
  29. "X-Requested-With": "XMLHttpRequest"
  30. }
  31. # 设置窗口大小
  32. self.resize(1500, 800)
  33. # 创建主布局
  34. main_layout = QVBoxLayout()
  35. # 创建按钮
  36. self.scan_button = QPushButton("扫货")
  37. self.scan_button.clicked.connect(self.scan_items)
  38. self.stop_scan_button = QPushButton("停止扫货")
  39. self.stop_scan_button.clicked.connect(self.stop_scan_items)
  40. # 设置按钮大小
  41. self.scan_button.setFixedSize(100, 100)
  42. self.stop_scan_button.setFixedSize(100, 100)
  43. # 将按钮添加到布局中
  44. button_layout = QHBoxLayout()
  45. button_layout.addWidget(self.scan_button)
  46. button_layout.addWidget(self.stop_scan_button)
  47. main_layout.addLayout(button_layout)
  48. # 创建标签页
  49. self.tab_widget = QTabWidget()
  50. self.tab1 = QWidget()
  51. self.tab2 = QWidget()
  52. self.tab3 = QWidget()
  53. self.tab4 = QWidget()
  54. # 修改第一个标签页的标题和内容
  55. self.tab_widget.addTab(self.tab1, "BUFF选品日志")
  56. self.setup_tab1()
  57. # 修改第二个标签页的标题和内容
  58. self.tab_widget.addTab(self.tab2, "扫货账号信息")
  59. self.setup_tab2()
  60. self.tab_widget.addTab(self.tab3, "扫货配置信息")
  61. self.setup_tab3()
  62. self.tab_widget.addTab(self.tab4, "Tab 4")
  63. # 将标签页添加到主布局中
  64. main_layout.addWidget(self.tab_widget)
  65. # 设置主窗口的中心部件
  66. container = QWidget()
  67. container.setLayout(main_layout)
  68. self.setCentralWidget(container)
  69. def stop_scan_items(self):
  70. # 在这里添加停止扫货的逻辑
  71. # 设置扫货停止标志为True
  72. self.stop_selecting_flag = True
  73. QMessageBox.information(self, "停止扫货", "扫货操作已终止")
  74. def scan_items(self):
  75. self.stop_selecting_flag = False
  76. # 必填条件,没有则跳出
  77. self.phone_number = self.phone_edit.text()
  78. QMessageBox.information(self, "扫货手机号码", f"扫货手机号码: {self.phone_number}")
  79. # 判断phone_number是否为空,为空则跳出方法
  80. if not self.phone_number:
  81. QMessageBox.information(self, "扫货手机号码", "扫货手机号码不能为空")
  82. return
  83. # 判断扫货cookie是否为空,为空则退出方法
  84. self.cookie_text = self.cookie_edit.toPlainText()
  85. QMessageBox.information(self, "扫货Cookie", f"扫货Cookie: {self.cookie_text}")
  86. if not self.cookie_text:
  87. QMessageBox.information(self, "扫货Cookie", "扫货Cookie不能为空")
  88. return
  89. try:
  90. thread_BUFFSH = threading.Thread(target=self.BUFFSH)
  91. thread_BUFFSH.start()
  92. except Exception as e:
  93. print(f"Error: {e}")
  94. def BUFFSH(self):
  95. print(f'开始扫货')
  96. # 遍历树形多选框中的所有项
  97. for i1 in range(self.tree_widget.topLevelItemCount()):
  98. item = self.tree_widget.topLevelItem(i1)
  99. if self.stop_selecting_flag:
  100. print(f'人工停止扫货')
  101. break
  102. goods_id = item.text(1)
  103. goods_min_wear = item.text(3)
  104. goods_max_wear = item.text(4)
  105. goods_buy_price = item.text(6)
  106. # 请求BUFF 商品信息列表,获取可以购买的商品
  107. goods_items_list = self.getGoodsInfo(goods_id, goods_min_wear, goods_max_wear, goods_buy_price)
  108. for goods_item in goods_items_list:
  109. if self.stop_selecting_flag:
  110. print(f'人工停止扫货')
  111. break
  112. # post 请求 购买接口
  113. try:
  114. print(f"商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']}")
  115. # 获取当前时间戳
  116. start_time = time.time()
  117. api_data ={
  118. "game": "csgo",
  119. "goods_id": goods_item['goods_id'],
  120. "sell_order_id": goods_item['id'],
  121. "price": goods_item['price'],
  122. "pay_method": 1,
  123. "allow_tradable_cooldown": 0,
  124. "token": "",
  125. "cdkey_id": "",
  126. "hide_non_epay": False
  127. }
  128. api_header = {
  129. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
  130. "Host": "buff.163.com", "X-Requested-With": "XMLHttpRequest",
  131. 'Referer': f"https://buff.163.com/goods/{goods_item['goods_id']}?from=market",
  132. 'Cookie': self.cookie_text,
  133. 'x-csrftoken': "ImM2NTBjYmZhNjk2MGRjOWVkMTQxYjM5MTBjY2RhZjJjODRkNTBlMjUi.Z7WAmQ.yZ6n3Hcjv6eXHEElO1ZA95aqSEA"}
  134. # todo
  135. print(f'api_header: {api_header}')
  136. res = req.post(self.buyGoodsUrl, headers=api_header, data=api_data)
  137. print(f'post 请求 {self.buyGoodsUrl} 返回报文: {res.text.strip()}')
  138. if res.json()['code'] == 'OK':
  139. print(f'购买成功,暂停{float(self.pause_time_edit.text())}秒发报价')
  140. time.sleep(float(self.pause_time_edit.text()))
  141. print(f'post 请求 {self.buyGoodsUrl} 返回报文code等于OK,商品id:{goods_id}的磨损区间{goods_min_wear}-{goods_max_wear}的商品信息:{goods_item}')
  142. try:
  143. bill_order_id = res.json()['data']['id']
  144. print(f'开始发报价 bill_order_id:{bill_order_id}')
  145. fbj_api_data=json.dumps({
  146. "bill_orders": [
  147. bill_order_id
  148. ],
  149. "game": "csgo"
  150. })
  151. print(f'fbj_api_data: { fbj_api_data }')
  152. fbj_api_header = {
  153. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
  154. "Host": "buff.163.com", "X-Requested-With": "XMLHttpRequest",
  155. 'Referer': f"https://buff.163.com/market/buy_order/history?game=csgo",
  156. 'Cookie': self.cookie_text,
  157. "Content-Type":"application/json",
  158. 'x-csrftoken': "ImM2NTBjYmZhNjk2MGRjOWVkMTQxYjM5MTBjY2RhZjJjODRkNTBlMjUi.Z7WAmQ.yZ6n3Hcjv6eXHEElO1ZA95aqSEA"
  159. }
  160. # todo
  161. #fbj_res = req.post(self.fbjUrl, headers=fbj_api_header, data=fbj_api_data)
  162. #print(f'post 请求 发报价 返回报文: {fbj_res.text.strip()}')
  163. #if fbj_res.json()['code'] == 'OK':
  164. # print(f'报价成功')
  165. #else:
  166. # print(f'报价失败')
  167. except Exception as e:
  168. print(f'商品发报价信息接口请求--失败', e)
  169. except Exception as e:
  170. print(f'购买商品信息接口请求--失败', e)
  171. finally:
  172. # 结束时间为当前时间
  173. end_time = time.time()
  174. # 从start_time到end_time 必须修改pause_time秒
  175. if float(end_time - start_time) < float(self.pause_time_edit.text()):
  176. time.sleep(float(self.pause_time_edit.text()) - (end_time - start_time) + random.randint(0, 5))
  177. print(f'停止扫货')
  178. def getGoodsInfo(self, goods_id, goods_min_wear, goods_max_wear, goods_buy_price):
  179. # 获取当前时间戳
  180. timestamp = time.time()
  181. # 将时间戳转换为datetime对象
  182. dt_object = datetime.fromtimestamp(timestamp)
  183. print(f"{dt_object.strftime('%Y-%m-%d %H:%M:%S')}获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息")
  184. # 开始时间为当前时间
  185. goods_id_list = []
  186. start_time = time.time()
  187. self.my_headers.update({
  188. 'Cookie': self.cookie_text
  189. })
  190. try:
  191. # todo 为了测试,先去除磨损区间
  192. # api_url = f'{self.getToBuyUrl}{goods_id}&min_price=0&max_price={goods_buy_price}&min_paintwear={goods_min_wear}&max_paintwear={goods_max_wear}'
  193. api_url = f'{self.getToBuyUrl}{goods_id}&min_price=0&max_price={goods_buy_price}'
  194. # print(f'api_url = {api_url}')
  195. api2_res = req.get(api_url, headers=self.my_headers)
  196. # print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息的返回报文: {api2_res.text.strip()}')
  197. data = api2_res.json()['data']
  198. # 如果data中的code不等于OK,则跳出循环
  199. if api2_res.json()['code'] != 'OK':
  200. print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息请求返回报文: {api2_res.text.strip()}')
  201. print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息接口请求返回报文code不等于OK,跳出循环')
  202. return
  203. goods_id_list = data['items']
  204. print(f"获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息:", len(goods_id_list))
  205. except Exception as e:
  206. print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息接口请求--失败', e)
  207. finally:
  208. # 结束时间为当前时间
  209. end_time = time.time()
  210. # 从start_time到end_time 必须修改pause_time秒
  211. if float(end_time - start_time) < float(self.pause_time_edit.text()):
  212. time.sleep(float(self.pause_time_edit.text()) - (end_time - start_time) + random.randint(0, 5))
  213. return goods_id_list
  214. def setup_tab1(self):
  215. # 创建树形多选框
  216. self.tree_widget = QTreeWidget()
  217. self.tree_widget.setHeaderLabels(
  218. ["商品选择", "商品ID", "商品名称", "商品磨损最低值", "商品磨损最高值", "商品全磨损区间最低价", "商品扫货价",
  219. "商品判断价", "时间"])
  220. self.tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
  221. # 创建操作按钮
  222. self.add_button = QPushButton("新增")
  223. self.edit_button = QPushButton("修改")
  224. self.delete_button = QPushButton("删除")
  225. self.export_button = QPushButton("导出")
  226. self.import_button = QPushButton("导入")
  227. # 将按钮添加到布局中
  228. button_layout = QHBoxLayout()
  229. button_layout.addWidget(self.add_button)
  230. button_layout.addWidget(self.edit_button)
  231. button_layout.addWidget(self.delete_button)
  232. button_layout.addWidget(self.export_button)
  233. button_layout.addWidget(self.import_button)
  234. # 创建保存按钮
  235. self.save_button = QPushButton("保存")
  236. self.save_button.clicked.connect(self.save_items_to_db)
  237. button_layout.addWidget(self.save_button)
  238. # 创建主布局
  239. main_layout = QVBoxLayout()
  240. main_layout.addLayout(button_layout)
  241. main_layout.addWidget(self.tree_widget)
  242. # 设置标签页的布局
  243. self.tab1.setLayout(main_layout)
  244. # 连接按钮信号和槽
  245. self.add_button.clicked.connect(self.add_item)
  246. self.edit_button.clicked.connect(self.edit_item)
  247. self.delete_button.clicked.connect(self.delete_item)
  248. self.export_button.clicked.connect(self.export_items)
  249. self.import_button.clicked.connect(self.import_items)
  250. # 加载数据
  251. self.load_items_from_db()
  252. def load_items_from_db(self):
  253. import sqlite3
  254. # 连接到SQLite数据库
  255. conn = sqlite3.connect('SH1.db')
  256. c = conn.cursor()
  257. # 创建表(如果表不存在)
  258. self.create_items_table(c)
  259. # 查询数据
  260. c.execute("SELECT * FROM items_info")
  261. rows = c.fetchall()
  262. # 将数据添加到树形多选框
  263. for row in rows:
  264. item = QTreeWidgetItem()
  265. item.setText(0, "") # 商品选择
  266. item.setText(1, row[0]) # 商品ID
  267. item.setText(2, row[1]) # 商品名称
  268. item.setText(3, row[2]) # 商品磨损最低值
  269. item.setText(4, row[3]) # 商品磨损最高值
  270. item.setText(5, row[4]) # 商品全磨损区间最低价
  271. item.setText(6, row[5]) # 商品扫货价
  272. item.setText(7, row[6]) # 商品判断价
  273. item.setText(8, row[7]) # 时间
  274. self.tree_widget.addTopLevelItem(item)
  275. # 关闭数据库连接
  276. conn.close()
  277. def setup_tab2(self):
  278. # 创建表单布局
  279. form_layout = QFormLayout()
  280. # 从数据库中获取默认值
  281. conn = sqlite3.connect('SH1.db')
  282. c = conn.cursor()
  283. c.execute('''CREATE TABLE IF NOT EXISTS account_info
  284. (phone TEXT, email TEXT, code TEXT, cookie TEXT)''')
  285. c.execute("SELECT phone, email, code, cookie FROM account_info LIMIT 1")
  286. default_values = c.fetchone()
  287. conn.close()
  288. # 设置默认值
  289. phone_default = default_values[0] if default_values else "17756576757"
  290. email_default = default_values[1] if default_values else "704541015@qq.com"
  291. code_default = default_values[2] if default_values else "0012312"
  292. cookie_default = default_values[3] if default_values else ""
  293. # 添加输入字段
  294. self.phone_edit = QLineEdit(phone_default)
  295. self.email_edit = QLineEdit(email_default)
  296. self.code_edit = QLineEdit(code_default)
  297. self.cookie_edit = QTextEdit(cookie_default)
  298. # 设置输入字段的宽度
  299. self.phone_edit.setFixedWidth(500)
  300. self.email_edit.setFixedWidth(500)
  301. self.code_edit.setFixedWidth(500)
  302. self.cookie_edit.setFixedWidth(500)
  303. form_layout.addRow("扫货手机号码", self.phone_edit)
  304. form_layout.addRow("扫货邮箱号", self.email_edit)
  305. form_layout.addRow("扫货邮箱特殊代码", self.code_edit)
  306. form_layout.addRow("扫货cookie", self.cookie_edit)
  307. # 创建主布局
  308. main_layout = QVBoxLayout()
  309. main_layout.addLayout(form_layout)
  310. # 设置标签页的布局
  311. self.tab2.setLayout(main_layout)
  312. # 连接保存按钮信号和槽
  313. self.save_button = QPushButton("保存")
  314. self.save_button.clicked.connect(self.save_account_info)
  315. self.save_button.setFixedSize(100, 50)
  316. # 创建一个水平布局来放置保存按钮
  317. button_layout = QHBoxLayout()
  318. button_layout.setContentsMargins(300, 0, 0, 0)
  319. button_layout.addWidget(self.save_button, alignment=Qt.AlignmentFlag.AlignLeft)
  320. # 将垂直布局添加到表单布局中
  321. form_layout.addRow(button_layout)
  322. form_layout.setContentsMargins(300, 0, 0, 0)
  323. def save_account_info(self):
  324. import sqlite3
  325. # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
  326. conn = sqlite3.connect('SH1.db')
  327. c = conn.cursor()
  328. # 创建表
  329. c.execute('''CREATE TABLE IF NOT EXISTS account_info
  330. (phone TEXT, email TEXT, code TEXT, cookie TEXT)''')
  331. c.execute('DELETE FROM account_info')
  332. # 插入数据
  333. c.execute("INSERT INTO account_info (phone, email, code, cookie) VALUES (?, ?, ?, ?)",
  334. (self.phone_edit.text(), self.email_edit.text(), self.code_edit.text(),
  335. self.cookie_edit.toPlainText()))
  336. # 提交更改并关闭连接
  337. conn.commit()
  338. conn.close()
  339. QMessageBox.information(self, "成功", "账号信息已保存")
  340. def setup_tab3(self):
  341. # 创建表单布局
  342. form_layout = QFormLayout()
  343. # 添加输入字段
  344. self.pause_time_edit = QLineEdit()
  345. self.pause_time_edit.setFixedWidth(500)
  346. form_layout.addRow("API接口请求暂停时间(秒)", self.pause_time_edit)
  347. # 创建主布局
  348. main_layout = QVBoxLayout()
  349. main_layout.addLayout(form_layout)
  350. # 创建保存按钮
  351. self.save_button = QPushButton("保存")
  352. self.save_button.clicked.connect(self.save_settings)
  353. self.save_button.setFixedSize(100, 50)
  354. # 创建一个水平布局来放置保存按钮
  355. button_layout = QHBoxLayout()
  356. button_layout.setContentsMargins(300, 0, 0, 0)
  357. button_layout.addWidget(self.save_button, alignment=Qt.AlignmentFlag.AlignLeft)
  358. # 将垂直布局添加到表单布局中
  359. form_layout.addRow(button_layout)
  360. form_layout.setContentsMargins(300, 0, 0, 0)
  361. # 添加pause_time_edit到主布局
  362. main_layout.addWidget(self.pause_time_edit)
  363. # 设置标签页的布局
  364. self.tab3.setLayout(main_layout)
  365. # 加载默认值
  366. self.load_pause_time_from_db()
  367. def load_pause_time_from_db(self):
  368. import sqlite3
  369. # 连接到SQLite数据库
  370. conn = sqlite3.connect('SH1.db')
  371. c = conn.cursor()
  372. # 创建表(如果表不存在)
  373. c.execute('''CREATE TABLE IF NOT EXISTS settings
  374. (pause_time REAL)''')
  375. # 查询数据
  376. c.execute("SELECT pause_time FROM settings LIMIT 1")
  377. default_value = c.fetchone()
  378. # 设置默认值
  379. pause_time_default = default_value[0] if default_value else "5"
  380. # 设置输入字段的默认值
  381. self.pause_time_edit.setText(str(pause_time_default))
  382. # 关闭数据库连接
  383. conn.close()
  384. def save_settings(self):
  385. import sqlite3
  386. # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
  387. conn = sqlite3.connect('SH1.db')
  388. c = conn.cursor()
  389. # 创建表
  390. c.execute('''CREATE TABLE IF NOT EXISTS settings
  391. (pause_time REAL)''')
  392. c.execute('DELETE FROM settings')
  393. # 插入数据
  394. c.execute("INSERT INTO settings (pause_time) VALUES (?)",
  395. (float(self.pause_time_edit.text()),))
  396. # 提交更改并关闭连接
  397. conn.commit()
  398. conn.close()
  399. QMessageBox.information(self, "成功", "设置已保存")
  400. def save_items_to_db(self):
  401. import sqlite3
  402. # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
  403. conn = sqlite3.connect('SH1.db')
  404. c = conn.cursor()
  405. # 创建表
  406. self.create_items_table(c)
  407. c.execute('DELETE FROM items_info')
  408. # 插入数据
  409. for i in range(self.tree_widget.topLevelItemCount()):
  410. item = self.tree_widget.topLevelItem(i)
  411. c.execute(
  412. "INSERT INTO items_info (item_id, item_name, min_paintwear, max_paintwear, min_price, buy_price, judge_price, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
  413. (item.text(1), item.text(2), item.text(3), item.text(4), item.text(5), item.text(6), item.text(7),
  414. item.text(8)))
  415. # 提交更改并关闭连接
  416. conn.commit()
  417. conn.close()
  418. QMessageBox.information(self, "成功", "商品信息已保存")
  419. def create_items_table(self, cursor):
  420. cursor.execute('''CREATE TABLE IF NOT EXISTS items_info
  421. (item_id TEXT, item_name TEXT, min_paintwear TEXT, max_paintwear TEXT, min_price TEXT, buy_price TEXT, judge_price TEXT, timestamp TEXT)''')
  422. def add_item(self):
  423. # 创建一个对话框来添加新项目
  424. dialog = QDialog(self)
  425. dialog.setWindowTitle("新增商品")
  426. layout = QDialogVBoxLayout()
  427. # 添加输入字段
  428. fields = ["商品ID", "商品名称", "商品磨损最低值", "商品磨损最高值", "商品全磨损区间最低价", "商品扫货价",
  429. "商品判断价", "时间"]
  430. line_edits = {}
  431. for field in fields:
  432. label = QLabel(field)
  433. line_edit = QDialogLineEdit()
  434. layout.addWidget(label)
  435. layout.addWidget(line_edit)
  436. line_edits[field] = line_edit
  437. # 添加按钮框
  438. button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
  439. button_box.accepted.connect(dialog.accept)
  440. button_box.rejected.connect(dialog.reject)
  441. layout.addWidget(button_box)
  442. dialog.setLayout(layout)
  443. if dialog.exec() == QDialog.DialogCode.Accepted:
  444. item = QTreeWidgetItem()
  445. for field in fields:
  446. # 调整索引值,将商品ID填入到“商品选择”的内容框体中
  447. item.setText(fields.index(field) + 1, line_edits[field].text())
  448. self.tree_widget.addTopLevelItem(item)
  449. def edit_item(self):
  450. # 获取选中的项
  451. selected_items = self.tree_widget.selectedItems()
  452. if not selected_items:
  453. QMessageBox.warning(self, "警告", "请选择要编辑的项目")
  454. return
  455. item = selected_items[0]
  456. dialog = QDialog(self)
  457. dialog.setWindowTitle("编辑商品")
  458. layout = QDialogVBoxLayout()
  459. # 添加输入字段
  460. fields = ["商品ID", "商品名称", "商品磨损最低值", "商品磨损最高值", "商品全磨损区间最低价", "商品扫货价",
  461. "商品判断价", "时间"]
  462. line_edits = {}
  463. for field in fields:
  464. label = QLabel(field)
  465. line_edit = QDialogLineEdit(item.text(fields.index(field) + 1))
  466. layout.addWidget(label)
  467. layout.addWidget(line_edit)
  468. line_edits[field] = line_edit
  469. # 添加按钮框
  470. button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
  471. button_box.accepted.connect(dialog.accept)
  472. button_box.rejected.connect(dialog.reject)
  473. layout.addWidget(button_box)
  474. dialog.setLayout(layout)
  475. if dialog.exec() == QDialog.DialogCode.Accepted:
  476. for field in fields:
  477. item.setText(fields.index(field) + 1, line_edits[field].text())
  478. def delete_item(self):
  479. # 获取选中的项
  480. selected_items = self.tree_widget.selectedItems()
  481. if not selected_items:
  482. QMessageBox.warning(self, "警告", "请选择要删除的项目")
  483. return
  484. for item in selected_items:
  485. # 删除顶级项
  486. (self.tree_widget.indexOfTopLevelItem(item))
  487. self.tree_widget.takeTopLevelItem(self.tree_widget.indexOfTopLevelItem(item))
  488. def export_items(self):
  489. # 导出元素的逻辑
  490. file_path, _ = QFileDialog.getSaveFileName(self, "导出商品数据", "", "JSON Files (*.json);;All Files (*)")
  491. if file_path:
  492. items = {}
  493. for i in range(self.tree_widget.topLevelItemCount()):
  494. item = self.tree_widget.topLevelItem(i)
  495. items[item.text(1)] = {
  496. "price": item.text(6),
  497. "min_paintwear": item.text(3),
  498. "max_paintwear": item.text(4),
  499. "name": item.text(2),
  500. '商品ID': item.text(1),
  501. '商品名称': item.text(2),
  502. '磨损最低值': item.text(3),
  503. '磨损最高值': item.text(4),
  504. '全磨损区间最低价': item.text(5),
  505. '扫货价': item.text(6),
  506. '判断价': item.text(7),
  507. '时间': item.text(8)
  508. }
  509. with open(file_path, 'w', encoding='utf-8') as f:
  510. json.dump(items, f, ensure_ascii=False, indent=4)
  511. QMessageBox.information(self, "成功", "数据已成功导出到 {}".format(file_path))
  512. def import_items(self):
  513. # 导入元素的逻辑
  514. file_path, _ = QFileDialog.getOpenFileName(self, "导入商品数据", "", "JSON Files (*.json);;All Files (*)")
  515. if file_path:
  516. with open(file_path, 'r', encoding='utf-8') as f:
  517. items = json.load(f)
  518. for item_id, item_data in items.items():
  519. item = QTreeWidgetItem()
  520. item.setText(0, "") # 商品选择
  521. item.setText(1, item_data['商品ID'])
  522. item.setText(2, item_data['商品名称'])
  523. item.setText(3, item_data['磨损最低值'])
  524. item.setText(4, item_data['磨损最高值'])
  525. item.setText(5, item_data['全磨损区间最低价'])
  526. item.setText(6, item_data['扫货价'])
  527. item.setText(7, item_data['判断价'])
  528. item.setText(8, item_data['时间'])
  529. self.tree_widget.addTopLevelItem(item)
  530. QMessageBox.information(self, "成功", "数据已成功导入")
  531. if __name__ == "__main__":
  532. app = QApplication(sys.argv)
  533. window = MainWindow()
  534. window.show()
  535. sys.exit(app.exec())