@@ -1581,3 +1581,214 @@ func (h *TunnelHandler) HandleBatchDeleteTunnels(w http.ResponseWriter, r *http.
15811581
15821582 _ = json .NewEncoder (w ).Encode (resp )
15831583}
1584+
1585+ // HandleNewBatchCreateTunnels 新的批量创建隧道处理
1586+ func (h * TunnelHandler ) HandleNewBatchCreateTunnels (w http.ResponseWriter , r * http.Request ) {
1587+ if r .Method != http .MethodPost {
1588+ http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
1589+ return
1590+ }
1591+
1592+ var req tunnel.NewBatchCreateRequest
1593+ if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
1594+ w .WriteHeader (http .StatusBadRequest )
1595+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1596+ Success : false ,
1597+ Error : "无效的请求数据" ,
1598+ })
1599+ return
1600+ }
1601+
1602+ // 添加调试日志,显示接收到的原始请求数据
1603+ reqBytes , _ := json .MarshalIndent (req , "" , " " )
1604+ log .Infof ("[API] 接收到新的批量创建请求,原始数据: %s" , string (reqBytes ))
1605+
1606+ // 验证请求模式
1607+ if req .Mode == "" {
1608+ w .WriteHeader (http .StatusBadRequest )
1609+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1610+ Success : false ,
1611+ Error : "请求模式不能为空" ,
1612+ })
1613+ return
1614+ }
1615+
1616+ // 根据模式验证具体数据
1617+ switch req .Mode {
1618+ case "standard" :
1619+ if len (req .Standard ) == 0 {
1620+ w .WriteHeader (http .StatusBadRequest )
1621+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1622+ Success : false ,
1623+ Error : "标准模式批量创建项目不能为空" ,
1624+ })
1625+ return
1626+ }
1627+
1628+ // 限制批量创建的数量
1629+ const maxBatchSize = 50
1630+ if len (req .Standard ) > maxBatchSize {
1631+ w .WriteHeader (http .StatusBadRequest )
1632+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1633+ Success : false ,
1634+ Error : fmt .Sprintf ("标准模式批量创建数量不能超过 %d 个" , maxBatchSize ),
1635+ })
1636+ return
1637+ }
1638+
1639+ // 验证每个项目的必填字段
1640+ for i , item := range req .Standard {
1641+ if item .EndpointID <= 0 {
1642+ w .WriteHeader (http .StatusBadRequest )
1643+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1644+ Success : false ,
1645+ Error : fmt .Sprintf ("第 %d 项的端点ID无效" , i + 1 ),
1646+ })
1647+ return
1648+ }
1649+ if item .TunnelPort <= 0 || item .TunnelPort > 65535 {
1650+ w .WriteHeader (http .StatusBadRequest )
1651+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1652+ Success : false ,
1653+ Error : fmt .Sprintf ("第 %d 项的隧道端口无效" , i + 1 ),
1654+ })
1655+ return
1656+ }
1657+ if item .TargetHost == "" {
1658+ w .WriteHeader (http .StatusBadRequest )
1659+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1660+ Success : false ,
1661+ Error : fmt .Sprintf ("第 %d 项的目标地址不能为空" , i + 1 ),
1662+ })
1663+ return
1664+ }
1665+ if item .TargetPort <= 0 || item .TargetPort > 65535 {
1666+ w .WriteHeader (http .StatusBadRequest )
1667+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1668+ Success : false ,
1669+ Error : fmt .Sprintf ("第 %d 项的目标端口无效" , i + 1 ),
1670+ })
1671+ return
1672+ }
1673+ if item .Name == "" {
1674+ w .WriteHeader (http .StatusBadRequest )
1675+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1676+ Success : false ,
1677+ Error : fmt .Sprintf ("第 %d 项的隧道名称不能为空" , i + 1 ),
1678+ })
1679+ return
1680+ }
1681+ }
1682+
1683+ case "config" :
1684+ if len (req .Config ) == 0 {
1685+ w .WriteHeader (http .StatusBadRequest )
1686+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1687+ Success : false ,
1688+ Error : "配置模式批量创建项目不能为空" ,
1689+ })
1690+ return
1691+ }
1692+
1693+ // 计算总的配置项数量并验证
1694+ totalConfigs := 0
1695+ for _ , configItem := range req .Config {
1696+ totalConfigs += len (configItem .Config )
1697+ }
1698+
1699+ const maxBatchSize = 50
1700+ if totalConfigs > maxBatchSize {
1701+ w .WriteHeader (http .StatusBadRequest )
1702+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1703+ Success : false ,
1704+ Error : fmt .Sprintf ("配置模式批量创建数量不能超过 %d 个" , maxBatchSize ),
1705+ })
1706+ return
1707+ }
1708+
1709+ // 验证每个配置项
1710+ for i , configItem := range req .Config {
1711+ if configItem .EndpointID <= 0 {
1712+ w .WriteHeader (http .StatusBadRequest )
1713+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1714+ Success : false ,
1715+ Error : fmt .Sprintf ("第 %d 个配置组的端点ID无效" , i + 1 ),
1716+ })
1717+ return
1718+ }
1719+
1720+ if len (configItem .Config ) == 0 {
1721+ w .WriteHeader (http .StatusBadRequest )
1722+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1723+ Success : false ,
1724+ Error : fmt .Sprintf ("第 %d 个配置组的配置列表不能为空" , i + 1 ),
1725+ })
1726+ return
1727+ }
1728+
1729+ for j , config := range configItem .Config {
1730+ if config .ListenPort <= 0 || config .ListenPort > 65535 {
1731+ w .WriteHeader (http .StatusBadRequest )
1732+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1733+ Success : false ,
1734+ Error : fmt .Sprintf ("第 %d 个配置组第 %d 项的监听端口无效" , i + 1 , j + 1 ),
1735+ })
1736+ return
1737+ }
1738+ if config .Dest == "" {
1739+ w .WriteHeader (http .StatusBadRequest )
1740+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1741+ Success : false ,
1742+ Error : fmt .Sprintf ("第 %d 个配置组第 %d 项的目标地址不能为空" , i + 1 , j + 1 ),
1743+ })
1744+ return
1745+ }
1746+ if config .Name == "" {
1747+ w .WriteHeader (http .StatusBadRequest )
1748+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1749+ Success : false ,
1750+ Error : fmt .Sprintf ("第 %d 个配置组第 %d 项的隧道名称不能为空" , i + 1 , j + 1 ),
1751+ })
1752+ return
1753+ }
1754+ }
1755+ }
1756+
1757+ default :
1758+ w .WriteHeader (http .StatusBadRequest )
1759+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1760+ Success : false ,
1761+ Error : "不支持的批量创建模式: " + req .Mode ,
1762+ })
1763+ return
1764+ }
1765+
1766+ log .Infof ("[API] 接收到新的批量创建隧道请求,模式: %s" , req .Mode )
1767+
1768+ // 调用服务层新的批量创建
1769+ response , err := h .tunnelService .NewBatchCreateTunnels (req )
1770+ if err != nil {
1771+ w .WriteHeader (http .StatusInternalServerError )
1772+ json .NewEncoder (w ).Encode (tunnel.NewBatchCreateResponse {
1773+ Success : false ,
1774+ Error : "新批量创建失败: " + err .Error (),
1775+ })
1776+ return
1777+ }
1778+
1779+ // 根据结果设置HTTP状态码
1780+ if response .Success {
1781+ if response .FailCount > 0 {
1782+ // 部分成功
1783+ w .WriteHeader (http .StatusPartialContent )
1784+ } else {
1785+ // 全部成功
1786+ w .WriteHeader (http .StatusOK )
1787+ }
1788+ } else {
1789+ // 全部失败
1790+ w .WriteHeader (http .StatusBadRequest )
1791+ }
1792+
1793+ json .NewEncoder (w ).Encode (response )
1794+ }
0 commit comments