2025-08-01 13:43:51 +08:00
|
|
|
|
import json
|
|
|
|
|
|
import os
|
|
|
|
|
|
import socket
|
|
|
|
|
|
import threading
|
2025-09-08 21:42:09 +08:00
|
|
|
|
from pathlib import Path
|
2025-08-01 13:43:51 +08:00
|
|
|
|
from queue import Queue
|
2025-08-08 22:08:10 +08:00
|
|
|
|
from typing import Any, Dict
|
2025-09-05 16:32:27 +08:00
|
|
|
|
|
|
|
|
|
|
from Entity.AnchorModel import AnchorModel
|
2025-08-14 14:30:36 +08:00
|
|
|
|
from Utils.AiUtils import AiUtils
|
2025-08-20 13:48:32 +08:00
|
|
|
|
from Utils.LogManager import LogManager
|
2025-08-01 13:43:51 +08:00
|
|
|
|
import tidevice
|
|
|
|
|
|
import wda
|
|
|
|
|
|
from flask import Flask, request
|
|
|
|
|
|
from flask_cors import CORS
|
|
|
|
|
|
from Entity.ResultData import ResultData
|
2025-08-08 22:08:10 +08:00
|
|
|
|
from Utils.ControlUtils import ControlUtils
|
2025-08-06 22:11:33 +08:00
|
|
|
|
from Utils.ThreadManager import ThreadManager
|
2025-08-01 13:43:51 +08:00
|
|
|
|
from script.ScriptManager import ScriptManager
|
2025-09-08 21:42:09 +08:00
|
|
|
|
from Entity.Variables import anchorList, prologueList, addModelToAnchorList, removeModelFromAnchorList
|
2025-09-05 16:32:27 +08:00
|
|
|
|
import Entity.Variables as ev
|
2025-09-08 21:42:09 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
CORS(app)
|
2025-09-08 19:16:05 +08:00
|
|
|
|
app.config['JSON_AS_ASCII'] = False # Flask jsonify 不转义中文/emoji
|
|
|
|
|
|
app.config['JSONIFY_MIMETYPE'] = "application/json; charset=utf-8"
|
2025-09-08 21:42:09 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
listData = []
|
|
|
|
|
|
dataQueue = Queue()
|
|
|
|
|
|
|
|
|
|
|
|
def start_socket_listener():
|
|
|
|
|
|
port = int(os.getenv('FLASK_COMM_PORT', 0))
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"Received port from environment: {port}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
print(f"Received port from environment: {port}")
|
|
|
|
|
|
if port <= 0:
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info("未获取到通信端口,跳过Socket监听")
|
|
|
|
|
|
print("未获取到通信端口,跳过Socket监听")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
return
|
|
|
|
|
|
try:
|
|
|
|
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
|
|
|
|
# 设置端口复用,避免端口被占用时无法绑定
|
|
|
|
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
|
|
|
|
|
|
|
|
|
|
# 尝试绑定端口
|
|
|
|
|
|
try:
|
|
|
|
|
|
s.bind(('127.0.0.1', port))
|
|
|
|
|
|
print(f"[INFO] Socket successfully bound to port {port}")
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"[INFO] Socket successfully bound to port {port}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
except Exception as bind_error:
|
2025-08-20 13:48:32 +08:00
|
|
|
|
print(f"[ERROR]端口绑定失败: {bind_error}")
|
|
|
|
|
|
LogManager.info(f"[ERROR]端口绑定失败: {bind_error}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 开始监听
|
|
|
|
|
|
s.listen()
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"[INFO] Socket listener started on port {port}, waiting for connections...")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
print(f"[INFO] Socket listener started on port {port}, waiting for connections...")
|
|
|
|
|
|
while True:
|
|
|
|
|
|
try:
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"[INFO] Waiting for a new connection on port {port}...")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
print(f"[INFO] Waiting for a new connection on port {port}...")
|
|
|
|
|
|
conn, addr = s.accept()
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"[INFO] Connection accepted from: {addr}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
print(f"[INFO] Connection accepted from: {addr}")
|
|
|
|
|
|
|
|
|
|
|
|
raw_data = conn.recv(1024).decode('utf-8').strip()
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"[INFO] Raw data received: {raw_data}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
print(f"[INFO] Raw data received: {raw_data}")
|
|
|
|
|
|
|
|
|
|
|
|
data = json.loads(raw_data)
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.info(f"[INFO] Parsed data: {data}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
print(f"[INFO] Parsed data: {data}")
|
|
|
|
|
|
dataQueue.put(data)
|
|
|
|
|
|
except Exception as conn_error:
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.error(f"[ERROR]连接处理失败: {conn_error}")
|
|
|
|
|
|
print(f"[ERROR]连接处理失败: {conn_error}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
except Exception as e:
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.error(f"[ERROR]Socket服务启动失败: {e}")
|
|
|
|
|
|
print(f"[ERROR]Socket服务启动失败: {e}")
|
2025-08-01 13:43:51 +08:00
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 在独立线程中启动Socket服务
|
|
|
|
|
|
listener_thread = threading.Thread(target=start_socket_listener, daemon=True)
|
|
|
|
|
|
listener_thread.start()
|
|
|
|
|
|
|
2025-09-05 16:32:27 +08:00
|
|
|
|
# 传递token,暂时用不到了
|
|
|
|
|
|
# @app.route('/passToken', methods=['POST'])
|
|
|
|
|
|
# def passToken():
|
|
|
|
|
|
# try:
|
|
|
|
|
|
# data = request.get_json()
|
|
|
|
|
|
# token = data['token']
|
|
|
|
|
|
# Requester.requestPrologue(token)
|
|
|
|
|
|
# return ResultData(data="").toJson()
|
|
|
|
|
|
# except Exception as e:
|
|
|
|
|
|
# print(e)
|
|
|
|
|
|
# return ResultData(data="").toJson()
|
2025-08-18 22:20:23 +08:00
|
|
|
|
|
2025-08-27 21:58:55 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 获取设备列表
|
|
|
|
|
|
@app.route('/deviceList', methods=['GET'])
|
|
|
|
|
|
def deviceList():
|
2025-08-18 22:20:23 +08:00
|
|
|
|
try:
|
|
|
|
|
|
while not dataQueue.empty():
|
|
|
|
|
|
obj = dataQueue.get()
|
|
|
|
|
|
type = obj["type"]
|
|
|
|
|
|
if type == 1:
|
|
|
|
|
|
listData.append(obj)
|
|
|
|
|
|
else:
|
|
|
|
|
|
for data in listData:
|
|
|
|
|
|
if data.get("deviceId") == obj.get("deviceId") and data.get("screenPort") == obj.get("screenPort"):
|
|
|
|
|
|
listData.remove(data)
|
|
|
|
|
|
return ResultData(data=listData).toJson()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(e)
|
2025-08-20 13:48:32 +08:00
|
|
|
|
LogManager.error("获取设备列表失败:", e)
|
2025-08-18 22:20:23 +08:00
|
|
|
|
return ResultData(data=[]).toJson()
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-27 21:58:55 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 获取设备应用列表
|
|
|
|
|
|
@app.route('/deviceAppList', methods=['POST'])
|
|
|
|
|
|
def deviceAppList():
|
|
|
|
|
|
param = request.get_json()
|
|
|
|
|
|
udid = param["udid"]
|
2025-08-08 22:08:10 +08:00
|
|
|
|
apps = ControlUtils.getDeviceAppList(udid)
|
|
|
|
|
|
return ResultData(data=apps).toJson()
|
2025-08-01 13:43:51 +08:00
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-05 15:41:20 +08:00
|
|
|
|
# 打开指定app
|
2025-08-01 13:43:51 +08:00
|
|
|
|
@app.route('/launchApp', methods=['POST'])
|
|
|
|
|
|
def launchApp():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
bundleId = body.get("bundleId")
|
|
|
|
|
|
t = tidevice.Device(udid)
|
|
|
|
|
|
t.app_start(bundleId)
|
|
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 回到首页
|
|
|
|
|
|
@app.route('/toHome', methods=['POST'])
|
|
|
|
|
|
def toHome():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
client = wda.USBClient(udid)
|
|
|
|
|
|
client.home()
|
|
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 点击事件
|
|
|
|
|
|
@app.route('/tapAction', methods=['POST'])
|
|
|
|
|
|
def tapAction():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
client = wda.USBClient(udid)
|
|
|
|
|
|
session = client.session()
|
|
|
|
|
|
session.appium_settings({"snapshotMaxDepth": 0})
|
2025-08-14 13:49:28 +08:00
|
|
|
|
x = body.get("x")
|
|
|
|
|
|
y = body.get("y")
|
|
|
|
|
|
session.tap(x, y)
|
2025-08-01 13:43:51 +08:00
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 拖拽事件
|
|
|
|
|
|
@app.route('/swipeAction', methods=['POST'])
|
|
|
|
|
|
def swipeAction():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
direction = body.get("direction")
|
|
|
|
|
|
client = wda.USBClient(udid)
|
|
|
|
|
|
session = client.session()
|
|
|
|
|
|
session.appium_settings({"snapshotMaxDepth": 0})
|
|
|
|
|
|
|
|
|
|
|
|
if direction == 1:
|
|
|
|
|
|
session.swipe_up()
|
|
|
|
|
|
elif direction == 2:
|
|
|
|
|
|
session.swipe_left()
|
|
|
|
|
|
elif direction == 3:
|
|
|
|
|
|
session.swipe_down()
|
|
|
|
|
|
else:
|
|
|
|
|
|
session.swipe_right()
|
|
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 长按事件
|
|
|
|
|
|
@app.route('/longPressAction', methods=['POST'])
|
|
|
|
|
|
def longPressAction():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
x = body.get("x")
|
|
|
|
|
|
y = body.get("y")
|
|
|
|
|
|
client = wda.USBClient(udid)
|
|
|
|
|
|
session = client.session()
|
|
|
|
|
|
session.appium_settings({"snapshotMaxDepth": 5})
|
2025-08-14 15:40:17 +08:00
|
|
|
|
session.tap_hold(x, y, 1.0)
|
2025-08-01 13:43:51 +08:00
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 养号
|
|
|
|
|
|
@app.route('/growAccount', methods=['POST'])
|
|
|
|
|
|
def growAccount():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
|
2025-08-06 22:11:33 +08:00
|
|
|
|
manager = ScriptManager()
|
|
|
|
|
|
event = threading.Event()
|
2025-08-01 13:43:51 +08:00
|
|
|
|
# 启动脚本
|
2025-08-14 15:40:17 +08:00
|
|
|
|
thread = threading.Thread(target=manager.growAccount, args=(udid, event))
|
2025-08-06 22:11:33 +08:00
|
|
|
|
thread.start()
|
|
|
|
|
|
# 添加到线程管理
|
|
|
|
|
|
ThreadManager.add(udid, thread, event)
|
2025-08-01 13:43:51 +08:00
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-11 22:06:48 +08:00
|
|
|
|
# 观看直播
|
|
|
|
|
|
@app.route("/watchLiveForGrowth", methods=['POST'])
|
|
|
|
|
|
def watchLiveForGrowth():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
manager = ScriptManager()
|
|
|
|
|
|
event = threading.Event()
|
|
|
|
|
|
thread = threading.Thread(target=manager.watchLiveForGrowth, args=(udid, event))
|
|
|
|
|
|
thread.start()
|
|
|
|
|
|
# 添加到线程管理
|
|
|
|
|
|
ThreadManager.add(udid, thread, event)
|
|
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-06 22:11:33 +08:00
|
|
|
|
# 停止脚本
|
|
|
|
|
|
@app.route("/stopScript", methods=['POST'])
|
|
|
|
|
|
def stopScript():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
2025-08-14 14:46:52 +08:00
|
|
|
|
code, msg = ThreadManager.stop(udid)
|
|
|
|
|
|
return ResultData(code=code, data="", msg=msg).toJson()
|
2025-08-06 22:11:33 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-09-08 21:42:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 关注打招呼
|
2025-08-08 22:08:10 +08:00
|
|
|
|
@app.route('/passAnchorData', methods=['POST'])
|
|
|
|
|
|
def passAnchorData():
|
2025-09-08 21:42:09 +08:00
|
|
|
|
try:
|
|
|
|
|
|
data: Dict[str, Any] = request.get_json()
|
|
|
|
|
|
# 设备列表
|
|
|
|
|
|
idList = data.get("deviceList", [])
|
|
|
|
|
|
# 主播列表
|
|
|
|
|
|
acList = data.get("anchorList", [])
|
|
|
|
|
|
AiUtils.save_aclist_flat_append(acList)
|
|
|
|
|
|
|
|
|
|
|
|
# 是否需要回复
|
|
|
|
|
|
needReply = data.get("needReply", True)
|
|
|
|
|
|
# 获取打招呼数据
|
|
|
|
|
|
ev.prologueList = data.get("prologueList", [])
|
|
|
|
|
|
|
|
|
|
|
|
# 添加主播数据
|
|
|
|
|
|
addModelToAnchorList(acList)
|
|
|
|
|
|
# 启动线程,执行脚本
|
|
|
|
|
|
for udid in idList:
|
|
|
|
|
|
manager = ScriptManager()
|
|
|
|
|
|
event = threading.Event()
|
|
|
|
|
|
# 启动脚本
|
|
|
|
|
|
thread = threading.Thread(target=manager.safe_greetNewFollowers, args=(udid, needReply, event))
|
|
|
|
|
|
thread.start()
|
|
|
|
|
|
# 添加到线程管理
|
|
|
|
|
|
ThreadManager.add(udid, thread, event)
|
|
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
LogManager.error(e)
|
2025-08-08 22:08:10 +08:00
|
|
|
|
|
2025-09-05 16:32:27 +08:00
|
|
|
|
# 获取私信数据
|
|
|
|
|
|
@app.route("/getPrologueList", methods=['GET'])
|
|
|
|
|
|
def getPrologueList():
|
2025-09-08 21:42:09 +08:00
|
|
|
|
import Entity.Variables as Variables
|
|
|
|
|
|
return ResultData(data=Variables.prologueList).toJson()
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-08 22:08:10 +08:00
|
|
|
|
# 添加临时数据
|
2025-09-08 21:42:09 +08:00
|
|
|
|
# 批量追加主播到 JSON 文件
|
2025-08-08 22:08:10 +08:00
|
|
|
|
@app.route("/addTempAnchorData", methods=['POST'])
|
|
|
|
|
|
def addTempAnchorData():
|
2025-09-08 21:42:09 +08:00
|
|
|
|
"""
|
|
|
|
|
|
请求体支持:
|
|
|
|
|
|
- 单个对象:{"anchorId": "xxx", "country": "CN"}
|
|
|
|
|
|
- 对象数组:[{"anchorId": "xxx", "country": "CN"}, {"anchorId": "yyy", "country": "US"}]
|
|
|
|
|
|
"""
|
2025-08-08 22:08:10 +08:00
|
|
|
|
data = request.get_json()
|
2025-09-08 21:42:09 +08:00
|
|
|
|
if not data:
|
|
|
|
|
|
return ResultData(code=400, msg="请求数据为空").toJson()
|
|
|
|
|
|
# 追加到 JSON 文件
|
|
|
|
|
|
AiUtils.save_aclist_flat_append(data, "log/acList.json")
|
|
|
|
|
|
return ResultData(data="ok").toJson()
|
2025-08-06 22:11:33 +08:00
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
2025-08-14 14:30:36 +08:00
|
|
|
|
# 获取当前屏幕上的聊天信息
|
|
|
|
|
|
@app.route("/getChatTextInfo", methods=['POST'])
|
|
|
|
|
|
def getChatTextInfo():
|
|
|
|
|
|
data = request.get_json()
|
|
|
|
|
|
udid = data.get("udid")
|
|
|
|
|
|
client = wda.USBClient(udid)
|
|
|
|
|
|
session = client.session()
|
|
|
|
|
|
xml = session.source()
|
2025-08-27 21:58:55 +08:00
|
|
|
|
try:
|
|
|
|
|
|
result = AiUtils.extract_messages_from_xml(xml)
|
|
|
|
|
|
print(result)
|
|
|
|
|
|
return ResultData(data=result).toJson()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
data = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'type': 'msg',
|
|
|
|
|
|
'dir': 'in',
|
|
|
|
|
|
'text': '当前页面无法获取聊天记录,请在tiktok聊天页面进行获取!!!'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'type': 'msg',
|
|
|
|
|
|
'dir': 'in',
|
|
|
|
|
|
'text': 'Unable to retrieve chat messages on the current screen. Please navigate to the TikTok chat page and try again!!!'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
return ResultData(data=data, msg="解析失败").toJson()
|
2025-08-14 14:30:36 +08:00
|
|
|
|
|
2025-08-14 15:40:17 +08:00
|
|
|
|
|
|
|
|
|
|
# 监控消息
|
|
|
|
|
|
@app.route("/replyMessages", methods=['POST'])
|
|
|
|
|
|
def monitorMessages():
|
|
|
|
|
|
body = request.get_json()
|
|
|
|
|
|
udid = body.get("udid")
|
|
|
|
|
|
manager = ScriptManager()
|
|
|
|
|
|
event = threading.Event()
|
|
|
|
|
|
thread = threading.Thread(target=manager.replyMessages, args=(udid, event))
|
|
|
|
|
|
thread.start()
|
|
|
|
|
|
# 添加到线程管理
|
|
|
|
|
|
ThreadManager.add(udid, thread, event)
|
|
|
|
|
|
return ResultData(data="").toJson()
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-04 19:35:36 +08:00
|
|
|
|
@app.route("/setLoginInfo", methods=['POST'])
|
2025-09-04 20:50:48 +08:00
|
|
|
|
def upLoadLogLogs():
|
2025-09-04 19:35:36 +08:00
|
|
|
|
data = request.get_json() # 解析 JSON
|
|
|
|
|
|
token = data.get("token")
|
|
|
|
|
|
userId = data.get("userId")
|
|
|
|
|
|
tenantId = data.get("tenantId")
|
|
|
|
|
|
ok = LogManager.upload_all_logs("http://47.79.98.113:8101/api/log/upload", token, userId, tenantId)
|
2025-09-01 21:51:36 +08:00
|
|
|
|
if ok:
|
|
|
|
|
|
return ResultData(data="日志上传成功").toJson()
|
|
|
|
|
|
else:
|
|
|
|
|
|
return ResultData(data="", msg="日志上传失败").toJson()
|
|
|
|
|
|
|
2025-09-05 16:32:27 +08:00
|
|
|
|
# 获取当前的主播列表数据
|
|
|
|
|
|
@app.route("/anchorList", methods=['POST'])
|
|
|
|
|
|
def queryAnchorList():
|
2025-09-08 21:42:09 +08:00
|
|
|
|
file_path = "log/acList.json"
|
2025-09-05 16:32:27 +08:00
|
|
|
|
data = []
|
2025-09-08 21:42:09 +08:00
|
|
|
|
if Path(file_path).exists():
|
|
|
|
|
|
try:
|
|
|
|
|
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
LogManager.error(f"[anchorList] 读取失败: {e}")
|
|
|
|
|
|
data = []
|
2025-09-05 16:32:27 +08:00
|
|
|
|
return ResultData(data=data).toJson()
|
|
|
|
|
|
|
2025-09-08 21:42:09 +08:00
|
|
|
|
|
2025-09-05 16:32:27 +08:00
|
|
|
|
# 删除主播
|
|
|
|
|
|
@app.route("/deleteAnchorWithIds", methods=['POST'])
|
|
|
|
|
|
def deleteAnchorWithIds():
|
2025-09-08 21:42:09 +08:00
|
|
|
|
ls: list[dict] = request.get_json() # [{"anchorId": "xxx"}, ...]
|
|
|
|
|
|
ids = [d.get("anchorId") for d in ls if d.get("anchorId")]
|
|
|
|
|
|
deleted = AiUtils.delete_anchors_by_ids(ids)
|
|
|
|
|
|
return ResultData(data={"deleted": deleted}).toJson()
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-01 21:51:36 +08:00
|
|
|
|
|
2025-08-01 13:43:51 +08:00
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
app.run("0.0.0.0", port=5000, debug=True, use_reloader=False)
|