PUGE 1 hónapja
szülő
commit
8cc26c6e92
3 módosított fájl, 455 hozzáadás és 5 törlés
  1. 1 0
      .gitignore
  2. 420 0
      主播工具.py
  3. 34 5
      爱回收.py

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 /build
 /dist
 *.spec
+user_scripts_backup.json

+ 420 - 0
主播工具.py

@@ -0,0 +1,420 @@
+import sys
+import json
+from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QHBoxLayout, 
+                             QVBoxLayout, QListWidget, QListWidgetItem, QCheckBox, 
+                             QPushButton, QLineEdit, QTextEdit, QGroupBox, 
+                             QSplitter, QLabel, QMessageBox, QComboBox, QShortcut)
+from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QKeySequence
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle("三栏布局 - 用户独立话术管理 (快捷键F1-F5)")
+        self.setGeometry(100, 100, 1300, 750)
+        
+        # 数据存储:用户话术字典 {用户名: [话术列表]}
+        self.user_scripts = {}
+        # 当前选中的用户
+        self.current_user = None
+        
+        # 中央部件
+        central_widget = QWidget()
+        self.setCentralWidget(central_widget)
+        
+        # 主布局 - 水平分割器
+        main_splitter = QSplitter(Qt.Horizontal)
+        central_layout = QHBoxLayout(central_widget)
+        central_layout.addWidget(main_splitter)
+        central_layout.setContentsMargins(10, 10, 10, 10)
+        
+        # ---------- 左侧:日志显示 ----------
+        left_widget = QWidget()
+        left_layout = QVBoxLayout(left_widget)
+        left_layout.setContentsMargins(5, 5, 5, 5)
+        
+        log_label = QLabel("📋 运行日志")
+        log_label.setStyleSheet("font-weight: bold; font-size: 14px;")
+        left_layout.addWidget(log_label)
+        
+        self.log_text = QTextEdit()
+        self.log_text.setReadOnly(True)
+        self.log_text.setPlaceholderText("日志信息将显示在这里...")
+        self.log_text.append("[系统] 程序启动")
+        self.log_text.append("[系统] 界面初始化完成")
+        self.log_text.append("[系统] 快捷键: F1-F5 快速切换用户")
+        left_layout.addWidget(self.log_text)
+        
+        log_btn_layout = QHBoxLayout()
+        clear_log_btn = QPushButton("清空日志")
+        clear_log_btn.clicked.connect(self.clear_log)
+        log_btn_layout.addStretch()
+        log_btn_layout.addWidget(clear_log_btn)
+        left_layout.addLayout(log_btn_layout)
+        
+        # ---------- 中间:在线用户列表 ----------
+        middle_widget = QWidget()
+        middle_layout = QVBoxLayout(middle_widget)
+        middle_layout.setContentsMargins(5, 5, 5, 5)
+        
+        user_label = QLabel("👥 在线用户列表")
+        user_label.setStyleSheet("font-weight: bold; font-size: 14px;")
+        middle_layout.addWidget(user_label)
+        
+        select_btn_layout = QHBoxLayout()
+        self.select_all_btn = QPushButton("✅ 全选")
+        self.deselect_all_btn = QPushButton("❌ 取消全选")
+        self.select_all_btn.clicked.connect(self.select_all_users)
+        self.deselect_all_btn.clicked.connect(self.deselect_all_users)
+        select_btn_layout.addWidget(self.select_all_btn)
+        select_btn_layout.addWidget(self.deselect_all_btn)
+        select_btn_layout.addStretch()
+        middle_layout.addLayout(select_btn_layout)
+        
+        self.user_list_widget = QListWidget()
+        self.user_list_widget.setSelectionMode(QListWidget.NoSelection)
+        # 添加示例用户
+        sample_users = ["用户A", "用户B", "用户C", "用户D", "用户E"]
+        for user in sample_users:
+            self.add_user_item(user)
+            # 初始化用户话术数据
+            self.user_scripts[user] = [f"话术1: 您好{user},请问有什么可以帮您?", 
+                                       f"话术2: {user},感谢您的反馈,我们会尽快处理。",
+                                       f"话术3: {user},请您稍等,我为您转接专员。"]
+        middle_layout.addWidget(self.user_list_widget)
+        
+        user_count_label = QLabel(f"当前在线人数: {self.user_list_widget.count()}")
+        user_count_label.setStyleSheet("color: gray;")
+        middle_layout.addWidget(user_count_label)
+        
+        # ---------- 右侧:用户独立话术列表 ----------
+        right_widget = QWidget()
+        right_layout = QVBoxLayout(right_widget)
+        right_layout.setContentsMargins(5, 5, 5, 5)
+        
+        # 顶部:用户选择下拉框
+        user_select_layout = QHBoxLayout()
+        user_select_layout.addWidget(QLabel("选择用户 (快捷键F1-F5):"))
+        self.user_combo = QComboBox()
+        self.user_combo.addItems(sample_users)
+        self.user_combo.currentTextChanged.connect(self.on_user_changed)
+        user_select_layout.addWidget(self.user_combo)
+        user_select_layout.addStretch()
+        right_layout.addLayout(user_select_layout)
+        
+        # 话术列表标题
+        script_label = QLabel("📝 话术列表 (当前用户)")
+        script_label.setStyleSheet("font-weight: bold; font-size: 14px;")
+        right_layout.addWidget(script_label)
+        
+        # 话术列表显示
+        self.script_list_widget = QListWidget()
+        right_layout.addWidget(self.script_list_widget)
+        
+        # 话术编辑区域
+        script_edit_layout = QVBoxLayout()
+        
+        # 添加话术
+        add_layout = QHBoxLayout()
+        self.script_input = QLineEdit()
+        self.script_input.setPlaceholderText("输入新话术内容...")
+        add_btn = QPushButton("➕ 添加")
+        add_btn.clicked.connect(self.add_script)
+        add_layout.addWidget(self.script_input)
+        add_layout.addWidget(add_btn)
+        script_edit_layout.addLayout(add_layout)
+        
+        # 删除和修改按钮
+        modify_layout = QHBoxLayout()
+        delete_btn = QPushButton("🗑️ 删除选中")
+        delete_btn.clicked.connect(self.delete_script)
+        modify_btn = QPushButton("✏️ 修改选中")
+        modify_btn.clicked.connect(self.modify_script)
+        modify_layout.addWidget(delete_btn)
+        modify_layout.addWidget(modify_btn)
+        script_edit_layout.addLayout(modify_layout)
+        
+        # 保存按钮
+        save_layout = QHBoxLayout()
+        save_layout.addStretch()
+        self.save_scripts_btn = QPushButton("💾 保存话术配置")
+        self.save_scripts_btn.setStyleSheet("background-color: #2196F3; color: white; font-weight: bold; padding: 8px 20px; border-radius: 5px;")
+        self.save_scripts_btn.clicked.connect(self.save_user_scripts)
+        save_layout.addWidget(self.save_scripts_btn)
+        script_edit_layout.addLayout(save_layout)
+        
+        right_layout.addLayout(script_edit_layout)
+        
+        # 发送任务按钮
+        send_layout = QHBoxLayout()
+        send_layout.addStretch()
+        self.send_task_btn = QPushButton("🚀 发送任务")
+        self.send_task_btn.setStyleSheet("background-color: #4CAF50; color: white; font-weight: bold; padding: 8px 20px; border-radius: 5px;")
+        self.send_task_btn.clicked.connect(self.send_task)
+        send_layout.addWidget(self.send_task_btn)
+        right_layout.addLayout(send_layout)
+        
+        # ---------- 将三个部件加入分割器 ----------
+        main_splitter.addWidget(left_widget)
+        main_splitter.addWidget(middle_widget)
+        main_splitter.addWidget(right_widget)
+        main_splitter.setSizes([300, 450, 450])
+        
+        # 初始化显示第一个用户的话术
+        if sample_users:
+            self.current_user = sample_users[0]
+            self.load_user_scripts(self.current_user)
+        
+        # ---------- 设置快捷键 F1-F5 ----------
+        self.setup_shortcuts()
+        
+        # 窗口样式
+        self.setStyleSheet("""
+            QGroupBox {
+                font-weight: bold;
+                border: 1px solid #ccc;
+                border-radius: 5px;
+                margin-top: 10px;
+            }
+            QGroupBox::title {
+                subcontrol-origin: margin;
+                left: 10px;
+                padding: 0 5px 0 5px;
+            }
+            QListWidget::item {
+                padding: 5px;
+            }
+            QTextEdit {
+                background-color: #f8f8f8;
+                font-family: Consolas, monospace;
+            }
+            QComboBox {
+                padding: 5px;
+                min-width: 150px;
+            }
+        """)
+    
+    # ---------- 快捷键设置 ----------
+    def setup_shortcuts(self):
+        """设置F1-F5快捷键切换用户"""
+        # F1 选择第一个用户,F2 第二个,以此类推
+        shortcuts = [
+            (Qt.Key_F1, 0),
+            (Qt.Key_F2, 1),
+            (Qt.Key_F3, 2),
+            (Qt.Key_F4, 3),
+            (Qt.Key_F5, 4),
+        ]
+        
+        for key, index in shortcuts:
+            shortcut = QShortcut(QKeySequence(key), self)
+            # 使用lambda捕获index,并绑定到切换函数
+            shortcut.activated.connect(lambda idx=index: self.switch_to_user_by_index(idx))
+    
+    def switch_to_user_by_index(self, index):
+        """根据索引切换到对应用户"""
+        if index < self.user_combo.count():
+            user = self.user_combo.itemText(index)
+            self.user_combo.setCurrentText(user)
+            self.log_text.append(f"[快捷键] 切换到用户: {user}")
+        else:
+            self.log_text.append(f"[快捷键] 用户索引 {index} 不存在")
+    
+    # ---------- 用户管理 ----------
+    def add_user_item(self, username):
+        """添加一个带复选框的用户项"""
+        item = QListWidgetItem()
+        checkbox = QCheckBox(username)
+        self.user_list_widget.addItem(item)
+        self.user_list_widget.setItemWidget(item, checkbox)
+        checkbox.stateChanged.connect(self.on_user_check_changed)
+    
+    def get_user_checkboxes(self):
+        """获取所有用户复选框"""
+        checkboxes = []
+        for i in range(self.user_list_widget.count()):
+            item = self.user_list_widget.item(i)
+            widget = self.user_list_widget.itemWidget(item)
+            if isinstance(widget, QCheckBox):
+                checkboxes.append(widget)
+        return checkboxes
+    
+    def get_selected_users(self):
+        """获取所有选中的用户"""
+        selected = []
+        for cb in self.get_user_checkboxes():
+            if cb.isChecked():
+                selected.append(cb.text())
+        return selected
+    
+    def select_all_users(self):
+        for cb in self.get_user_checkboxes():
+            cb.setChecked(True)
+        self.log_text.append("[操作] 已全选所有用户")
+    
+    def deselect_all_users(self):
+        for cb in self.get_user_checkboxes():
+            cb.setChecked(False)
+        self.log_text.append("[操作] 已取消全选所有用户")
+    
+    def on_user_check_changed(self):
+        """复选框状态改变时更新下拉框列表"""
+        # 获取当前所有用户
+        current_users = []
+        for i in range(self.user_list_widget.count()):
+            item = self.user_list_widget.item(i)
+            widget = self.user_list_widget.itemWidget(item)
+            if isinstance(widget, QCheckBox):
+                current_users.append(widget.text())
+        
+        # 更新下拉框
+        current_selection = self.user_combo.currentText()
+        self.user_combo.clear()
+        self.user_combo.addItems(current_users)
+        
+        # 如果之前的用户还在列表中,恢复选择
+        if current_selection in current_users:
+            self.user_combo.setCurrentText(current_selection)
+        elif current_users:
+            self.user_combo.setCurrentIndex(0)
+    
+    # ---------- 话术管理 (用户独立) ----------
+    def load_user_scripts(self, username):
+        """加载指定用户的话术列表"""
+        if username in self.user_scripts:
+            self.script_list_widget.clear()
+            for script in self.user_scripts[username]:
+                self.script_list_widget.addItem(script)
+            self.current_user = username
+            self.log_text.append(f"[系统] 加载用户 '{username}' 的话术列表")
+    
+    def on_user_changed(self, username):
+        """下拉框切换用户"""
+        if username and username != self.current_user:
+            # 如果当前用户有修改但未保存,先保存
+            if self.current_user and self.current_user in self.user_scripts:
+                # 自动保存当前用户的话术
+                self.save_current_user_scripts()
+            
+            self.load_user_scripts(username)
+    
+    def save_current_user_scripts(self):
+        """保存当前用户的话术到内存"""
+        if self.current_user and self.current_user in self.user_scripts:
+            scripts = []
+            for i in range(self.script_list_widget.count()):
+                scripts.append(self.script_list_widget.item(i).text())
+            self.user_scripts[self.current_user] = scripts
+            self.log_text.append(f"[系统] 自动保存用户 '{self.current_user}' 的话术配置")
+    
+    def save_user_scripts(self):
+        """手动保存当前用户的话术(并持久化)"""
+        if not self.current_user:
+            QMessageBox.warning(self, "提示", "请先选择一个用户!")
+            return
+        
+        # 保存到内存
+        self.save_current_user_scripts()
+        
+        # 持久化保存到文件
+        try:
+            with open("user_scripts_backup.json", "w", encoding="utf-8") as f:
+                json.dump(self.user_scripts, f, ensure_ascii=False, indent=2)
+            self.log_text.append(f"[系统] 话术配置已保存到文件 user_scripts_backup.json")
+            QMessageBox.information(self, "保存成功", f"用户 '{self.current_user}' 的话术配置已保存!")
+        except Exception as e:
+            QMessageBox.critical(self, "保存失败", f"保存到文件时出错: {str(e)}")
+    
+    def add_script(self):
+        """添加话术到当前用户"""
+        text = self.script_input.text().strip()
+        if text:
+            self.script_list_widget.addItem(text)
+            self.script_input.clear()
+            # 自动保存
+            self.save_current_user_scripts()
+            self.log_text.append(f"[操作] 为用户 '{self.current_user}' 添加话术: {text}")
+        else:
+            QMessageBox.information(self, "提示", "话术内容不能为空!")
+    
+    def delete_script(self):
+        """删除当前用户选中的话术"""
+        current_row = self.script_list_widget.currentRow()
+        if current_row >= 0:
+            item_text = self.script_list_widget.item(current_row).text()
+            self.script_list_widget.takeItem(current_row)
+            # 自动保存
+            self.save_current_user_scripts()
+            self.log_text.append(f"[操作] 删除用户 '{self.current_user}' 的话术: {item_text}")
+        else:
+            QMessageBox.information(self, "提示", "请先选中一条话术!")
+    
+    def modify_script(self):
+        """修改当前用户选中的话术"""
+        current_row = self.script_list_widget.currentRow()
+        if current_row >= 0:
+            old_text = self.script_list_widget.item(current_row).text()
+            new_text, ok = QMessageBox.getText(self, "修改话术", "请输入新的话术内容:", 
+                                               text=old_text)
+            if ok and new_text.strip():
+                self.script_list_widget.item(current_row).setText(new_text.strip())
+                # 自动保存
+                self.save_current_user_scripts()
+                self.log_text.append(f"[操作] 修改用户 '{self.current_user}' 的话术: {old_text} -> {new_text.strip()}")
+            elif ok and not new_text.strip():
+                QMessageBox.information(self, "提示", "话术内容不能为空!")
+        else:
+            QMessageBox.information(self, "提示", "请先选中一条话术!")
+    
+    def clear_log(self):
+        self.log_text.clear()
+        self.log_text.append("[系统] 日志已清空")
+        self.log_text.append("[系统] 快捷键: F1-F5 快速切换用户")
+    
+    # ---------- 发送任务 ----------
+    def send_task(self):
+        """发送任务到选中的用户"""
+        selected_users = self.get_selected_users()
+        
+        if not selected_users:
+            QMessageBox.warning(self, "提示", "请至少选择一个用户!")
+            return
+        
+        # 获取每个用户选中的话术 (这里演示:取每个用户的第一条话术)
+        task_details = []
+        for user in selected_users:
+            if user in self.user_scripts and self.user_scripts[user]:
+                script = self.user_scripts[user][0]  # 取第一条
+                task_details.append(f"{user}: {script}")
+            else:
+                task_details.append(f"{user}: (无话术)")
+        
+        # 记录日志
+        self.log_text.append(f"[任务] 发送给 {len(selected_users)} 个用户:")
+        for detail in task_details:
+            self.log_text.append(f"  - {detail}")
+        self.log_text.append("[任务] 发送完成 (功能待实现)")
+        
+        # 显示详情
+        msg = "\n".join(task_details)
+        QMessageBox.information(self, "发送任务", 
+                                 f"已发送任务给 {len(selected_users)} 个用户:\n\n{msg}")
+    
+    # ---------- 窗口关闭时保存 ----------
+    def closeEvent(self, event):
+        """关闭窗口时自动保存所有用户话术"""
+        if self.current_user:
+            self.save_current_user_scripts()
+        try:
+            with open("user_scripts_backup.json", "w", encoding="utf-8") as f:
+                json.dump(self.user_scripts, f, ensure_ascii=False, indent=2)
+            self.log_text.append("[系统] 程序退出,已自动保存所有话术配置")
+        except:
+            pass
+        event.accept()
+
+if __name__ == "__main__":
+    app = QApplication(sys.argv)
+    window = MainWindow()
+    window.show()
+    sys.exit(app.exec_())

+ 34 - 5
爱回收.py

@@ -26,13 +26,22 @@ class PhoneQueryApp:
         self.total_pages = 0
         self.page_size = 30
         self.current_keyword = ""
+        self.current_sort = "sort_composite"  # 默认综合排序
+        
+        # 排序选项映射
+        self.sort_map = {
+            "综合排序": "sort_composite",
+            "价格从低到高": "sort_price_asc",
+            "价格从高到低": "sort_price_desc"
+        }
         
         # 筛选选项映射
         self.memory_map = {
             "1T": 187,
             "512G": 192,
             "256G": 209,
-            "128G": 210
+            "128G": 210,
+            "64G": 217,
         }
         
         self.battery_map = {
@@ -137,14 +146,26 @@ class PhoneQueryApp:
         query_frame = ttk.LabelFrame(main_frame, text="查询条件", padding="10")
         query_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
         query_frame.columnconfigure(1, weight=1)
+        query_frame.columnconfigure(3, weight=1)
         
+        # 机型输入
         ttk.Label(query_frame, text="机型:", font=("Arial", 11)).grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
-        self.model_entry = ttk.Entry(query_frame, width=50, font=("Arial", 11))
+        self.model_entry = ttk.Entry(query_frame, width=35, font=("Arial", 11))
         self.model_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
         self.model_entry.insert(0, "iPhone 15 Pro")
         
+        # 排序选择
+        ttk.Label(query_frame, text="排序方式:", font=("Arial", 11)).grid(row=0, column=2, sticky=tk.W, padx=(10, 10))
+        self.sort_var = tk.StringVar(value="综合排序")
+        self.sort_combo = ttk.Combobox(query_frame, textvariable=self.sort_var, 
+                                       values=["综合排序", "价格从低到高", "价格从高到低", "最新上架", "人气最高"],
+                                       width=15, state="readonly", font=("Arial", 10))
+        self.sort_combo.grid(row=0, column=3, sticky=(tk.W, tk.E), padx=(0, 10))
+        self.sort_combo.bind('<<ComboboxSelected>>', self.on_sort_changed)
+        
+        # 搜索按钮
         self.search_btn = ttk.Button(query_frame, text="搜索", command=self.search_products, width=15)
-        self.search_btn.grid(row=0, column=2)
+        self.search_btn.grid(row=0, column=4)
         
         # ==================== 筛选区域 ====================
         # 第一行:内存 + 电池效率(各占一半)
@@ -292,6 +313,11 @@ class PhoneQueryApp:
         
         self.update_pagination_buttons()
         
+    def on_sort_changed(self, event=None):
+        """排序方式改变时自动搜索"""
+        if self.model_entry.get().strip():
+            self.search_products()
+        
     def get_selected_memory(self):
         """获取选中的内存PPV ID列表"""
         selected = []
@@ -349,6 +375,8 @@ class PhoneQueryApp:
             
         self.current_keyword = keyword
         self.current_page = page
+        # 获取当前选中的排序方式
+        self.current_sort = self.sort_map.get(self.sort_var.get(), "sort_composite")
         
         for item in self.result_tree.get_children():
             self.result_tree.delete(item)
@@ -376,7 +404,7 @@ class PhoneQueryApp:
             condition_tags = self.get_selected_condition_tags()
             
             request_data = {
-                "sortValue": "sort_composite",
+                "sortValue": self.current_sort,  # 使用当前选中的排序方式
                 "scene": "search",
                 "keyword": keyword,
                 "sirReq": False,
@@ -497,7 +525,8 @@ class PhoneQueryApp:
                 'info': info
             })
             
-        self.status_var.set(f"第 {page + 1} 页,共找到 {len(data)} 条结果")
+        sort_name = self.sort_var.get()
+        self.status_var.set(f"第 {page + 1} 页,排序: {sort_name},共找到 {len(data)} 条结果")
         self.update_pagination_buttons()
         
     def update_pagination_buttons(self):