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/.idea/workspace.xml b/.idea/workspace.xml
index 00341f0..d97821c 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,8 +5,14 @@
+
+
+
+
+
+
@@ -49,31 +55,35 @@
- {
- "keyToString": {
- "ASKED_ADD_EXTERNAL_FILES": "true",
- "Python.12.executor": "Run",
- "Python.123.executor": "Run",
- "Python.Main.executor": "Run",
- "Python.tidevice_entry.executor": "Run",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
- "RunOnceActivity.git.unshallow": "true",
- "SHARE_PROJECT_CONFIGURATION_FILES": "true",
- "git-widget-placeholder": "main",
- "javascript.nodejs.core.library.configured.version": "20.17.0",
- "javascript.nodejs.core.library.typings.version": "20.17.58",
- "last_opened_file_path": "F:/company code/AI item/20250820/iOSAI",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "preferences.editor.code.editing",
- "vue.rearranger.settings.migration": "true"
+
+}]]>
+
+
+
@@ -118,6 +128,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -166,6 +199,7 @@
+
@@ -304,19 +338,21 @@
-
+
+
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Utils/JsonUtils.py b/Utils/JsonUtils.py
index d80e387..0dda46c 100644
--- a/Utils/JsonUtils.py
+++ b/Utils/JsonUtils.py
@@ -3,7 +3,8 @@ import json
from pathlib import Path
from Utils.LogManager import LogManager
-
+from pathlib import Path
+import portalocker as locker # ① 引入跨平台锁
class JsonUtils:
@staticmethod
@@ -190,39 +191,33 @@ class JsonUtils:
data = cls._read_json_list(file_path)
return data if isinstance(data, list) else []
-
-
@classmethod
- def delete_json_items(cls, match: dict, filename="log/last_message.json", multi: bool = True) -> int:
- """
- 删除 JSON 文件(数组)中符合条件的项
- :param match: 匹配条件(如 {"sender": "xxx"})
- :param filename: JSON 文件路径
- :param multi: True=删除所有匹配项,False=只删除第一项
- :return: 删除的条数
- """
+ def delete_json_items(cls,
+ match: dict,
+ filename: str = "log/last_message.json",
+ multi: bool = True) -> int:
file_path = Path(filename)
- data = cls._read_json_list(file_path)
+ 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
- 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)
- deleted = 0
- new_data = []
- for item in data:
- if not isinstance(item, dict):
- continue
- # 是否匹配
- if all(item.get(k) == v for k, v in match.items()):
- deleted += 1
- if not multi and deleted > 0:
- # 只删除一条 → 剩下的全保留
- new_data.extend(data[data.index(item) + 1:])
- break
- continue
- new_data.append(item)
+ if deleted:
+ f.seek(0)
+ json.dump(new_data, f, ensure_ascii=False, indent=2)
+ f.truncate()
- if deleted > 0:
- cls._write_json_list(file_path, new_data)
-
- return deleted
+ 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 eae5d2c..e2186c2 100644
--- a/script/ScriptManager.py
+++ b/script/ScriptManager.py
@@ -322,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():
@@ -359,7 +359,7 @@ class ScriptManager():
input.clear_text()
time.sleep(1)
# 输入主播id
- input.set_text(aid + "\n")
+ input.set_text(f"{aid or '暂无数据'}\n")
# 定位 "关注" 按钮 通过关注按钮的位置点击主播首页
@@ -488,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)
@@ -568,17 +569,17 @@ class ScriptManager():
time.sleep(3)
while not event.is_set():
- # try:
+ try:
# 调用检测消息的方法
- self.monitorMessages(session, udid)
- # except Exception as e:
- # LogManager.method_error(f"监控消息 出现异常: {e},重新启动监控直播", "检测消息", udid)
- # # 出现异常时,稍等再重启 TikTok 并重试
- # ControlUtils.closeTikTok(session, udid)
- # time.sleep(2)
- # ControlUtils.openTikTok(session, udid)
- # time.sleep(3)
- # continue # 重新进入 while 循环,调用 monitorMessages
+ self.monitorMessages(session, udid)
+ except Exception as e:
+ LogManager.method_error(f"监控消息 出现异常: {e},重新启动监控直播", "检测消息", udid)
+ # 出现异常时,稍等再重启 TikTok 并重试
+ ControlUtils.closeTikTok(session, udid)
+ time.sleep(2)
+ ControlUtils.openTikTok(session, udid)
+ time.sleep(3)
+ continue # 重新进入 while 循环,调用 monitorMessages
# 检查未读消息并回复
def monitorMessages(self, session, udid):
@@ -740,14 +741,14 @@ class ScriptManager():
}]
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']
@@ -757,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)