refactor: 枚举移入Models目录,命名空间更新为Rainbow.Entity.Models
大石头 authored at 2026-07-02 12:54:58
3.66 KiB
RainbowBridge
using Microsoft.AspNetCore.Mvc;
using NewLife;
using Rainbow.Entity;
using Rainbow.Services;

namespace Rainbow.Web.Controllers;

/// <summary>DNS 规则管理 API</summary>
[ApiController]
[Route("api/dns")]
public class DnsController : ControllerBase
{
    private readonly DnsmasqManager _dnsmasqManager;

    /// <summary>构造 DNS 控制器</summary>
    /// <param name="dnsmasqManager">Dnsmasq 配置管理器</param>
    public DnsController(DnsmasqManager dnsmasqManager) => _dnsmasqManager = dnsmasqManager;

    // ── DNS 规则 CRUD ──

    [HttpGet("rules")] public ActionResult<IList<DnsRule>> GetRules() => Ok(DnsRule.FindAllWithCache());

    [HttpPost("rules")]
    public ActionResult AddRule([FromBody] DnsRule rule)
    {
        rule.Insert();
        TryApplyDnsmasq();
        return Ok(new { success = true, id = rule.Id });
    }

    [HttpPut("rules/{id}")]
    public ActionResult UpdateRule(Int32 id, [FromBody] DnsRule rule)
    {
        var entity = DnsRule.FindById(id);
        if (entity == null) return NotFound();
        entity.Domain = rule.Domain; entity.TargetIp = rule.TargetIp; entity.RuleKind = rule.RuleKind; entity.Enable = rule.Enable;
        entity.Update();
        TryApplyDnsmasq();
        return Ok(new { success = true });
    }

    [HttpDelete("rules/{id}")]
    public ActionResult DeleteRule(Int32 id)
    {
        var r = DnsRule.FindById(id);
        if (r == null) return NotFound();
        r.Delete();
        TryApplyDnsmasq();
        return Ok(new { success = true });
    }

    // ── 儿童模式 DNS 白名单 ──

    /// <summary>获取儿童模式状态。true=仅允许教育/学习域名</summary>
    [HttpGet("children-mode")]
    public ActionResult GetChildrenMode()
    {
        // 儿童模式通过检测白名单规则是否全部启用来判断
        var rules = DnsRule.FindAll(DnsRule._.RuleKind == Rainbow.Entity.Models.RuleKinds.白名单 & DnsRule._.Enable == true);
        var enabled = rules.Count > 0;
        return Ok(new { enabled, whitelistRuleCount = rules.Count });
    }

    /// <summary>切换儿童模式</summary>
    [HttpPost("children-mode")]
    public ActionResult ToggleChildrenMode([FromBody] ChildrenModeDto dto)
    {
        var rules = DnsRule.FindAll(DnsRule._.RuleKind == Rainbow.Entity.Models.RuleKinds.白名单);
        foreach (var rule in rules)
        {
            rule.Enable = dto.Enable;
            rule.Update();
        }
        TryApplyDnsmasq();
        return Ok(new { success = true, enabled = dto.Enable, affectedCount = rules.Count });
    }

    /// <summary>获取教育/学习域名白名单</summary>
    [HttpGet("whitelist")]
    public ActionResult<IList<DnsRule>> GetWhitelist()
    {
        var list = DnsRule.FindAll(DnsRule._.RuleKind == Rainbow.Entity.Models.RuleKinds.白名单);
        return Ok(list);
    }

    /// <summary>添加白名单域名(教育/学习类)</summary>
    [HttpPost("whitelist")]
    public ActionResult AddWhitelist([FromBody] DnsRule rule)
    {
        rule.RuleKind = Rainbow.Entity.Models.RuleKinds.白名单;
        rule.Enable = true;
        rule.Insert();
        TryApplyDnsmasq();
        return Ok(new { success = true, id = rule.Id });
    }

    /// <summary>尝试应用 dnsmasq 配置(最佳努力,失败不影响 API 返回)</summary>
    private void TryApplyDnsmasq()
    {
        _ = Task.Run(async () =>
        {
            try
            {
                await _dnsmasqManager.ApplyAsync();
            }
            catch { }
        });
    }
}

/// <summary>儿童模式开关 DTO</summary>
public class ChildrenModeDto
{
    /// <summary>是否启用</summary>
    public Boolean Enable { get; set; }
}