Compare commits

...

3 Commits

Author SHA1 Message Date
c1cf6c04e2 20250911-初步功能已完成 2025-09-11 22:39:57 +08:00
19780a8a85 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.idea/workspace.xml
2025-09-11 21:15:19 +08:00
7e7d183f5f 20250911-初步功能已完成 2025-09-11 21:14:57 +08:00
10 changed files with 266 additions and 53 deletions

2
.idea/iOSAI.iml generated
View File

@@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" /> <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" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="Black"> <component name="Black">
<option name="sdkName" value="Python 3.12" /> <option name="sdkName" value="Python 3.12" />
</component> </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> </project>

94
.idea/workspace.xml generated
View File

@@ -5,8 +5,14 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="eceeff5e-51c1-459c-a911-d21ec090a423" name="Changes" comment="20250904-初步功能已完成"> <list default="true" id="eceeff5e-51c1-459c-a911-d21ec090a423" name="Changes" comment="20250904-初步功能已完成">
<change afterPath="$PROJECT_DIR$/resources/516d237878617fae4bfb5bc5322a8fe3ad0b2761/bgv.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/resources/FlashLink.exe" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/iOSAI.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/iOSAI.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Utils/JsonUtils.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/JsonUtils.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Utils/Requester.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/Requester.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Utils/Requester.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/Requester.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/script/ScriptManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/script/ScriptManager.py" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -49,31 +55,35 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;ASKED_ADD_EXTERNAL_FILES&quot;: &quot;true&quot;, "ASKED_ADD_EXTERNAL_FILES": "true",
&quot;Python.12.executor&quot;: &quot;Run&quot;, "Python.12.executor": "Run",
&quot;Python.123.executor&quot;: &quot;Run&quot;, "Python.123 (1).executor": "Run",
&quot;Python.Main.executor&quot;: &quot;Run&quot;, "Python.123.executor": "Run",
&quot;Python.tidevice_entry.executor&quot;: &quot;Run&quot;, "Python.Main.executor": "Run",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "Python.tidevice_entry.executor": "Run",
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;git-widget-placeholder&quot;: &quot;main&quot;, "SHARE_PROJECT_CONFIGURATION_FILES": "true",
&quot;javascript.nodejs.core.library.configured.version&quot;: &quot;20.17.0&quot;, "git-widget-placeholder": "main",
&quot;javascript.nodejs.core.library.typings.version&quot;: &quot;20.17.58&quot;, "javascript.nodejs.core.library.configured.version": "20.17.0",
&quot;last_opened_file_path&quot;: &quot;F:/company code/AI item/20250820/iOSAI&quot;, "javascript.nodejs.core.library.typings.version": "20.17.58",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "last_opened_file_path": "F:/company code/AI item/20250820/iOSAI/resources",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.editor.code.editing&quot;, "nodejs_package_manager_path": "npm",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "settings.editor.selected.configurable": "preferences.editor.code.editing",
"vue.rearranger.settings.migration": "true"
} }
}</component> }]]></component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="F:\company code\AI item\20250820\iOSAI\resources" />
</key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="E:\Code\python\iOSAI\resources" /> <recent name="E:\Code\python\iOSAI\resources" />
<recent name="E:\Code\python\iOSAI" /> <recent name="E:\Code\python\iOSAI" />
@@ -118,6 +128,29 @@
<option name="INPUT_FILE" value="" /> <option name="INPUT_FILE" value="" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="123 (1)" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="iOSAI" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/Module" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Module/123.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="123" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> <configuration name="123" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="iOSAI" /> <module name="iOSAI" />
<option name="ENV_FILES" value="" /> <option name="ENV_FILES" value="" />
@@ -166,6 +199,7 @@
</configuration> </configuration>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Python.123 (1)" />
<item itemvalue="Python.12" /> <item itemvalue="Python.12" />
<item itemvalue="Python.123" /> <item itemvalue="Python.123" />
</list> </list>
@@ -304,19 +338,21 @@
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" /> <option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="ai 开始测试" /> <MESSAGE value="ai 开始测试" />
<MESSAGE value="20250904-初步功能已完成" /> <MESSAGE value="20250904-初步功能已完成" />
<option name="LAST_COMMIT_MESSAGE" value="20250904-初步功能已完成" /> <MESSAGE value="20250911-初步功能已完成" />
<option name="LAST_COMMIT_MESSAGE" value="20250911-初步功能已完成" />
</component> </component>
<component name="com.intellij.coverage.CoverageDataManagerImpl"> <component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/iOSAI$LogManager.coverage" NAME="LogManager 覆盖结果" MODIFIED="1756711414832" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/Utils" /> <SUITE FILE_PATH="coverage/iOSAI$LogManager.coverage" NAME="LogManager 覆盖结果" MODIFIED="1756711414832" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/Utils" />
<SUITE FILE_PATH="coverage/iOSAI$123__1_.coverage" NAME="123 (1) 覆盖结果" MODIFIED="1756897091135" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$FlaskService.coverage" NAME="FlaskService 覆盖结果" MODIFIED="1756730187792" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/Module" /> <SUITE FILE_PATH="coverage/iOSAI$FlaskService.coverage" NAME="FlaskService 覆盖结果" MODIFIED="1756730187792" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/Module" />
<SUITE FILE_PATH="coverage/iOSAI$test.coverage" NAME="test 覆盖结果" MODIFIED="1756467664420" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> <SUITE FILE_PATH="coverage/iOSAI$test.coverage" NAME="test 覆盖结果" MODIFIED="1756467664420" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$windows_run.coverage" NAME="windows_run Coverage Results" MODIFIED="1756473558532" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" /> <SUITE FILE_PATH="coverage/iOSAI$windows_run.coverage" NAME="windows_run Coverage Results" MODIFIED="1756473558532" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" />
<SUITE FILE_PATH="coverage/iOSAI$tidevice_entry.coverage" NAME="tidevice_entry 覆盖结果" MODIFIED="1757061969626" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$mac_wda_agent.coverage" NAME="mac_wda_agent Coverage Results" MODIFIED="1756473148639" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" /> <SUITE FILE_PATH="coverage/iOSAI$mac_wda_agent.coverage" NAME="mac_wda_agent Coverage Results" MODIFIED="1756473148639" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" />
<SUITE FILE_PATH="coverage/iOSAI$ScriptManager.coverage" NAME="ScriptManager 覆盖结果" MODIFIED="1756896057801" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" />
<SUITE FILE_PATH="coverage/iOSAI$Main.coverage" NAME="Main 覆盖结果" MODIFIED="1757579400023" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
<SUITE FILE_PATH="coverage/iOSAI$123.coverage" NAME="123 覆盖结果" MODIFIED="1757587713569" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$2111.coverage" NAME="2111 覆盖结果" MODIFIED="1757330714370" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> <SUITE FILE_PATH="coverage/iOSAI$2111.coverage" NAME="2111 覆盖结果" MODIFIED="1757330714370" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$12.coverage" NAME="12 覆盖结果" MODIFIED="1757588112167" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$123__1_.coverage" NAME="123 (1) 覆盖结果" MODIFIED="1757597330034" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/Module" />
<SUITE FILE_PATH="coverage/iOSAI$tidevice_entry.coverage" NAME="tidevice_entry 覆盖结果" MODIFIED="1757061969626" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/iOSAI$ScriptManager.coverage" NAME="ScriptManager 覆盖结果" MODIFIED="1756896057801" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/script" />
<SUITE FILE_PATH="coverage/iOSAI$Main.coverage" NAME="Main 覆盖结果" MODIFIED="1757600791452" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
<SUITE FILE_PATH="coverage/iOSAI$123.coverage" NAME="123 覆盖结果" MODIFIED="1757594119268" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component> </component>
</project> </project>

View File

@@ -384,5 +384,48 @@ def aiConfig():
JsonUtils.write_json("aiConfig", dict) JsonUtils.write_json("aiConfig", dict)
return ResultData(data="").toJson() 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__': if __name__ == '__main__':
app.run("0.0.0.0", port=5000, debug=True, use_reloader=False) 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) json.dump(data, f, ensure_ascii=False, indent=2)
except Exception as e: except Exception as e:
LogManager.error(f"[delete_anchors_by_ids] 写入失败: {e}") LogManager.error(f"[delete_anchors_by_ids] 写入失败: {e}")
return deleted return deleted

View File

@@ -2,6 +2,9 @@ import os
import json import json
from pathlib import Path from pathlib import Path
from Utils.LogManager import LogManager
from pathlib import Path
import portalocker as locker # ① 引入跨平台锁
class JsonUtils: class JsonUtils:
@staticmethod @staticmethod
@@ -98,3 +101,123 @@ class JsonUtils:
except Exception as e: except Exception as e:
print(f"删除 JSON key 失败: {e}") print(f"删除 JSON key 失败: {e}")
return False 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", "") contactTool = aiConfig.get("contactTool", "")
contact = aiConfig.get("contact", "") contact = aiConfig.get("contact", "")
param["agentName"] = agentName inputs = {
param["guildName"] = guildName "agentName":agentName,
param["contactTool"] = contactTool "guildName":guildName,
param["contact"] = contact "contactTool":contactTool,
"contact":contact
}
param["inputs"] = inputs
try: try:
url = "https://ai.yolozs.com/chat" 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 import os
from Utils.AiUtils import AiUtils from Utils.AiUtils import AiUtils
from Utils.ControlUtils import ControlUtils from Utils.ControlUtils import ControlUtils
from Utils.JsonUtils import JsonUtils
from Utils.LogManager import LogManager from Utils.LogManager import LogManager
from Entity.Variables import anchorList, removeModelFromAnchorList, anchorWithSession from Entity.Variables import anchorList, removeModelFromAnchorList, anchorWithSession
from Utils.Requester import Requester from Utils.Requester import Requester
@@ -321,9 +322,9 @@ class ScriptManager():
ControlUtils.clickBack(session) ControlUtils.clickBack(session)
time.sleep(2) time.sleep(2)
print("循环条件1", not event.is_set()) LogManager.method_info(f"循环条件1:{not event.is_set()}", "关注打招呼", udid)
print("循环条件2", len(anchorList) > 0) LogManager.method_info(f"循环条件2:{len(anchorList) > 0}", "关注打招呼", udid)
print("循环条件", not event.is_set() and len(anchorList) > 0) LogManager.method_info(f"循环条件3:{not event.is_set() and len(anchorList) > 0}", "关注打招呼", udid)
# 循环条件。1、 循环关闭 2、 数据处理完毕 # 循环条件。1、 循环关闭 2、 数据处理完毕
while not event.is_set(): while not event.is_set():
@@ -358,7 +359,7 @@ class ScriptManager():
input.clear_text() input.clear_text()
time.sleep(1) time.sleep(1)
# 输入主播id # 输入主播id
input.set_text(aid + "\n") input.set_text(f"{aid or '暂无数据'}\n")
# 定位 "关注" 按钮 通过关注按钮的位置点击主播首页 # 定位 "关注" 按钮 通过关注按钮的位置点击主播首页
@@ -487,11 +488,12 @@ class ScriptManager():
chatInput.click() chatInput.click()
time.sleep(2) 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) time.sleep(1)
else: else:
print("无法发送信息") print("无法发送信息")
LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid) LogManager.method_info(f"给主播{aid} 发送消息失败", "关注打招呼", udid)
@@ -731,12 +733,22 @@ class ScriptManager():
LogManager.method_info(f"获取主播的名称:{anchor_name}", "检测消息", udid) 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") sel = session.xpath("//TextView")
if anchor_name not in anchorWithSession: if anchor_name not in anchorWithSession:
# 如果是第一次发消息(没有sessionId的情况) # 如果是第一次发消息(没有sessionId的情况)
response = Requester.chatToAi({"msg": last_msg_text})
response = Requester.chatToAi({"query": last_msg_text})
aiResult = response['result'] aiResult = response['result']
sessionId = response['session_id'] sessionId = response['session_id']
@@ -746,20 +758,21 @@ class ScriptManager():
sel.click() # 聚焦 sel.click() # 聚焦
time.sleep(1) time.sleep(1)
sel.clear_text() sel.clear_text()
sel.set_text(aiResult + "\n") sel.set_text(f"{aiResult or '暂无数据'}\n")
else: else:
LogManager.method_error("找不到输入框,重启", "检测消息", udid) LogManager.method_error("找不到输入框,重启", "检测消息", udid)
raise Exception("找不到输入框,重启") raise Exception("找不到输入框,重启")
else: else:
# 如果不是第一次发消息证明存储的有sessionId # 如果不是第一次发消息证明存储的有sessionId
sessionId = anchorWithSession[anchor_name] 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'] aiResult = response['result']
if sel.exists: if sel.exists:
sel.click() # 聚焦 sel.click() # 聚焦
time.sleep(1) time.sleep(1)
sel.clear_text() sel.clear_text()
sel.set_text(aiResult + "\n") sel.set_text(f"{aiResult or '暂无数据'}\n")
LogManager.method_info(f"存储的sessionId:{anchorWithSession}", "检测消息", udid) LogManager.method_info(f"存储的sessionId:{anchorWithSession}", "检测消息", udid)
time.sleep(1) time.sleep(1)