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

namespace Rainbow.Web.Controllers;

/// <summary>DHCP 服务管理 API</summary>
[ApiController]
[Route("api/dhcp")]
public class DhcpController : ControllerBase
{
    private readonly DnsmasqManager _dnsmasqManager;

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

    /// <summary>获取所有地址池</summary>
    [HttpGet("pool")]
    public ActionResult<IList<DhcpPool>> GetPools([FromQuery] String? iface = null)
    {
        if (!iface.IsNullOrEmpty())
        {
            return Ok(DhcpPool.FindAll(
                DhcpPool._.Interface == iface & DhcpPool._.Enable == true));
        }
        return Ok(DhcpPool.FindAllWithCache());
    }

    /// <summary>保存地址池(新增或更新)</summary>
    [HttpPost("pool")]
    public ActionResult SavePool([FromBody] DhcpPool pool)
    {
        var existing = DhcpPool.Find(DhcpPool._.Name == pool.Name);
        if (existing != null)
        {
            existing.Netmask = pool.Netmask;
            existing.RangeStart = pool.RangeStart;
            existing.RangeEnd = pool.RangeEnd;
            existing.Gateway = pool.Gateway;
            existing.LeaseTime = pool.LeaseTime;
            existing.DnsServers = pool.DnsServers;
            existing.Interface = pool.Interface;
            existing.Enable = pool.Enable;
            existing.Update();
        }
        else
        {
            pool.Insert();
        }
        TryApplyDnsmasq();
        return Ok(new { success = true });
    }

    /// <summary>为指定接口创建默认 DHCP 地址池</summary>
    [HttpPost("pool/for-interface")]
    public ActionResult CreatePoolForInterface([FromBody] InterfacePoolDto dto)
    {
        if (dto.Interface.IsNullOrEmpty())
            return BadRequest(new { error = "接口名不能为空" });

        // 检查是否已存在
        var existing = DhcpPool.Find(DhcpPool._.Interface == dto.Interface);
        if (existing != null)
            return Ok(new { success = true, message = "已存在", pool = existing });

        // 根据接口 IP 推断网段
        var gateway = dto.Gateway.IsNullOrEmpty() ? "192.168.100.1" : dto.Gateway;
        var parts = gateway.Split('.');
        if (parts.Length == 4)
            parts[3] = "100";
        var rangeStart = dto.RangeStart.IsNullOrEmpty() ? String.Join(".", parts) : dto.RangeStart;
        parts[3] = "200";
        var rangeEnd = dto.RangeEnd.IsNullOrEmpty() ? String.Join(".", parts) : dto.RangeEnd;

        var pool = new DhcpPool
        {
            Name = $"dhcp_{dto.Interface}",
            Interface = dto.Interface,
            Netmask = dto.Netmask.IsNullOrEmpty() ? "255.255.255.0" : dto.Netmask,
            RangeStart = rangeStart,
            RangeEnd = rangeEnd,
            Gateway = gateway,
            LeaseTime = dto.LeaseTime > 0 ? dto.LeaseTime : 86400,
            DnsServers = dto.DnsServers.IsNullOrEmpty() ? gateway : dto.DnsServers,
            Enable = true
        };
        pool.Insert();
        TryApplyDnsmasq();

        return Ok(new { success = true, pool });
    }

    /// <summary>尝试应用 dnsmasq 配置(最佳努力)</summary>
    private void TryApplyDnsmasq()
    {
        _ = Task.Run(async () =>
        {
            try
            {
                await _dnsmasqManager.ApplyAsync();
            }
            catch { }
        });
    }
}

/// <summary>接口 DHCP 池请求</summary>
public class InterfacePoolDto
{
    public String? Interface { get; set; }
    public String? Gateway { get; set; }
    public String? Netmask { get; set; }
    public String? RangeStart { get; set; }
    public String? RangeEnd { get; set; }
    public Int32 LeaseTime { get; set; }
    public String? DnsServers { get; set; }
}