Files
zsglpt/database.py
yuyx 30b6e3144b fix: database.py 添加缺失的 kdocs_row_start/row_end 参数
修复保存金山文档配置时报 500 错误的问题

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 01:03:19 +08:00

242 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据库模块(稳定 API 门面)- SQLite
P2 / O-07拆分 `database.py` 为稳定门面 + `db/` 分域实现。
约束:
- 外部仍通过 `import database` 调用(函数名/参数/返回结构保持不变)
- schema/migration 入口统一,避免 scattered ALTER TABLE
"""
from __future__ import annotations
import os
import threading
import time
from typing import Optional
import db_pool
from app_config import get_config
from db.schema import ensure_schema
from db.migrations import migrate_database as _migrate_database
from db.admin import (
admin_reset_user_password,
clean_old_operation_logs,
ensure_default_admin,
get_hourly_registration_count,
get_system_config_raw as _get_system_config_raw,
get_system_stats,
update_admin_password,
update_admin_username,
update_system_config as _update_system_config,
verify_admin,
)
from db.accounts import (
create_account,
delete_account,
delete_user_accounts,
get_account,
get_account_status,
get_account_status_batch,
get_user_accounts,
increment_account_login_fail,
reset_account_login_status,
update_account_remark,
)
from db.announcements import (
create_announcement,
delete_announcement,
dismiss_announcement_for_user,
get_active_announcement_for_user,
get_announcement_by_id,
get_announcements,
set_announcement_active,
)
from db.email import (
get_user_by_email,
get_user_email_notify,
update_user_email,
update_user_email_notify,
)
from db.feedbacks import (
close_feedback,
create_bug_feedback,
delete_feedback,
get_bug_feedbacks,
get_feedback_by_id,
get_feedback_stats,
get_user_feedbacks,
reply_feedback,
)
from db.schedules import (
clean_old_schedule_logs,
create_schedule_execution_log,
create_user_schedule,
delete_schedule_logs,
delete_user_schedule,
get_due_user_schedules,
get_enabled_user_schedules,
get_schedule_by_id,
get_schedule_execution_logs,
get_user_all_schedule_logs,
get_user_schedules,
recompute_schedule_next_run,
toggle_user_schedule,
update_schedule_next_run,
update_schedule_execution_log,
update_schedule_last_run,
update_user_schedule,
)
from db.tasks import create_task_log, delete_old_task_logs, get_task_logs, get_task_stats, get_user_run_stats
from db.users import (
approve_user,
create_user,
delete_user,
extend_user_vip,
get_all_users,
get_pending_users,
get_user_by_id,
get_user_by_username,
get_user_kdocs_settings,
get_user_stats,
get_user_vip_info,
get_vip_config,
is_user_vip,
reject_user,
remove_user_vip,
set_default_vip_days,
set_user_vip,
update_user_kdocs_settings,
verify_user,
)
from db.security import record_login_context
config = get_config()
# 数据库文件路径
DB_FILE = config.DB_FILE
# 数据库版本 (用于迁移管理)
DB_VERSION = 17
# ==================== 系统配置缓存P1 / O-03 ====================
_system_config_cache_lock = threading.Lock()
_system_config_cache_value: Optional[dict] = None
_system_config_cache_loaded_at = 0.0
try:
_SYSTEM_CONFIG_CACHE_TTL_SECONDS = float(os.environ.get("SYSTEM_CONFIG_CACHE_TTL_SECONDS", "3"))
except Exception:
_SYSTEM_CONFIG_CACHE_TTL_SECONDS = 3.0
_SYSTEM_CONFIG_CACHE_TTL_SECONDS = max(0.0, _SYSTEM_CONFIG_CACHE_TTL_SECONDS)
def invalidate_system_config_cache() -> None:
global _system_config_cache_value, _system_config_cache_loaded_at
with _system_config_cache_lock:
_system_config_cache_value = None
_system_config_cache_loaded_at = 0.0
def init_database():
"""初始化数据库表结构 + 迁移(入口统一)。"""
db_pool.init_pool(DB_FILE, pool_size=config.DB_POOL_SIZE)
with db_pool.get_db() as conn:
ensure_schema(conn)
_migrate_database(conn, DB_VERSION)
ensure_default_admin()
def migrate_database():
"""数据库迁移(对外保留接口)。"""
with db_pool.get_db() as conn:
ensure_schema(conn)
_migrate_database(conn, DB_VERSION)
# ==================== 系统配置管理(缓存门面) ====================
def get_system_config():
"""获取系统配置(带进程内缓存)。"""
global _system_config_cache_value, _system_config_cache_loaded_at
now_ts = time.time()
with _system_config_cache_lock:
if _system_config_cache_value is not None:
if _SYSTEM_CONFIG_CACHE_TTL_SECONDS <= 0 or (now_ts - _system_config_cache_loaded_at) < _SYSTEM_CONFIG_CACHE_TTL_SECONDS:
return dict(_system_config_cache_value)
value = _get_system_config_raw()
with _system_config_cache_lock:
_system_config_cache_value = dict(value)
_system_config_cache_loaded_at = now_ts
return dict(value)
def update_system_config(
max_concurrent=None,
schedule_enabled=None,
schedule_time=None,
schedule_browse_type=None,
schedule_weekdays=None,
max_concurrent_per_account=None,
max_screenshot_concurrent=None,
enable_screenshot=None,
proxy_enabled=None,
proxy_api_url=None,
proxy_expire_minutes=None,
auto_approve_enabled=None,
auto_approve_hourly_limit=None,
auto_approve_vip_days=None,
kdocs_enabled=None,
kdocs_doc_url=None,
kdocs_default_unit=None,
kdocs_sheet_name=None,
kdocs_sheet_index=None,
kdocs_unit_column=None,
kdocs_image_column=None,
kdocs_admin_notify_enabled=None,
kdocs_admin_notify_email=None,
kdocs_row_start=None,
kdocs_row_end=None,
):
"""更新系统配置(写入后立即失效缓存)。"""
ok = _update_system_config(
max_concurrent=max_concurrent,
schedule_enabled=schedule_enabled,
schedule_time=schedule_time,
schedule_browse_type=schedule_browse_type,
schedule_weekdays=schedule_weekdays,
max_concurrent_per_account=max_concurrent_per_account,
max_screenshot_concurrent=max_screenshot_concurrent,
enable_screenshot=enable_screenshot,
proxy_enabled=proxy_enabled,
proxy_api_url=proxy_api_url,
proxy_expire_minutes=proxy_expire_minutes,
auto_approve_enabled=auto_approve_enabled,
auto_approve_hourly_limit=auto_approve_hourly_limit,
auto_approve_vip_days=auto_approve_vip_days,
kdocs_enabled=kdocs_enabled,
kdocs_doc_url=kdocs_doc_url,
kdocs_default_unit=kdocs_default_unit,
kdocs_sheet_name=kdocs_sheet_name,
kdocs_sheet_index=kdocs_sheet_index,
kdocs_unit_column=kdocs_unit_column,
kdocs_image_column=kdocs_image_column,
kdocs_admin_notify_enabled=kdocs_admin_notify_enabled,
kdocs_admin_notify_email=kdocs_admin_notify_email,
kdocs_row_start=kdocs_row_start,
kdocs_row_end=kdocs_row_end,
)
if ok:
invalidate_system_config_cache()
return ok