diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..4cdce8a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,45 @@
+FROM python:3.11-slim
+
+ENV DEBIAN_FRONTEND=noninteractive \
+ PYTHONDONTWRITEBYTECODE=1 \
+ PYTHONUNBUFFERED=1 \
+ TZ=Asia/Shanghai
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ ca-certificates curl bash tzdata \
+ mariadb-server redis-server \
+ ffmpeg libgl1 libglib2.0-0 \
+ && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /app
+
+COPY requirements.txt /app/requirements.txt
+RUN pip install --no-cache-dir -r /app/requirements.txt
+
+COPY . /app
+
+COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
+RUN chmod +x /usr/local/bin/docker-entrypoint.sh
+
+ENV DB_HOST=127.0.0.1 \
+ DB_PORT=3306 \
+ DB_NAME=abot \
+ DB_USER=root \
+ DB_PASSWORD= \
+ REDIS_HOST=127.0.0.1 \
+ REDIS_PORT=6379 \
+ REDIS_DB=0 \
+ REDIS_PASSWORD= \
+ WECHAT_SERVER_URL=http://127.0.0.1:8059/ \
+ WECHAT_SERVER_IP=127.0.0.1 \
+ WECHAT_SERVER_PORT=8059 \
+ WECHAT_WXID= \
+ WECHAT_DEVICE_NAME=ABOTPad \
+ WECHAT_DEVICE_ID= \
+ DASHBOARD_HOST=0.0.0.0 \
+ DASHBOARD_PORT=8888
+
+EXPOSE 8888
+
+ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
+CMD ["python", "main.py"]
diff --git a/admin/dashboard/blueprints/system.py b/admin/dashboard/blueprints/system.py
index 9143834..8143323 100644
--- a/admin/dashboard/blueprints/system.py
+++ b/admin/dashboard/blueprints/system.py
@@ -20,13 +20,31 @@ APP_START_TIME = time.time()
@system_bp.route('/api_docs')
@login_required
def api_docs():
- return render_template('api_docs.html')
+ src = request.args.get('src')
+ if not src:
+ try:
+ server = current_app.dashboard_server
+ cfg = getattr(server.robot, "ipad_config", {}) or {}
+ src = cfg.get("server_url", "http://127.0.0.1:8059/")
+ except Exception:
+ src = "http://127.0.0.1:8059/"
+ return render_template('api_docs.html', src_url=src)
@system_bp.route('/system_status')
@login_required
def system_status():
- return render_template('system_status.html')
+ src = request.args.get('src')
+ if not src:
+ try:
+ server = current_app.dashboard_server
+ glances = getattr(server.robot, "config").glances if hasattr(server.robot, "config") else {}
+ host = glances.get("host", "127.0.0.1")
+ port = glances.get("port", 61208)
+ src = f"http://{host}:{port}/"
+ except Exception:
+ src = "http://127.0.0.1:61208/"
+ return render_template('system_status.html', src_url=src)
# 页面路由
diff --git a/admin/dashboard/templates/api_docs.html b/admin/dashboard/templates/api_docs.html
index 58f1c01..3af0449 100644
--- a/admin/dashboard/templates/api_docs.html
+++ b/admin/dashboard/templates/api_docs.html
@@ -9,7 +9,7 @@
接口文档
-
+
@@ -67,4 +67,4 @@
display: block;
}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/admin/dashboard/templates/system_status.html b/admin/dashboard/templates/system_status.html
index 8b70e1e..b970349 100644
--- a/admin/dashboard/templates/system_status.html
+++ b/admin/dashboard/templates/system_status.html
@@ -9,7 +9,7 @@
服务器资源监控
-
+
@@ -67,4 +67,4 @@
display: block;
}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/db/scripts/init.sql b/db/scripts/init.sql
index 6501b6f..3f8c4df 100644
--- a/db/scripts/init.sql
+++ b/db/scripts/init.sql
@@ -1,7 +1,33 @@
-- 创建数据库
CREATE DATABASE IF NOT EXISTS message_archive CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE message_archive;
-create or replace table messages
+create or replace table message_archive.forum_posts
+(
+ id int auto_increment
+ primary key,
+ tid varchar(50) not null comment '帖子ID',
+ fid int not null comment '板块ID',
+ category_name varchar(50) null comment '板块名称',
+ designation varchar(100) null comment '番号',
+ actress varchar(100) null comment '出演女优',
+ title varchar(255) not null comment '标题',
+ magnet_link text null comment '磁力链接',
+ cover_image varchar(500) null comment '封面图URL',
+ post_url varchar(255) not null comment '帖子链接',
+ publish_date varchar(20) null comment '发布时间',
+ created_at timestamp default current_timestamp() null,
+ updated_at timestamp default current_timestamp() null on update current_timestamp(),
+ constraint tid
+ unique (tid)
+);
+
+create or replace index forum_posts_designation_index
+ on message_archive.forum_posts (designation);
+
+create or replace index idx_actress
+ on message_archive.forum_posts (actress);
+
+create or replace table message_archive.messages
(
id int auto_increment comment '自增主键ID'
primary key,
@@ -19,15 +45,21 @@ create or replace table messages
comment '微信群消息存储表,记录所有群聊消息';
create or replace index idx_date_timestamp
- on messages (timestamp);
+ on message_archive.messages (timestamp);
create or replace index idx_group_timestamp
- on messages (group_id, timestamp);
+ on message_archive.messages (group_id, timestamp);
+
+create or replace index idx_message_sender
+ on message_archive.messages (sender);
create or replace index idx_message_type
- on messages (message_type);
+ on message_archive.messages (message_type);
-create or replace table speech_counts
+create or replace index messages_message_id_index
+ on message_archive.messages (message_id);
+
+create or replace table message_archive.speech_counts
(
id int auto_increment comment '自增主键ID'
primary key,
@@ -40,7 +72,7 @@ create or replace table speech_counts
)
comment '群成员每日发言统计表';
-create or replace table t_chatroom_member
+create or replace table message_archive.t_chatroom_member
(
id int auto_increment
primary key,
@@ -68,12 +100,14 @@ create or replace table t_chatroom_member
remark_quan_pin varchar(256) null comment '备注全拼',
create_time datetime default current_timestamp() not null comment '创建时间',
update_time datetime default current_timestamp() not null on update current_timestamp() comment '更新时间',
+ latest_active_time datetime null comment '最后活跃时间',
+ status tinyint default 1 null comment '1-在群里,2-已退群',
constraint idx_chatroom_member
unique (chatroom_id, wxid)
)
comment '微信群成员信息表';
-create or replace table t_chatrooms
+create or replace table message_archive.t_chatrooms
(
id int auto_increment
primary key,
@@ -96,7 +130,7 @@ create or replace table t_chatrooms
)
comment '微信群信息表';
-create or replace table t_encyclopedia_active_tasks
+create or replace table message_archive.t_encyclopedia_active_tasks
(
active_task_id int auto_increment comment '任务ID'
primary key,
@@ -113,12 +147,12 @@ create or replace table t_encyclopedia_active_tasks
comment '百科答题游戏活跃任务表';
create or replace index group_id
- on t_encyclopedia_active_tasks (group_id);
+ on message_archive.t_encyclopedia_active_tasks (group_id);
create or replace index question_id
- on t_encyclopedia_active_tasks (question_id);
+ on message_archive.t_encyclopedia_active_tasks (question_id);
-create or replace table t_encyclopedia_groups
+create or replace table message_archive.t_encyclopedia_groups
(
group_id varchar(50) not null comment '群聊ID'
primary key,
@@ -126,7 +160,7 @@ create or replace table t_encyclopedia_groups
)
comment '百科答题游戏群聊表';
-create or replace table t_encyclopedia_players
+create or replace table message_archive.t_encyclopedia_players
(
player_id varchar(50) not null comment '玩家ID(微信ID)',
group_id varchar(50) not null comment '群聊ID',
@@ -137,7 +171,7 @@ create or replace table t_encyclopedia_players
)
comment '百科答题游戏玩家表';
-create or replace table t_encyclopedia_task_history
+create or replace table message_archive.t_encyclopedia_task_history
(
history_id int auto_increment comment '历史记录ID'
primary key,
@@ -152,9 +186,9 @@ create or replace table t_encyclopedia_task_history
comment '百科答题游戏任务历史表';
create or replace index group_id
- on t_encyclopedia_task_history (group_id);
+ on message_archive.t_encyclopedia_task_history (group_id);
-create or replace table t_error_logs
+create or replace table message_archive.t_error_logs
(
id bigint auto_increment
primary key,
@@ -169,12 +203,12 @@ create or replace table t_error_logs
comment '错误日志表';
create or replace index idx_created_at
- on t_error_logs (created_at);
+ on message_archive.t_error_logs (created_at);
create or replace index idx_plugin_name
- on t_error_logs (plugin_name);
+ on message_archive.t_error_logs (plugin_name);
-create or replace table t_group_stats
+create or replace table message_archive.t_group_stats
(
id bigint auto_increment
primary key,
@@ -193,12 +227,12 @@ create or replace table t_group_stats
comment '群组使用统计表';
create or replace index idx_group_id
- on t_group_stats (group_id);
+ on message_archive.t_group_stats (group_id);
create or replace index idx_last_used_at
- on t_group_stats (last_used_at);
+ on message_archive.t_group_stats (last_used_at);
-create or replace table t_plugin_point_config
+create or replace table message_archive.t_plugin_point_config
(
id int auto_increment
primary key,
@@ -210,7 +244,7 @@ create or replace table t_plugin_point_config
unique (plugin_name)
);
-create or replace table t_plugin_stats
+create or replace table message_archive.t_plugin_stats
(
id bigint auto_increment
primary key,
@@ -231,9 +265,9 @@ create or replace table t_plugin_stats
comment '插件统计汇总表';
create or replace index idx_stat_date
- on t_plugin_stats (stat_date);
+ on message_archive.t_plugin_stats (stat_date);
-create or replace table t_point_transactions
+create or replace table message_archive.t_point_transactions
(
id int auto_increment
primary key,
@@ -246,7 +280,7 @@ create or replace table t_point_transactions
created_at timestamp default current_timestamp() null
);
-create or replace table t_prison_records
+create or replace table message_archive.t_prison_records
(
id int auto_increment
primary key,
@@ -261,7 +295,76 @@ create or replace table t_prison_records
created_at timestamp default current_timestamp() null
);
-create or replace table t_sign_history
+create or replace table message_archive.t_push_feedback
+(
+ feedback_id varchar(36) not null
+ primary key,
+ task_id varchar(36) not null,
+ user_id varchar(50) not null,
+ content text not null,
+ timestamp datetime default current_timestamp() null
+);
+
+create or replace table message_archive.t_push_previews
+(
+ preview_id varchar(36) not null
+ primary key,
+ task_id varchar(36) not null,
+ content longtext collate utf8mb4_bin not null
+ check (json_valid(`content`)),
+ recipients longtext collate utf8mb4_bin not null
+ check (json_valid(`recipients`)),
+ validation longtext collate utf8mb4_bin null
+ check (json_valid(`validation`)),
+ status enum ('sent', 'confirmed', 'modified') default 'sent' null,
+ created_at datetime default current_timestamp() null
+);
+
+create or replace table message_archive.t_push_task_logs
+(
+ log_id varchar(36) not null
+ primary key,
+ task_id varchar(36) not null,
+ action enum ('create', 'update', 'delete', 'pause', 'resume') not null,
+ user_id varchar(50) not null,
+ changes longtext collate utf8mb4_bin null
+ check (json_valid(`changes`)),
+ timestamp datetime default current_timestamp() null
+);
+
+create or replace table message_archive.t_push_tasks
+(
+ task_id varchar(36) not null
+ primary key,
+ name varchar(50) not null,
+ schedule_type enum ('once', 'recurring') not null,
+ schedule_time datetime not null,
+ recurring_interval enum ('daily', 'weekly', 'monthly') null,
+ recurring_end datetime null,
+ recurring_time time null,
+ weekly_days longtext collate utf8mb4_bin null
+ check (json_valid(`weekly_days`)),
+ monthly_day int null,
+ content_text text null,
+ content_image varchar(255) null,
+ content_link longtext collate utf8mb4_bin null
+ check (json_valid(`content_link`)),
+ content_voice varchar(255) null comment '语音消息文件路径',
+ content_video varchar(255) null comment '视频消息文件路径',
+ content_miniprogram longtext collate utf8mb4_bin null
+ check (json_valid(`content_miniprogram`)),
+ groups longtext collate utf8mb4_bin null
+ check (json_valid(`groups`)),
+ priority enum ('high', 'medium', 'low') default 'medium' null,
+ status enum ('draft', 'scheduled', 'running', 'completed', 'failed', 'paused') default 'draft' null,
+ creator_id varchar(50) not null,
+ preview_recipients longtext collate utf8mb4_bin null
+ check (json_valid(`preview_recipients`)),
+ created_at datetime default current_timestamp() null,
+ updated_at datetime default current_timestamp() null on update current_timestamp()
+);
+
+create or replace table message_archive.t_sign_history
(
id bigint auto_increment comment '历史记录ID'
primary key,
@@ -277,12 +380,12 @@ create or replace table t_sign_history
comment '用户签到历史记录表';
create or replace index idx_sign_date
- on t_sign_history (sign_date);
+ on message_archive.t_sign_history (sign_date);
create or replace index idx_user_group
- on t_sign_history (wx_id, group_id);
+ on message_archive.t_sign_history (wx_id, group_id);
-create or replace table t_sign_record
+create or replace table message_archive.t_sign_record
(
id bigint auto_increment comment '自增主键ID'
primary key,
@@ -304,7 +407,21 @@ create or replace table t_sign_record
)
comment '用户群内签到记录表';
-create or replace table t_user_points
+create or replace table message_archive.t_user_levels
+(
+ id bigint auto_increment
+ primary key,
+ user_id varchar(100) not null,
+ group_id varchar(100) not null,
+ exp bigint default 0 null,
+ level int default 1 null,
+ last_calc datetime default current_timestamp() null,
+ last_active_at datetime default current_timestamp() null,
+ constraint uniq_user_group
+ unique (user_id, group_id)
+);
+
+create or replace table message_archive.t_user_points
(
id int auto_increment
primary key,
@@ -319,7 +436,7 @@ create or replace table t_user_points
unique (user_id, group_id)
);
-create or replace table t_user_stats
+create or replace table message_archive.t_user_stats
(
id bigint auto_increment
primary key,
@@ -337,12 +454,12 @@ create or replace table t_user_stats
comment '用户使用统计表';
create or replace index idx_last_used_at
- on t_user_stats (last_used_at);
+ on message_archive.t_user_stats (last_used_at);
create or replace index idx_user_id
- on t_user_stats (user_id);
+ on message_archive.t_user_stats (user_id);
-create or replace table t_wechat_contacts
+create or replace table message_archive.t_wechat_contacts
(
id int auto_increment
primary key,
@@ -374,15 +491,71 @@ create or replace table t_wechat_contacts
)
comment '微信联系人信息表';
-create or replace table tasks
+create or replace table message_archive.t_xiuxian_clan
(
- task_id int auto_increment comment '任务ID'
+ clan_id bigint auto_increment comment '门派ID'
primary key,
- task_description varchar(255) not null comment '任务描述',
- reminder_time time not null comment '提醒时间',
- task_type enum ('single', 'recurring') default 'single' null comment '任务类型:单次或周期性',
- status enum ('pending', 'completed') default 'pending' null comment '任务状态:待办或已完成',
- created_at timestamp default current_timestamp() null comment '创建时间'
+ clan_name varchar(100) not null comment '门派名称',
+ group_id varchar(100) not null comment '所属群ID',
+ leader_user_id varchar(100) not null comment '掌门ID',
+ constraint uk_group_clan_name
+ unique (group_id, clan_name)
)
- comment '机器人定时任务表';
+ comment '门派表' collate = utf8mb4_unicode_ci;
+
+create or replace table message_archive.t_xiuxian_item
+(
+ item_id int auto_increment comment '物品ID'
+ primary key,
+ name varchar(100) not null comment '物品名称',
+ type varchar(50) not null comment '物品类型',
+ description text null comment '物品描述',
+ constraint uk_name
+ unique (name)
+)
+ comment '物品定义表' collate = utf8mb4_unicode_ci;
+
+create or replace table message_archive.t_xiuxian_player
+(
+ user_id varchar(100) not null comment '平台用户ID'
+ primary key,
+ group_id varchar(100) not null comment '主要所在群ID',
+ dao_name varchar(100) not null comment '道号',
+ realm varchar(50) default '凡人' null comment '境界',
+ spirit_root varchar(50) default '凡灵根' null comment '灵根天赋',
+ clan_id bigint null comment '所属门派ID',
+ cultivation_points bigint default 0 null comment '修为',
+ spirit_stone bigint default 0 null comment '灵石',
+ status varchar(20) default 'Idle' null comment '玩家状态',
+ status_until datetime null comment '状态到期时间',
+ last_cultivate_time datetime null comment '上次闭关开始时间',
+ constraint fk_clan_id
+ foreign key (clan_id) references message_archive.t_xiuxian_clan (clan_id)
+ on delete set null
+)
+ comment '玩家核心数据表' collate = utf8mb4_unicode_ci;
+
+create or replace table message_archive.t_xiuxian_inventory
+(
+ id bigint auto_increment comment '背包条目ID'
+ primary key,
+ user_id varchar(100) not null comment '玩家ID',
+ item_id int not null comment '物品ID',
+ quantity int default 0 not null comment '数量',
+ constraint uk_user_item
+ unique (user_id, item_id),
+ constraint fk_inv_item
+ foreign key (item_id) references message_archive.t_xiuxian_item (item_id)
+ on delete cascade,
+ constraint fk_inv_user
+ foreign key (user_id) references message_archive.t_xiuxian_player (user_id)
+ on delete cascade
+)
+ comment '玩家背包表' collate = utf8mb4_unicode_ci;
+
+create or replace index idx_clan_id
+ on message_archive.t_xiuxian_player (clan_id);
+
+create or replace index idx_realm
+ on message_archive.t_xiuxian_player (realm);
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
new file mode 100644
index 0000000..f92d04c
--- /dev/null
+++ b/docker-entrypoint.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+mkdir -p /app/logs
+
+if [ ! -f /app/config.yaml ]; then
+ cat > /app/config.yaml < /app/wechat_ipad/config.toml </dev/null
+fi
+
+service mariadb start
+service redis-server start
+
+mysql -uroot -e "CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
+
+exec "$@"
diff --git a/test/douyu.py b/test/douyu.py
index 7d692ca..ddab968 100644
--- a/test/douyu.py
+++ b/test/douyu.py
@@ -2,7 +2,7 @@ import requests
import time
# 配置信息
-ROOM_ID = "52876"
+ROOM_ID = "7718843"
CHECK_INTERVAL = 300 # 5分钟 = 300秒
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",