| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406 |
- import sys
- from stringprep import in_table_c11
- from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QTabWidget, \
- QLabel, QLineEdit, QTextEdit, QFormLayout, QMessageBox, QTreeWidget, QTreeWidgetItem, QDialog, \
- QVBoxLayout as QDialogVBoxLayout, QLineEdit as QDialogLineEdit, QDialogButtonBox, QCheckBox, QComboBox
- from PyQt6.QtCore import Qt
- import requests as req
- import time, random, numpy as np
- import threading
- import asyncio
- import json
- from PyQt6.QtWidgets import QFileDialog
- from PyQt6.QtCore import pyqtSignal, QObject, pyqtSlot
- import sqlite3
- from CollectibleDialog import CollectibleDialog
- from AppearanceDialog import AppearanceDialog
- from TypeDialog import TypeDialog
- from QualityDialog import QualityDialog
- from CategoryDialog import CategoryDialog
- from SelectLogDialog import SelectLogDialog
- from InitDB import InitDB
- from BUFFAPI import BUFFAPI
- from BUFFXP import BUFFXP
- from datetime import datetime
- class MainWindow(QMainWindow):
- # 定义一个信号,用于传递日志信息
- log_added = pyqtSignal(str, str, str, str, str, str, str, str)
- def __init__(self):
- super().__init__()
- # 设置一个选品停止的flag
- self.stop_selecting_flag = False
- # 向BUFF选品日志列表中写内容的槽函数
- self.log_added.connect(self._add_select_log) # 连接信号到槽函数
- # 初始化数据库
- InitDB.init_db()
- self.xp_goodsurl = 'https://buff.163.com/api/market/goods'
- self.xp_getPaintwearChoicesUrl = 'https://buff.163.com/api/market/goods/info?goods_id='
- self.xp_getPriceUrl = 'https://buff.163.com/api/market/goods/sell_order?game=csgo&page_num=1&sort_by=price.asc&goods_id='
- self.xp_my_headers = {
- "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",
- "Host": "buff.163.com",
- "Referer": "https://buff.163.com/market/?game=csgo",
- "X-Requested-With": "XMLHttpRequest"
- }
- # todo 为了测试 page_size = 1
- self.sh_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='
- self.sh_buyGoodsUrl = 'https://buff.163.com/api/market/goods/buy'
- # self.sh_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='
- self.sh_fbjUrl= 'https://buff.163.com/api/market/bill_order/ask_seller_to_send_offer'
- self.sh_my_headers = {
- "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",
- "Host": "buff.163.com",
- "Referer": "https://buff.163.com/market/?game=csgo",
- "X-Requested-With": "XMLHttpRequest"
- }
- # 初始化 phone_edit_map
- self.setup_phone_edit_map()
- # 设置窗口标题和大小
- self.setWindowTitle("垂直布局示例")
- self.setGeometry(100, 100, 1500, 800)
- # 创建一个垂直布局
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保垂直布局内容靠左对齐
- # 创建一个水平布局来放置按钮
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保水平布局内容靠左对齐
- # 创建两个按钮
- button1 = QPushButton("选品")
- # 增加停止选品和停止扫货按钮
- stop_select_button = QPushButton("停止选品")
- button_layout.addWidget(button1)
- button_layout.addWidget(stop_select_button)
- # 连接按钮的点击事件
- button1.clicked.connect(self.show_selected_phone_number)
- stop_select_button.clicked.connect(self.stop_selecting) # 新增连接停止选品按钮的点击事件
- button_sh = QPushButton("扫货")
- button_layout.addWidget(button_sh)
- button_sh.clicked.connect(self.beginSH)
- button_stop_sh = QPushButton("停止扫货")
- button_layout.addWidget(button_stop_sh)
- button_stop_sh.clicked.connect(self.stopSH)
- # 将水平布局添加到垂直布局中
- layout.addLayout(button_layout)
- # 创建一个Tab容器
- self.tab_widget = QTabWidget()
- # 向Tab容器中添加10个标签页
- for i in range(1, 11): # 修改循环范围以添加第11个标签页
- tab = QWidget()
- tab_layout = QVBoxLayout()
- # tab_layout.setAlignment(Qt.AlignmentFlag.AlignVCenter) # 确保标签页布局内容靠左对齐
- if i == 1:
- form_layout = self.create_account_info_form("选品")
- tab_layout.addLayout(form_layout)
- elif i == 2:
- tree_layout = self.create_category_info_form()
- tab_layout.addLayout(tree_layout)
- elif i == 3:
- quality_layout = self.create_quality_info_form()
- tab_layout.addLayout(quality_layout)
- elif i == 4:
- type_layout = self.create_type_info_form()
- tab_layout.addLayout(type_layout)
- elif i == 5:
- appearance_layout = self.create_appearance_info_form()
- tab_layout.addLayout(appearance_layout)
- elif i == 6:
- collectible_layout = self.create_collectible_info_form()
- tab_layout.addLayout(collectible_layout)
- elif i == 7:
- config_layout = self.create_config_info_form("选品")
- tab_layout.addLayout(config_layout)
- elif i == 8:
- select_log_layout = self.create_select_log_info_form() # 添加BUFF选品日志标签页
- tab_layout.addLayout(select_log_layout)
- elif i == 9:
- shzhtab_layout = self.setup_shzhtab()
- tab_layout.addLayout(shzhtab_layout)
- elif i == 10:
- shpztab_layout = self.setup_shpztab()
- tab_layout.addLayout(shpztab_layout)
- else:
- label = QLabel(f"这是标签页 {i}")
- tab_layout.addWidget(label)
- tab.setLayout(tab_layout)
- if i == 1:
- self.tab_widget.addTab(tab, "选品账号信息")
- elif i == 2:
- self.tab_widget.addTab(tab, "BUFF品类信息")
- elif i == 3:
- self.tab_widget.addTab(tab, "BUFF品质信息")
- elif i == 4:
- self.tab_widget.addTab(tab, "BUFFTYPE信息")
- elif i == 5:
- self.tab_widget.addTab(tab, "BUFF外观信息")
- elif i == 6:
- self.tab_widget.addTab(tab, "BUFF收藏品信息")
- elif i == 7:
- self.tab_widget.addTab(tab, "BUFF选品配置")
- elif i == 8:
- self.tab_widget.addTab(tab, "BUFF选品日志")
- elif i == 9:
- self.tab_widget.addTab(tab, "扫货账号信息")
- elif i == 10:
- self.tab_widget.addTab(tab, "扫货配置信息")
- # 将Tab容器添加到布局中
- layout.addWidget(self.tab_widget)
- # 创建一个中心部件,并将布局设置为中心部件的布局
- container = QWidget()
- container.setLayout(layout)
- # 将中心部件设置为主窗口的中心部件
- self.setCentralWidget(container)
- # 扫货时候关闭选品 选品时候关闭扫货 todo
- def beginSH(self):
- print('开始扫货')
- self.stop_shopping_flag = False
- # 必填条件,没有则跳出
- self.sh_phone_number = self.sh_phone_edit.text()
- QMessageBox.information(self, "扫货手机号码", f"扫货手机号码: {self.sh_phone_number}")
- # 判断phone_number是否为空,为空则跳出方法
- if not self.sh_phone_number:
- QMessageBox.information(self, "扫货手机号码", "扫货手机号码不能为空")
- return
- # 判断扫货cookie是否为空,为空则退出方法
- self.sh_cookie_text = self.sh_cookie_edit.toPlainText()
- QMessageBox.information(self, "扫货Cookie", f"扫货Cookie: {self.sh_cookie_text}")
- if not self.sh_cookie_text:
- QMessageBox.information(self, "扫货Cookie", "扫货Cookie不能为空")
- return
- # 判断扫货xcsrftoken是否为空,为空则退出方法
- self.sh_xcsrftoken_text = self.sh_xcsrftoken_edit.toPlainText()
- QMessageBox.information(self, "扫货xcsrftoken", f"扫货xcsrftoken: {self.sh_xcsrftoken_text}")
- if not self.sh_xcsrftoken_text:
- QMessageBox.information(self, "扫货xcsrftoken", "扫货xcsrftoken不能为空")
- return
- try:
- # 获取扫货线程self.shpz_thread_count_edit的值
- self.shpz_thread_count = int(self.shpz_thread_count_edit.text())
- if self.shpz_thread_count > 0 :
- j = 0
- while j < self.shpz_thread_count:
- print(f'开启扫货线程 - {j+1}')
- thread_BUFFSH = threading.Thread(target=self.BUFFSH,args=(j+1))
- thread_BUFFSH.start()
- j += 1
- except Exception as e:
- print(f"Error: {e}")
- def BUFFSH(self, thread_num):
- while True:
- print(f'BUFFSH线程 - {thread_num}')
- if self.stop_selecting_flag:
- print(f'人工停止扫货')
- return
- # 获取BUFF选品日志标签页列表中的数据
- sh_start_time = 0
- # 间隔扫货
- for i1 in range(self.select_log_tree_widget.topLevelItemCount()):
- if self.stop_selecting_flag:
- print(f'人工停止扫货')
- return
- #假设为10条数据,三个进程,第1,4,7由第一个进程处理 第2,5,8由第二个进程处理
- if i1 % self.shpz_thread_count == thread_num - 1:
- item = self.select_log_tree_widget.topLevelItem(i1)
- if self.stop_shopping_flag:
- print(f'人工停止扫货')
- return
- goods_id = item.text(1)
- goods_min_wear = item.text(3)
- goods_max_wear = item.text(4)
- goods_buy_price = item.text(6)
- # 请求BUFF 商品信息列表,获取可以购买的商品
- current_time = time.time()
- time_since_last_request = current_time - sh_start_time
- if time_since_last_request < float(self.shpz_pause_time_edit.text()):
- wait_time = float(self.shpz_pause_time_edit.text()) - time_since_last_request
- print(f"暂停 {wait_time:.2f} seconds before making the next request.")
- time.sleep(wait_time)
- goods_items_list = self.getGoodsInfo(goods_id, goods_min_wear, goods_max_wear, goods_buy_price)
- for goods_item in goods_items_list:
- if self.stop_selecting_flag:
- print(f'人工停止扫货')
- return
- # post请求购买接口
- try:
- print(f"商品ID: {goods_item['goods_id']} 订单id: {goods_item['id']} 购买价格: {goods_item['price']}")
- api_data ={
- "game": "csgo",
- "goods_id": goods_item['goods_id'],
- "sell_order_id": goods_item['id'],
- "price": goods_item['price'],
- "pay_method": 1,
- "allow_tradable_cooldown": 0,
- "token": "",
- "cdkey_id": "",
- "hide_non_epay": False
- }
- api_header = {
- "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",
- "Host": "buff.163.com", "X-Requested-With": "XMLHttpRequest",
- 'Referer': f"https://buff.163.com/goods/{goods_item['goods_id']}?from=market",
- 'Cookie': self.sh_cookie_text,
- 'x-csrftoken': self.sh_cookie_text}
- # todo
- print(f'api_header: {api_header}')
- res = req.post(self.sh_buyGoodsUrl, headers=api_header, data=api_data)
- print(f'post 请求 {self.buyGoodsUrl} 返回报文: {res.text.strip()}')
- if res.json()['code'] == 'OK':
- print(f'购买成功')
- except Exception as e:
- print(f'购买商品信息接口请求--失败', e)
- finally:
- sh_start_time = time.time()
- # # 结束时间为当前时间
- # end_time = time.time()
- # # 从start_time到end_time 必须修改pause_time秒
- # if float(end_time - start_time) < float(self.pause_time_edit.text()):
- # time.sleep(float(self.pause_time_edit.text()) - (end_time - start_time) + random.randint(0, 5))
- print(f'停止扫货')
- def getGoodsInfo(self, goods_id, goods_min_wear, goods_max_wear, goods_buy_price):
- # 获取当前时间戳
- timestamp = time.time()
- # 将时间戳转换为datetime对象
- dt_object = datetime.fromtimestamp(timestamp)
- print(f"{dt_object.strftime('%Y-%m-%d %H:%M:%S')}获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息")
- # 开始时间为当前时间
- goods_id_list = []
- start_time = time.time()
- self.sh_my_headers.update({
- 'Cookie': self.sh_cookie_text
- })
- try:
- # todo 为了测试,先去除磨损区间
- # 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}'
- api_url = f'{self.sh_getToBuyUrl}{goods_id}&min_price=0&max_price={goods_buy_price}'
- # print(f'api_url = {api_url}')
- api2_res = req.get(api_url, headers=self.sh_my_headers)
- # print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息的返回报文: {api2_res.text.strip()}')
- data = api2_res.json()['data']
- # 如果data中的code不等于OK,则跳出循环
- if api2_res.json()['code'] != 'OK':
- print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息请求返回报文: {api2_res.text.strip()}')
- print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息接口请求返回报文code不等于OK,跳出循环')
- return
- goods_id_list = data['items']
- print(f"获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息:", len(goods_id_list))
- except Exception as e:
- print(f'获取商品id:{goods_id}的在磨损区间{goods_min_wear}-{goods_max_wear}是否有低于{goods_buy_price}的商品信息接口请求--失败', e)
- finally:
- # # # 结束时间为当前时间
- # end_time = time.time()
- # # 从start_time到end_time 必须修改pause_time秒
- # if float(end_time - start_time) < float(self.pause_time_edit.text()):
- # time.sleep(float(self.pause_time_edit.text()) - (end_time - start_time) )
- return goods_id_list
- def stopSH(self):
- # 在这里添加停止扫货的逻辑
- # 设置扫货停止标志为True
- self.stop_shopping_flag = True
- QMessageBox.information(self, "停止扫货", "扫货操作已终止")
- def setup_shpztab(self):
- # 创建表单布局
- form_layout = QFormLayout()
- # 添加输入字段
- self.shpz_pause_time_edit = QLineEdit()
- self.shpz_pause_time_edit.setFixedWidth(500)
- form_layout.addRow("API接口请求暂停时间(秒)", self.shpz_pause_time_edit)
- # 添加扫货线程数输入字段
- self.shpz_thread_count_edit = QLineEdit()
- self.shpz_thread_count_edit.setFixedWidth(500)
- form_layout.addRow("扫货线程数", self.shpz_thread_count_edit)
- # 创建主布局
- main_layout = QVBoxLayout()
- main_layout.addLayout(form_layout)
- # 创建保存按钮
- self.shpz_save_button = QPushButton("保存")
- self.shpz_save_button.clicked.connect(self.shpz_save_settings)
- self.shpz_save_button.setFixedSize(100, 50)
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(300, 0, 0, 0)
- button_layout.addWidget(self.shpz_save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(300, 0, 0, 0)
- # 添加pause_time_edit到主布局
- main_layout.addWidget(self.shpz_pause_time_edit)
- main_layout.addWidget(self.shpz_thread_count_edit)
- # 加载默认值
- self.load_shpz_settings_from_db()
- return main_layout
- def shpz_save_settings(self):
- import sqlite3
- # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute('DELETE FROM shpz_settings')
- # 插入数据
- c.execute("INSERT INTO shpz_settings (pause_time, thread_count) VALUES (?, ?)",
- (float(self.shpz_pause_time_edit.text()), int(self.shpz_thread_count_edit.text())))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- QMessageBox.information(self, "成功", "设置已保存")
- def load_shpz_settings_from_db(self):
- import sqlite3
- # 连接到SQLite数据库
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- # 查询数据
- c.execute("SELECT pause_time, thread_count FROM shpz_settings LIMIT 1")
- default_value = c.fetchone()
- # 设置默认值
- pause_time_default = default_value[0] if default_value else "5"
- thread_count_default = default_value[1] if default_value else "1" # 默认扫货线程数为1
- # 设置输入字段的默认值
- self.shpz_pause_time_edit.setText(str(pause_time_default))
- self.shpz_thread_count_edit.setText(str(thread_count_default))
- # 关闭数据库连接
- conn.close()
- def setup_shzhtab(self):
- # 创建表单布局
- form_layout = QFormLayout()
- # 从数据库中获取默认值
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT phone, email, code, cookie,xcsrftoken FROM sh_account_info LIMIT 1")
- default_values = c.fetchone()
- conn.close()
- # 设置默认值
- phone_default = default_values[0] if default_values else "17756576757"
- email_default = default_values[1] if default_values else "704541015@qq.com"
- code_default = default_values[2] if default_values else "0012312"
- cookie_default = default_values[3] if default_values else ""
- xcsrftoken_default = default_values[3] if default_values else ""
- # 添加输入字段
- self.sh_phone_edit = QLineEdit(phone_default)
- self.sh_email_edit = QLineEdit(email_default)
- self.sh_code_edit = QLineEdit(code_default)
- self.sh_cookie_edit = QTextEdit(cookie_default)
- self.sh_xcsrftoken_edit = QTextEdit(xcsrftoken_default)
- # 设置输入字段的宽度
- self.sh_phone_edit.setFixedWidth(500)
- self.sh_email_edit.setFixedWidth(500)
- self.sh_code_edit.setFixedWidth(500)
- self.sh_cookie_edit.setFixedWidth(500)
- self.sh_xcsrftoken_edit.setFixedWidth(500)
- form_layout.addRow("扫货手机号码", self.sh_phone_edit)
- form_layout.addRow("扫货邮箱号", self.sh_email_edit)
- form_layout.addRow("扫货邮箱特殊代码", self.sh_code_edit)
- form_layout.addRow("扫货cookie", self.sh_cookie_edit)
- form_layout.addRow("扫货xcsrftoken", self.sh_xcsrftoken_edit)
- # 创建主布局
- main_layout = QVBoxLayout()
- main_layout.addLayout(form_layout)
- # 连接保存按钮信号和槽
- self.sh_save_button = QPushButton("保存")
- self.sh_save_button.clicked.connect(self.save_sh_account_info)
- self.sh_save_button.setFixedSize(100, 50)
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(300, 0, 0, 0)
- button_layout.addWidget(self.sh_save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(300, 0, 0, 0)
- return main_layout
- def save_sh_account_info(self):
- import sqlite3
- # 连接到SQLite数据库(如果数据库不存在,则会自动创建)
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute('DELETE FROM sh_account_info')
- # 插入数据
- c.execute("INSERT INTO sh_account_info (phone, email, code, cookie,xcsrftoken) VALUES (?, ?, ?, ?,?)",
- (self.sh_phone_edit.text(), self.sh_email_edit.text(), self.sh_code_edit.text(),
- self.sh_cookie_edit.toPlainText(), self.sh_xcsrftoken_edit.toPlainText()))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- QMessageBox.information(self, "成功", "扫货账号信息已保存")
- def create_account_info_form(self, prefix):
- form_layout = QFormLayout()
- # 从sqlite中accounts获取信息,降数据库中得到值填到输入框中
- # 从数据库中获取默认值
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT phone_number, email, email_alias, cookie FROM accounts LIMIT 1")
- default_values = c.fetchone()
- conn.close()
- # 设置默认值
- phone_default = default_values[0] if default_values else "17756576757"
- email_default = default_values[1] if default_values else "704541015@qq.com"
- code_default = default_values[2] if default_values else "0012312"
- cookie_default = default_values[3] if default_values else ""
- # 创建输入框及其标签
- phone_label = QLabel(f"{prefix}手机号码")
- phone_edit = QLineEdit()
- phone_edit.setFixedWidth(500) # 设置固定宽度为500像素
- phone_edit.setText(phone_default) # 设置选品手机号码默认值
- form_layout.addRow(phone_label, phone_edit)
- email_label = QLabel(f"{prefix}邮箱号")
- email_edit = QLineEdit()
- email_edit.setFixedWidth(500) # 设置固定宽度为500像素
- email_edit.setText(email_default) # 设置选品邮箱号默认值
- form_layout.addRow(email_label, email_edit)
- email_alias_label = QLabel(f"{prefix}邮箱特殊代码")
- email_alias_edit = QLineEdit()
- email_alias_edit.setFixedWidth(500) # 设置固定宽度为500像素
- email_alias_edit.setText(code_default) # 设置选品邮箱特殊代码默认值
- form_layout.addRow(email_alias_label, email_alias_edit)
- cookie_label = QLabel(f"{prefix}cookie")
- cookie_edit = QTextEdit() # 使用QTextEdit代替QLineEdit
- cookie_edit.setFixedWidth(500) # 设置固定宽度为500像素
- cookie_edit.setText(cookie_default) # 设置选品cookie默认值
- form_layout.addRow(cookie_label, cookie_edit)
- # 保存输入框的引用以便后续访问
- self.phone_edit_map[prefix] = phone_edit
- self.email_edit_map[prefix] = email_edit
- self.email_alias_edit_map[prefix] = email_alias_edit
- # 添加保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_account_info)
- save_button.setFixedSize(100, 50) # 设置固定宽度为500像素
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(300, 0, 0, 0)
- button_layout.addWidget(save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(300, 0, 0, 0)
- return form_layout
- def save_account_info(self):
- phone_number = self.phone_edit_map["选品"].text()
- # 获取选品邮箱号
- email = self.email_edit_map["选品"].text()
- email_alias = self.email_alias_edit_map["选品"].text()
- cookie = self.phone_edit_map["选品"].parent().findChild(QTextEdit).toPlainText()
- if not phone_number or not email or not email_alias or not cookie:
- QMessageBox.warning(self, "保存账号信息", "所有字段都必须填写")
- return
- try:
- conn = sqlite3.connect('buff.db')
- cursor = conn.cursor()
- cursor.execute('delete from accounts ')
- cursor.execute('''
- INSERT INTO accounts (phone_number, email, email_alias, cookie)
- VALUES (?, ?, ?, ?)
- ''', (phone_number, email, email_alias, cookie))
- conn.commit()
- conn.close()
- QMessageBox.information(self, "保存账号信息", "账号信息已成功保存")
- except Exception as e:
- QMessageBox.critical(self, "保存账号信息", f"保存账号信息时发生错误: {e}")
- def create_category_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.tree_widget = QTreeWidget()
- self.tree_widget.setHeaderLabels(["选择", "品类名称", "品类编码"])
- self.tree_widget.setColumnCount(3)
- self.tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.tree_widget.setColumnWidth(1, 300) # 设置品类名称列的宽度
- self.tree_widget.setColumnWidth(2, 150) # 设置品类编码列的宽度
- self.tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "品类名称", "品类编码"])) # 设置表头
- self.tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的品类信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM categories ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.tree_widget)
- item.setText(1, row[0])
- item.setText(2, row[1])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_category)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_category)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_category)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_categories)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- def add_category(self):
- CategoryDialog.add_category(self)
- def delete_category(self):
- CategoryDialog.delete_category(self)
- def edit_category(self):
- CategoryDialog.edit_category(self)
- def save_categories(self):
- CategoryDialog.save_categories(self)
- def create_quality_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.quality_tree_widget = QTreeWidget()
- self.quality_tree_widget.setHeaderLabels(["选择", "品质编码", "品质名称"])
- self.quality_tree_widget.setColumnCount(3)
- self.quality_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.quality_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.quality_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.quality_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.quality_tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.quality_tree_widget.setColumnWidth(1, 150) # 设置品质编码列的宽度
- self.quality_tree_widget.setColumnWidth(2, 300) # 设置品质名称列的宽度
- self.quality_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "品质编码", "品质名称"])) # 设置表头
- self.quality_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的品质信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM qualities ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.quality_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.quality_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.quality_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_quality)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_quality)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_quality)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_qualities)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- def add_quality(self):
- QualityDialog.add_quality(self)
- def delete_quality(self):
- QualityDialog.delete_quality(self)
- def edit_quality(self):
- QualityDialog.edit_quality(self)
- def save_qualities(self):
- QualityDialog.save_qualities(self)
- def create_type_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.type_tree_widget = QTreeWidget()
- self.type_tree_widget.setHeaderLabels(["选择", "type编码", "type名称"])
- self.type_tree_widget.setColumnCount(3)
- self.type_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.type_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.type_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.type_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.type_tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.type_tree_widget.setColumnWidth(1, 150) # 设置type编码列的宽度
- self.type_tree_widget.setColumnWidth(2, 300) # 设置type名称列的宽度
- self.type_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "type编码", "type名称"])) # 设置表头
- self.type_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的type信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM types ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.type_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.type_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.type_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_type)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_type)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_type)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_types)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- def add_type(self):
- TypeDialog.add_type(self)
- def delete_type(self):
- TypeDialog.delete_type(self)
- def edit_type(self):
- TypeDialog.edit_type(self)
- def save_types(self):
- TypeDialog.save_types(self)
- def create_appearance_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.appearance_tree_widget = QTreeWidget()
- self.appearance_tree_widget.setHeaderLabels(["选择", "外观编码", "外观名称"])
- self.appearance_tree_widget.setColumnCount(3)
- self.appearance_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.appearance_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.appearance_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.appearance_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.appearance_tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.appearance_tree_widget.setColumnWidth(1, 150) # 设置外观编码列的宽度
- self.appearance_tree_widget.setColumnWidth(2, 300) # 设置外观名称列的宽度
- self.appearance_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "外观编码", "外观名称"])) # 设置表头
- self.appearance_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的外观信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM appearances ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.appearance_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.appearance_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.appearance_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_appearance)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_appearance)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_appearance)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_appearances)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- def add_appearance(self):
- AppearanceDialog.add_appearance(self)
- def delete_appearance(self):
- AppearanceDialog.delete_appearance(self)
- def edit_appearance(self):
- AppearanceDialog.edit_appearance(self)
- def save_appearances(self):
- AppearanceDialog.save_appearances(self)
- def create_collectible_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.collectible_tree_widget = QTreeWidget()
- self.collectible_tree_widget.setHeaderLabels(["选择", "收藏品编码", "收藏品名称"])
- self.collectible_tree_widget.setColumnCount(3)
- self.collectible_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.collectible_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.collectible_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.collectible_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.collectible_tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.collectible_tree_widget.setColumnWidth(1, 150) # 设置收藏品编码列的宽度
- self.collectible_tree_widget.setColumnWidth(2, 300) # 设置收藏品名称列的宽度
- self.collectible_tree_widget.setHeaderItem(QTreeWidgetItem(["选择", "收藏品编码", "收藏品名称"])) # 设置表头
- self.collectible_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- # 添加默认的收藏品信息
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute("SELECT name,code,selected FROM collectibles ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.collectible_tree_widget)
- item.setText(1, row[1])
- item.setText(2, row[0])
- checkbox = QCheckBox()
- #row[2]为1 设置成True ,为0 设置成False
- checkbox.setChecked(True if row[2] == 1 else False)
- self.collectible_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.collectible_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.add_collectible)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_collectible)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_collectible)
- button_layout.addWidget(edit_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_collectibles)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 新增收藏品
- def add_collectible(self):
- CollectibleDialog.add_collectible(self)
- # 删除收藏品
- def delete_collectible(self):
- CollectibleDialog.delete_collectible(self)
- # 编辑收藏品
- def edit_collectible(self):
- CollectibleDialog.edit_collectible(self)
- # 保存收藏品
- def save_collectibles(self):
- CollectibleDialog.save_collectibles(self)
- def create_config_info_form(self, prefix):
- form_layout = QFormLayout()
- form_layout.setAlignment(Qt.AlignmentFlag.AlignVCenter) # 确保表单布局内容靠左对齐
- # 从数据库中获取默认值
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute(
- "SELECT min_price, max_price, sort_mode, stop_condition, success_count, scan_count, page_size, pause_time, max_pages, ref_price_adjust, sweep_price_adjust FROM config LIMIT 1")
- default_values = c.fetchone()
- conn.close()
- # 创建选品最低价输入框及其标签
- min_price_label = QLabel(f"{prefix}最低价")
- self.min_price_edit = QLineEdit()
- self.min_price_edit.setFixedWidth(500) # 设置固定宽度为500像素
- # default_values 为None
- if default_values is not None:
- self.min_price_edit.setText(str(default_values[0]))
- form_layout.addRow(min_price_label, self.min_price_edit)
- # 创建选品最高价输入框及其标签
- max_price_label = QLabel(f"{prefix}最高价")
- self.max_price_edit = QLineEdit()
- self.max_price_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.max_price_edit.setText(str(default_values[1]))
- form_layout.addRow(max_price_label, self.max_price_edit)
- # 创建选品排序模式下拉选择框及其标签
- sort_mode_label = QLabel(f"{prefix}排序模式")
- self.sort_mode_combo = QComboBox()
- self.sort_mode_combo.addItems(["默认", "价格升序", "价格降序", "在售数量升序"])
- self.sort_mode_combo.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.sort_mode_combo.setCurrentText(default_values[2])
- form_layout.addRow(sort_mode_label, self.sort_mode_combo)
- # 创建选品停止条件下拉选择框及其标签
- stop_condition_label = QLabel(f"{prefix}停止条件")
- self.stop_condition_combo = QComboBox()
- self.stop_condition_combo.addItems(["按照成功数量", "按照扫描数量"])
- self.stop_condition_combo.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.stop_condition_combo.setCurrentText(default_values[3])
- form_layout.addRow(stop_condition_label, self.stop_condition_combo)
- # 创建成功数量配置输入框及其标签
- success_count_label = QLabel(f"{prefix}成功数量配置")
- self.success_count_edit = QLineEdit()
- self.success_count_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.success_count_edit.setText(str(default_values[4]))
- form_layout.addRow(success_count_label, self.success_count_edit)
- # 创建扫描商品数量配置输入框及其标签
- scan_count_label = QLabel(f"{prefix}扫描商品数量")
- self.scan_count_edit = QLineEdit()
- self.scan_count_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.scan_count_edit.setText(str(default_values[5]))
- form_layout.addRow(scan_count_label, self.scan_count_edit)
- # 创建选品接口每页请求数量配置输入框及其标签
- page_size_label = QLabel(f"{prefix}接口每页请求数量")
- self.page_size_edit = QLineEdit()
- self.page_size_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.page_size_edit.setText(str(default_values[6]))
- form_layout.addRow(page_size_label, self.page_size_edit)
- # 创建每次调用BUFF接口暂停时间配置输入框及其标签
- pause_time_label = QLabel(f"{prefix}接口暂停时间(秒)")
- self.pause_time_edit = QLineEdit()
- self.pause_time_edit.setFixedWidth(500) # 设置固定宽度为500像素
- # self.pause_time_edit.setText("10") # 设置默认值为10
- if default_values is not None:
- self.pause_time_edit.setText(str(default_values[7]))
- form_layout.addRow(pause_time_label, self.pause_time_edit)
- # 创建选品接口最大请求多少页配置输入框及其标签
- max_pages_label = QLabel(f"{prefix}接口最大请求多少页")
- self.max_pages_edit = QLineEdit()
- self.max_pages_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.max_pages_edit.setText(str(default_values[8]))
- form_layout.addRow(max_pages_label, self.max_pages_edit)
- # 创建商品参考价调整系数输入框及其标签
- ref_price_adjust_label = QLabel(f"{prefix}商品参考价调整系数%")
- self.ref_price_adjust_edit = QLineEdit()
- self.ref_price_adjust_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.ref_price_adjust_edit.setText(str(default_values[9]))
- form_layout.addRow(ref_price_adjust_label, self.ref_price_adjust_edit)
- # 创建商品扫货价调整系数输入框及其标签
- sweep_price_adjust_label = QLabel(f"{prefix}商品扫货价调整系数%")
- self.sweep_price_adjust_edit = QLineEdit()
- self.sweep_price_adjust_edit.setFixedWidth(500) # 设置固定宽度为500像素
- if default_values is not None:
- self.sweep_price_adjust_edit.setText(str(default_values[10]))
- form_layout.addRow(sweep_price_adjust_label, self.sweep_price_adjust_edit)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_config)
- save_button.setFixedSize(100, 50) # 设置固定宽度为500像素
- # 创建一个水平布局来放置保存按钮
- button_layout = QHBoxLayout()
- button_layout.setContentsMargins(300, 0, 0, 0)
- button_layout.addWidget(save_button, alignment=Qt.AlignmentFlag.AlignLeft)
- # 将垂直布局添加到表单布局中
- form_layout.addRow(button_layout)
- form_layout.setContentsMargins(300, 0, 0, 0)
- return form_layout
- def save_config(self):
- # 连接到SQLite数据库
- conn = sqlite3.connect('buff.db')
- cursor = conn.cursor()
- # 清空表中的数据
- cursor.execute('DELETE FROM config')
- # 获取配置信息
- min_price = self.min_price_edit.text()
- max_price = self.max_price_edit.text()
- sort_mode = self.sort_mode_combo.currentText()
- stop_condition = self.stop_condition_combo.currentText()
- success_count = self.success_count_edit.text()
- scan_count = self.scan_count_edit.text()
- page_size = self.page_size_edit.text()
- pause_time = self.pause_time_edit.text()
- max_pages = self.max_pages_edit.text()
- ref_price_adjust = self.ref_price_adjust_edit.text()
- sweep_price_adjust = self.sweep_price_adjust_edit.text()
- # 插入数据到表中
- cursor.execute('''
- INSERT INTO config (min_price, max_price, sort_mode, stop_condition, success_count, scan_count, page_size, pause_time, max_pages, ref_price_adjust, sweep_price_adjust)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ''', (
- min_price, max_price, sort_mode, stop_condition, success_count, scan_count, page_size, pause_time,
- max_pages,
- ref_price_adjust, sweep_price_adjust))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- QMessageBox.information(self, "保存选品配置", "选品配置已成功保存")
- # 选品日志的tab框
- def create_select_log_info_form(self):
- layout = QVBoxLayout()
- layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保布局内容靠左对齐
- # 创建树形控件
- self.select_log_tree_widget = QTreeWidget()
- self.select_log_tree_widget.setHeaderLabels(
- ["选择", "商品ID", "商品名称", "磨损最低值", "磨损最高值", "全磨损区间最低价", "扫货价", "判断价", "时间"])
- self.select_log_tree_widget.setColumnCount(9)
- self.select_log_tree_widget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection)
- self.select_log_tree_widget.setRootIsDecorated(True) # 启用根节点的装饰
- self.select_log_tree_widget.setAlternatingRowColors(True) # 设置交替行颜色
- self.select_log_tree_widget.setStyleSheet("QTreeWidget::item { padding: 5px; }") # 设置项的内边距
- # 启用复选框
- self.select_log_tree_widget.setColumnWidth(0, 50) # 设置选择列的宽度
- self.select_log_tree_widget.setColumnWidth(1, 100) # 设置商品ID列的宽度
- self.select_log_tree_widget.setColumnWidth(2, 200) # 设置商品名称列的宽度
- self.select_log_tree_widget.setColumnWidth(3, 100) # 设置磨损最低值列的宽度
- self.select_log_tree_widget.setColumnWidth(4, 100) # 设置磨损最高值列的宽度
- self.select_log_tree_widget.setColumnWidth(5, 150) # 设置全磨损区间最低价列的宽度
- self.select_log_tree_widget.setColumnWidth(6, 100) # 设置扫货价列的宽度
- self.select_log_tree_widget.setColumnWidth(7, 100) # 设置判断价列的宽度
- self.select_log_tree_widget.setColumnWidth(8, 150) # 设置时间列的宽度
- self.select_log_tree_widget.setHeaderItem(QTreeWidgetItem(
- ["选择", "商品ID", "商品名称", "磨损最低值", "磨损最高值", "全磨损区间最低价", "扫货价", "判断价",
- "时间"])) # 设置表头
- self.select_log_tree_widget.header().setDefaultAlignment(Qt.AlignmentFlag.AlignLeft) # 设置表头对齐方式
- conn = sqlite3.connect('buff.db')
- c = conn.cursor()
- c.execute(
- "SELECT item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price, timestamp FROM select_logs ")
- rows = c.fetchall()
- for row in rows:
- item = QTreeWidgetItem(self.select_log_tree_widget)
- item.setText(1, str(row[0]))
- item.setText(2, str(row[1]))
- item.setText(3, str(row[2]))
- item.setText(4, str(row[3]))
- item.setText(5, str(row[4]))
- item.setText(6, str(row[5]))
- item.setText(7, str(row[6]))
- item.setText(8, str(row[7]))
- checkbox = QCheckBox()
- checkbox.setChecked(False)
- self.select_log_tree_widget.setItemWidget(item, 0, checkbox)
- conn.close()
- layout.addWidget(self.select_log_tree_widget)
- # 创建按钮布局
- button_layout = QHBoxLayout()
- button_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 确保按钮布局内容靠左对齐
- # 创建添加按钮
- add_button = QPushButton("添加")
- add_button.clicked.connect(self.show_add_select_log_dialog)
- button_layout.addWidget(add_button)
- # 创建删除按钮
- delete_button = QPushButton("删除")
- delete_button.clicked.connect(self.delete_select_log)
- button_layout.addWidget(delete_button)
- # 创建编辑按钮
- edit_button = QPushButton("编辑")
- edit_button.clicked.connect(self.edit_select_log)
- button_layout.addWidget(edit_button)
- # 创建导出按钮
- export_button = QPushButton("导出")
- export_button.clicked.connect(self.export_selected_logs)
- button_layout.addWidget(export_button)
- # 创建保存按钮
- save_button = QPushButton("保存")
- save_button.clicked.connect(self.save_select_logs)
- button_layout.addWidget(save_button)
- layout.addLayout(button_layout)
- return layout
- # 导出日志
- def export_selected_logs(self):
- SelectLogDialog.export_selected_logs(self)
- # 保存日志
- def save_select_logs(self):
- SelectLogDialog.save_select_logs(self)
- # 编辑日志
- def edit_select_log(self):
- SelectLogDialog.edit_select_log(self)
- # 删除日志
- def delete_select_log(self):
- SelectLogDialog.delete_select_log(self)
- # 新增日志
- def show_add_select_log_dialog(self):
- SelectLogDialog.show_add_select_log_dialog(self)
- def show_selected_phone_number(self):
- # 设置选品停止标志为False
- self.stop_selecting_flag = False
- # 查询检索选品入参
- if not BUFFXP.checkBuffXPParams(self):
- return
- try:
- thread_searchGoods = threading.Thread(target=self.firstSelectGoods)
- thread_searchGoods.start()
- except Exception as e:
- print(f"Error: {e}")
- def firstSelectGoods(self):
- print('开始选品')
- # 已经选品的数量
- self.searchedGoodsNum = 0
- # 已经选品成功的数量
- self.search_success_count = 0
- # 组装商品选取API的入参list
- self.search_goods_param_list = []
- # 获取商品选取API的入参list
- BUFFXP.get_goods_param_list(self)
- self.last_goodsinfo_request_time = 0
- self.last_paintwear_request_time = 0
- self.last_minprice_request_time = 0
- # 更新选品cookie
- self.xp_my_headers.update({
- 'Cookie': self.cookie_text
- })
- try:
- print('选品接口请求参数列表 search_goods_param_list 长度:', len(self.search_goods_param_list))
- # 遍历search_goods_param_list
- while True:
- #判断退出条件
- if self.stop_selecting_flag:
- print('停止选品')
- return
- # 判断选品停止条件来判断是否需要终止
- if self.stop_condition == '按照成功数量':
- print(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- if int(self.success_count) < int(self.search_success_count):
- return
- else:
- # 按照选品数量来判断是否要停止
- print(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- if int(self.scan_count) < int(self.searchedGoodsNum):
- return
- for i in range(len(self.search_goods_param_list)):
- try:
- if self.stop_selecting_flag:
- print('停止选品')
- return
- # 判断选品停止条件来判断是否需要终止
- if self.stop_condition == '按照成功数量':
- print(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- if int(self.success_count) < int(self.search_success_count):
- return
- else:
- # 按照选品数量来判断是否要停止
- print(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- if int(self.scan_count) < int(self.searchedGoodsNum):
- return
- pagenum = 1
- j = pagenum
- first_flag = True
- while int(j) <= int(pagenum):
- datalist = []
- if self.stop_selecting_flag:
- print('停止选品')
- return
- # 判断选品停止条件来判断是否需要终止
- if self.stop_condition == '按照成功数量':
- print(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- if int(self.success_count) < int(self.search_success_count):
- return
- else:
- # 按照选品数量来判断是否要停止
- print(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- if int(self.scan_count) < int(self.searchedGoodsNum):
- return
- if not first_flag:
- self.search_goods_param_list[i]['page_num'] = j
- print(f"第{j}/{pagenum}页,API请求参数为:{self.search_goods_param_list[i]}")
- else:
- self.search_goods_param_list[i]['page_num'] = 1
- print(f"新查询条件第一次预请求,API请求参数为:{self.search_goods_param_list[i]}")
- try:
- # 开始时间为当前时间
- current_time = time.time()
- time_since_last_request = current_time - self.last_goodsinfo_request_time
- if time_since_last_request < float(self.pause_time):
- wait_time = float(self.pause_time) - time_since_last_request
- print(f"暂停 {wait_time:.2f} seconds before making the next request.")
- time.sleep(wait_time)
- api1_res = req.get(url=self.xp_goodsurl, headers=self.xp_my_headers,
- params=self.search_goods_param_list[i])
- print('遍历商品接口请求返回报文:', api1_res.text.strip()[:50])
- data = api1_res.json()['data']
- print('遍历商品接口请求返回报文中的CODE:', api1_res.json()['code'])
- # 如果data中的code不等于OK,则跳出循环
- if api1_res.json()['code'] != 'OK':
- print('选品接口请求返回报文:', api1_res.text.strip()[:50])
- print('选品接口请求返回报文code不等于OK,跳出循环')
- continue
- datalist.extend(data['items'])
- # 遍历datalist
- for k in range(len(datalist)):
- # 做终止判断是否点击了停止选品按钮
- if self.stop_selecting_flag:
- print('停止选品')
- return
- # 判断选品停止条件来判断是否需要终止
- if self.stop_condition == '按照成功数量':
- print(f'按照成功数量,设定的成功数量为:{self.success_count},当前检索已成功的数量为:{self.search_success_count}')
- if int(self.success_count) < int(self.search_success_count):
- return
- else:
- # 按照选品数量来判断是否要停止
- print(f'按照选品数量,设定的选品数量为:{self.scan_count},当前检索的选品数量为:{self.searchedGoodsNum}')
- if int(self.scan_count) < int(self.searchedGoodsNum):
- return
- print(f'商品id:{str(datalist[k]["id"])}开始进行价格分析')
- # 选品的数量+1
- self.searchedGoodsNum += 1
- # 1、获取磨损信息
- BUFFAPI.getPaintwearChoices(self, datalist[k]["id"])
- if len(self.paintwear_choices) <= 0:
- print(f'获取商品id:{datalist[k]["id"]}磨损信息失败,筛选不满足条件,继续下次循环')
- continue
- # 1、先获取全磨损的最低价 170
- min_price = float(BUFFAPI.getPaintwearChoicesMinPrice(self, datalist[k]["id"], '', ''))
- # min_price为0 则continue
- if min_price == 0:
- print(f'获取商品id:{datalist[k]["id"]}全磨损的最低价为0,筛选不满足条件,继续下次循环')
- continue
- # 每个磨损区间的最低价
- min_price_list = []
- # 2、获取每个磨损区间的最低价 270 260 230 240 170
- break_flag = False
- for i3 in range(len(self.paintwear_choices)):
- # 做终止判断是否点击了停止选品按钮
- if self.stop_selecting_flag:
- print('停止选品')
- return
- min_price_list.append(
- {
- 'min_wear': self.paintwear_choices[i3][0],
- 'max_wear': self.paintwear_choices[i3][1],
- 'min_price': float(
- BUFFAPI.getPaintwearChoicesMinPrice(self, datalist[k]["id"],
- self.paintwear_choices[
- i3][0],
- self.paintwear_choices[
- i3][1]))
- }
- )
- print(f'获取商品id:{datalist[k]["id"]}磨损区间及最低价信息:', min_price_list)
- # todo 区间内容有价格为0,则跳过该商品,跳到下一个商品
- for i2 in range(len(min_price_list)):
- if min_price_list[i2]['min_price'] == 0:
- print(f'获取商品id:{datalist[k]["id"]}磨损区间及最低价信息:', min_price_list)
- print(
- f'获取商品id:{datalist[k]["id"]}磨损区间及最低价信息中,有价格是0,跳过该商品')
- break_flag = True
- if break_flag:
- print(f'商品id:{datalist[k]["id"]} 筛选不满足条件,继续下次循环')
- continue
- # 3、全区间的最低价 170 * (1+10%),10%是设定的 = 187元
- pd_price = round(min_price * (100 + self.ref_price_adjust) / 100, 4)
- # 4、将5个磨损区间的最低价跟187比对,只留高于这个187价格的区间
- # 遍历 min_price_list
- for i1 in range(len(min_price_list)):
- if min_price_list[i1]['min_price'] < pd_price:
- # min_price_list 删除i1及以后的元素
- min_price_list = min_price_list[:i1]
- break
- # 5、根据阶梯来确定磨损区间
- # 遍历 min_price_list,判断元素中的min_price是否小于上一个元素的min_price,
- for i2 in range(len(min_price_list) - 1):
- if min_price_list[i2]['min_price'] < min_price_list[i2 + 1]['min_price']:
- # min_price_list 删除i2及以后的元素
- min_price_list = min_price_list[:i2 + 1]
- break
- # 6、170*(1+0.02)= 173.4 购买溢价
- gm_price = round(min_price * (100 + self.sweep_price_adjust) / 100, 4)
- # min_price_list 为空则继续下次循环
- if len(min_price_list) <= 0:
- print(f'商品id:{datalist[k]["id"]} 筛选不满足条件,继续下次循环')
- continue
- # 向BUFF选品日志标签页中添加一条数据
- timestamp = time.time()
- local_time = time.localtime(timestamp)
- formatted_time = time.strftime('%Y-%m-%d %H:%M:%S', local_time)
- print(f'商品id:{datalist[k]["id"]} 筛选成功, 磨损及价格区间min_price_list:',
- min_price_list)
- # 向BUFF选品日志标签页中增加记录 发出信号而不是直接调用 add_select_log
- self.log_added.emit(str(datalist[k]["id"]), str(datalist[k]["name"]),
- str(min_price_list[0]['min_wear']),
- str(min_price_list[-1]['max_wear']), str(min_price), str(gm_price),
- str(pd_price), str(formatted_time))
- conn = sqlite3.connect('buff.db')
- cursor = conn.cursor()
- cursor.execute('''
- INSERT INTO select_logs (item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price, timestamp)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
- ''', (datalist[k]["id"], datalist[k]["name"], min_price_list[0]['min_wear'], min_price_list[-1]['max_wear'], min_price, gm_price, pd_price, formatted_time))
- # 提交更改并关闭连接
- conn.commit()
- conn.close()
- # 检索成功数量+1
- self.search_success_count += 1
- if not first_flag:
- j += 1
- if first_flag:
- if int(data['total_page']) < int(self.max_page):
- pagenum = data['total_page']
- else:
- pagenum = self.max_page
- j = 1
- first_flag = False
- except Exception as e:
- print('选品接口1请求--失败', e)
- j = 1
- pagenum = 0
- finally:
- self.last_goodsinfo_request_time = time.time() # 更新上次请求时间为当前时间
- pass
- except Exception as e:
- print('选品接口2请求--失败', e)
- except Exception as e:
- print('选品接口3请求--失败', e)
- finally:
- print('停止选品')
- def stop_selecting(self):
- # 设置选品停止标志为True
- self.stop_selecting_flag = True
- QMessageBox.information(self, "停止选品", "选品操作已终止")
- def setup_phone_edit_map(self):
- self.phone_edit_map = {}
- self.email_edit_map = {}
- self.email_alias_edit_map = {}
- # 向BUFF选品日志标签页的列表中写数据的槽函数
- @pyqtSlot(str, str, str, str, str, str, str, str)
- def _add_select_log(self, item_id, item_name, min_wear, max_wear, min_full_wear_price, sweep_price, judge_price,
- timestamp):
- # 创建一个字典来存储记录的详细信息
- record = {
- '商品ID': item_id,
- '商品名称': item_name,
- '磨损最低值': min_wear,
- '磨损最高值': max_wear,
- '全磨损区间最低价': min_full_wear_price,
- '扫货价': sweep_price,
- '判断价': judge_price,
- '时间': timestamp
- }
- # 将新记录添加到树形控件中
- item = QTreeWidgetItem(self.select_log_tree_widget)
- item.setText(0, "") # 选择列为空
- item.setText(1, record['商品ID'])
- item.setText(2, record['商品名称'])
- item.setText(3, str(record['磨损最低值']))
- item.setText(4, str(record['磨损最高值']))
- item.setText(5, str(record['全磨损区间最低价']))
- item.setText(6, str(record['扫货价']))
- item.setText(7, str(record['判断价']))
- item.setText(8, record['时间'])
- # 创建复选框
- checkbox = QCheckBox()
- checkbox.setChecked(False)
- self.select_log_tree_widget.setItemWidget(item, 0, checkbox)
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- window = MainWindow()
- window.show()
- sys.exit(app.exec())
- #代码备份 发送商家报价的代码
- #res = req.post(self.buyGoodsUrl, headers=api_header, data=api_data)
- #print(f'post 请求 {self.buyGoodsUrl} 返回报文: {res.text.strip()}')
- #if res.json()['code'] == 'OK':
- # print(f'购买成功')
- # time.sleep(float(self.pause_time_edit.text()))
- # print(f'post 请求 {self.buyGoodsUrl} 返回报文code等于OK,商品id:{goods_id}的磨损区间{goods_min_wear}-{goods_max_wear}的商品信息:{goods_item}')
- # try:
- # bill_order_id = res.json()['data']['id']
- # print(f'开始发报价 bill_order_id:{bill_order_id}')
- # # fbj_api_data=json.dumps({
- # # "bill_orders": [
- # # bill_order_id
- # # ],
- # # "game": "csgo"
- # # })
- # # print(f'fbj_api_data: { fbj_api_data }')
- # # fbj_api_header = {
- # # "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",
- # # "Host": "buff.163.com", "X-Requested-With": "XMLHttpRequest",
- # # 'Referer': f"https://buff.163.com/market/buy_order/history?game=csgo",
- # # 'Cookie': self.cookie_text,
- # # "Content-Type":"application/json",
- # # 'x-csrftoken': "ImM2NTBjYmZhNjk2MGRjOWVkMTQxYjM5MTBjY2RhZjJjODRkNTBlMjUi.Z7WAmQ.yZ6n3Hcjv6eXHEElO1ZA95aqSEA"
- # # }
- # # todo 使用现有的工具,后续再开发
- # #fbj_res = req.post(self.fbjUrl, headers=fbj_api_header, data=fbj_api_data)
- # #print(f'post 请求 发报价 返回报文: {fbj_res.text.strip()}')
- # #if fbj_res.json()['code'] == 'OK':
- # # print(f'报价成功')
- # #else:
- # # print(f'报价失败')
- # except Exception as e:
- # print(f'商品发报价信息接口请求--失败', e)
|