码桶

发现社区成员的开源项目

奶狗 /

ng-webot

公开
main
ng-webot/lib/settings.js
settings.js1.8 KB
/**
 * 系统设置读写 — 统一从 settings 表读取/写入键值配置
 */
const db = require('./db');

let _cache = {};
let _expire = {};

// 缓存有效期(毫秒),避免每个请求都查库
const TTL = 30 * 1000;

/**
 * 读取设置;命中缓存且未过期时直接返回
 * @param {string} key 设置键
 * @param {string} def 默认值(库里无值或为空时返回)
 * @param {boolean} force 是否强制读库(忽略缓存)
 */
async function getSetting(key, def = '', force = false) {
  const now = Date.now();
  if (!force && _cache[key] !== undefined && _expire[key] > now) {
    return _cache[key];
  }
  let val = def;
  try {
    const row = await db.row('SELECT value FROM settings WHERE key = ?', [key]);
    if (row && row.value !== null && row.value !== undefined && row.value !== '') {
      val = row.value;
    }
  } catch (e) {
    val = def;
  }
  _cache[key] = val;
  _expire[key] = now + TTL;
  return val;
}

/**
 * 获取管理员后台入口路径(去掉首尾斜杠,仅允许字母数字_-,为空则默认 admin)
 */
async function getAdminEntry(force = false) {
  let e = await getSetting('admin_entry', 'admin', force);
  e = (e || '').toString().trim().replace(/^\/+|\/+$/g, '');
  e = e.replace(/[^a-zA-Z0-9_-]/g, '');
  return e || 'admin';
}

/**
 * 写入设置(并清缓存)
 */
async function setSetting(key, val) {
  try {
    await db.exec(
      "INSERT INTO settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value",
      [key, String(val)]
    );
    // 仅写入成功时清除缓存
    delete _cache[key];
    delete _expire[key];
  } catch (e) {
    console.error('[settings] 写入失败:', e.message);
  }
}

module.exports = { getSetting, getAdminEntry, setSetting };