合并代码

This commit is contained in:
2025-09-11 22:49:08 +08:00
9 changed files with 201 additions and 24 deletions

2
.idea/iOSAI.iml generated
View File

@@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.12 (IOS-AI)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="Black">
<option name="sdkName" value="Python 3.12" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (IOS-AI)" project-jdk-type="Python SDK" />
</project>

View File

@@ -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)

View File

@@ -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

View File

@@ -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) # ③ 解锁

View File

@@ -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"

View File

@@ -1,6 +0,0 @@
{
"agentName": "小花",
"guildName": "牛逼工会",
"contactTool": "line",
"contact": "7788990"
}

BIN
resources/FlashLink.exe Normal file

Binary file not shown.

View File

@@ -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)