diff --git a/.idea/iOSAI.iml b/.idea/iOSAI.iml index f571432..df5cbff 100644 --- a/.idea/iOSAI.iml +++ b/.idea/iOSAI.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index db8786c..c27b771 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Module/FlaskService.py b/Module/FlaskService.py index 066e111..04a9882 100644 --- a/Module/FlaskService.py +++ b/Module/FlaskService.py @@ -387,5 +387,48 @@ def aiConfig(): JsonUtils.write_json("aiConfig", dict) return ResultData(data="").toJson() +# 查询主播聊天发送的最后一条信息 +@app.route("/select_last_message", methods=['GET']) +def select_last_message(): + data = JsonUtils.query_all_json_items() + + return ResultData(data=data).toJson() + + +@app.route("/update_last_message", methods=['POST']) +def update_last_message(): + data = request.get_json() # 解析 JSON + sender = data.get("sender") + udid = data.get("device") + text = data.get("text") + + updated_count = JsonUtils.update_json_items( + match={"sender": sender, "text": text}, # 匹配条件 + patch={"status": 1}, # 修改内容 + filename="log/last_message.json", # 要修改的文件 + multi=False # 只改第一条匹配的 + ) + if updated_count > 0: + return ResultData(data=updated_count, msg="修改成功").toJson() + return ResultData(data=updated_count, msg="修改失败").toJson() + + +@app.route("/delete_last_message", methods=['POST']) +def delete_last_message(): + data = request.get_json() # 解析 JSON + sender = data.get("sender") + udid = data.get("device") + text = data.get("text") + + updated_count = JsonUtils.delete_json_items( + match={"sender": sender, "text": text}, # 匹配条件 + filename="log/last_message.json", # 要修改的文件 + multi=False # 只改第一条匹配的 + ) + if updated_count > 0: + return ResultData(data=updated_count, msg="修改成功").toJson() + return ResultData(data=updated_count, msg="修改失败").toJson() + + if __name__ == '__main__': app.run("0.0.0.0", port=5000, debug=True, use_reloader=False) diff --git a/Utils/AiUtils.py b/Utils/AiUtils.py index 71515ce..f4f7934 100644 --- a/Utils/AiUtils.py +++ b/Utils/AiUtils.py @@ -709,4 +709,4 @@ class AiUtils(object): json.dump(data, f, ensure_ascii=False, indent=2) except Exception as e: LogManager.error(f"[delete_anchors_by_ids] 写入失败: {e}") - return deleted + return deleted \ No newline at end of file diff --git a/Utils/JsonUtils.py b/Utils/JsonUtils.py index e3ca259..0dda46c 100644 --- a/Utils/JsonUtils.py +++ b/Utils/JsonUtils.py @@ -2,6 +2,9 @@ import os import json from pathlib import Path +from Utils.LogManager import LogManager +from pathlib import Path +import portalocker as locker # ① 引入跨平台锁 class JsonUtils: @staticmethod @@ -98,3 +101,123 @@ class JsonUtils: except Exception as e: print(f"删除 JSON key 失败: {e}") return False + # "-------------------------------------------------" + @classmethod + def _read_json_list(cls, file_path: Path) -> list: + try: + if not file_path.exists(): + return [] + with file_path.open("r", encoding="utf-8") as f: + data = json.load(f) + return data if isinstance(data, list) else [] + except Exception: + return [] + + @classmethod + def _write_json_list(cls, file_path: Path, data: list) -> None: + file_path.parent.mkdir(parents=True, exist_ok=True) + with file_path.open("w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=4) + + # --- 新增:通用追加(不做字段校验) --- + @classmethod + def append_json_items(cls, items, filename="log/last_message.json"): + """ + 将 dict 或 [dict, ...] 追加到 JSON 文件(数组)中;不校验字段。 + """ + file_path = Path(filename) + data = cls._read_json_list(file_path) + + # 统一成 list + if isinstance(items, dict): + items = [items] + elif not isinstance(items, list): + # 既不是 dict 也不是 list,直接忽略 + return + + # 只接受字典项 + items = [it for it in items if isinstance(it, dict)] + if not items: + return + + data.extend(items) + + LogManager.method_info(filename,"路径") + cls._write_json_list(file_path, data) + + + @classmethod + def update_json_items(cls, match: dict, patch: dict, filename="log/last_message.json", multi: bool = True) -> int: + """ + 修改 JSON 文件(数组)中符合条件的项 + :param match: 匹配条件(如 {"sender": "xxx"}) + :param patch: 要修改/更新的字段(如 {"status": 1}) + :param filename: JSON 文件路径 + :param multi: True=修改所有匹配项,False=只修改第一项 + :return: 修改的条数 + """ + file_path = Path(filename) + data = cls._read_json_list(file_path) + + if not isinstance(match, dict) or not isinstance(patch, dict): + return 0 + + updated = 0 + for idx, item in enumerate(data): + if not isinstance(item, dict): + continue + + # 判断是否匹配 + if all(item.get(k) == v for k, v in match.items()): + data[idx].update(patch) + updated += 1 + if not multi: + break + + if updated > 0: + cls._write_json_list(file_path, data) + + return updated + + @classmethod + def query_all_json_items(cls, filename="log/last_message.json") -> list: + """ + 查询 JSON 文件(数组)中的所有项 + :param filename: JSON 文件路径 + :return: list,可能为空 + """ + file_path = Path(filename) + print(file_path) + data = cls._read_json_list(file_path) + return data if isinstance(data, list) else [] + + @classmethod + def delete_json_items(cls, + match: dict, + filename: str = "log/last_message.json", + multi: bool = True) -> int: + file_path = Path(filename) + with file_path.open('r+', encoding='utf-8') as f: + locker.lock(f, locker.LOCK_EX) # ② 加独占锁(Windows/Linux 通用) + try: + data = json.load(f) + if not isinstance(match, dict): + return 0 + + deleted = 0 + new_data = [] + for item in data: + if isinstance(item, dict) and all(item.get(k) == v for k, v in match.items()): + if multi or deleted == 0: # 删多条 / 第一条 + deleted += 1 + continue + new_data.append(item) + + if deleted: + f.seek(0) + json.dump(new_data, f, ensure_ascii=False, indent=2) + f.truncate() + + return deleted + finally: + locker.unlock(f) # ③ 解锁 \ No newline at end of file diff --git a/Utils/Requester.py b/Utils/Requester.py index a45dac4..2e0dbe0 100644 --- a/Utils/Requester.py +++ b/Utils/Requester.py @@ -51,10 +51,14 @@ class Requester(): contactTool = aiConfig.get("contactTool", "") contact = aiConfig.get("contact", "") - param["agentName"] = agentName - param["guildName"] = guildName - param["contactTool"] = contactTool - param["contact"] = contact + inputs = { + "agentName":agentName, + "guildName":guildName, + "contactTool":contactTool, + "contact":contact + } + + param["inputs"] = inputs try: url = "https://ai.yolozs.com/chat" diff --git a/data/aiConfig.json b/data/aiConfig.json deleted file mode 100644 index 07dd0e9..0000000 --- a/data/aiConfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "agentName": "小花", - "guildName": "牛逼工会", - "contactTool": "line", - "contact": "7788990" -} \ No newline at end of file diff --git a/resources/FlashLink.exe b/resources/FlashLink.exe new file mode 100644 index 0000000..370f320 Binary files /dev/null and b/resources/FlashLink.exe differ diff --git a/script/ScriptManager.py b/script/ScriptManager.py index af1b221..e2186c2 100644 --- a/script/ScriptManager.py +++ b/script/ScriptManager.py @@ -7,6 +7,7 @@ import wda import os from Utils.AiUtils import AiUtils from Utils.ControlUtils import ControlUtils +from Utils.JsonUtils import JsonUtils from Utils.LogManager import LogManager from Entity.Variables import anchorList, removeModelFromAnchorList, anchorWithSession from Utils.Requester import Requester @@ -321,9 +322,9 @@ class ScriptManager(): ControlUtils.clickBack(session) time.sleep(2) - print("循环条件1", not event.is_set()) - print("循环条件2", len(anchorList) > 0) - print("总循环条件", not event.is_set() and len(anchorList) > 0) + LogManager.method_info(f"循环条件1:{not event.is_set()}", "关注打招呼", udid) + LogManager.method_info(f"循环条件2:{len(anchorList) > 0}", "关注打招呼", udid) + LogManager.method_info(f"循环条件3:{not event.is_set() and len(anchorList) > 0}", "关注打招呼", udid) # 循环条件。1、 循环关闭 2、 数据处理完毕 while not event.is_set(): @@ -358,7 +359,7 @@ class ScriptManager(): input.clear_text() time.sleep(1) # 输入主播id - input.set_text(aid + "\n") + input.set_text(f"{aid or '暂无数据'}\n") # 定位 "关注" 按钮 通过关注按钮的位置点击主播首页 @@ -487,11 +488,12 @@ class ScriptManager(): chatInput.click() time.sleep(2) # 发送消息 - chatInput.set_text(msg + "\n") + chatInput.set_text(f"{msg or '暂无数据'}\n") + + # input.set_text(f"{aid or '暂无数据'}\n") + time.sleep(1) - - else: print("无法发送信息") LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid) @@ -731,12 +733,22 @@ class ScriptManager(): LogManager.method_info(f"获取主播的名称:{anchor_name}", "检测消息", udid) # 找到输入框 + last_data = [{ + "sender": anchor_name, + "device": udid, + "text": last_msg, + "status": 0 + }] + print(last_data) + LogManager.method_info(f"主播最后发送的数据:{last_data}", "检测消息", udid) + JsonUtils.append_json_items(last_data, "log/last_message.json") sel = session.xpath("//TextView") if anchor_name not in anchorWithSession: # 如果是第一次发消息(没有sessionId的情况) - response = Requester.chatToAi({"msg": last_msg_text}) + + response = Requester.chatToAi({"query": last_msg_text}) aiResult = response['result'] sessionId = response['session_id'] @@ -746,20 +758,21 @@ class ScriptManager(): sel.click() # 聚焦 time.sleep(1) sel.clear_text() - sel.set_text(aiResult + "\n") + sel.set_text(f"{aiResult or '暂无数据'}\n") + else: LogManager.method_error("找不到输入框,重启", "检测消息", udid) raise Exception("找不到输入框,重启") else: # 如果不是第一次发消息(证明存储的有sessionId) sessionId = anchorWithSession[anchor_name] - response = Requester.chatToAi({"msg": last_msg_text, "sid": sessionId}) + response = Requester.chatToAi({"query": last_msg_text, "conversation_id": sessionId}) aiResult = response['result'] if sel.exists: sel.click() # 聚焦 time.sleep(1) sel.clear_text() - sel.set_text(aiResult + "\n") + sel.set_text(f"{aiResult or '暂无数据'}\n") LogManager.method_info(f"存储的sessionId:{anchorWithSession}", "检测消息", udid) time.sleep(1)