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