From 1e6c637d9362d7fc3b4cbf479c287e2187a31eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=90=E5=BF=B5=E4=BA=91?= Date: Wed, 1 Jul 2026 18:12:37 +0800 Subject: [PATCH] feat: add downstream domain fix plugin --- DownstreamDomainFixPlugin.php | 32 ++++ controller/AdminIndexController.php | 90 ++++++++++++ lang/en-us.php | 2 + lang/zh-cn.php | 2 + menu.php | 13 ++ menuclientarea.php | 2 + template/admin/index.tpl | 219 ++++++++++++++++++++++++++++ 7 files changed, 360 insertions(+) create mode 100644 DownstreamDomainFixPlugin.php create mode 100644 controller/AdminIndexController.php create mode 100644 lang/en-us.php create mode 100644 lang/zh-cn.php create mode 100644 menu.php create mode 100644 menuclientarea.php create mode 100644 template/admin/index.tpl diff --git a/DownstreamDomainFixPlugin.php b/DownstreamDomainFixPlugin.php new file mode 100644 index 0000000..c95e608 --- /dev/null +++ b/DownstreamDomainFixPlugin.php @@ -0,0 +1,32 @@ + 'DownstreamDomainFix', + 'title' => '下游推送域名修复', + 'description' => '批量修改指定客户名下服务器的下游推送域名', + 'status' => 1, + 'author' => '沐念云', + 'version' => '1.0', + 'module' => 'addons', + 'lang' => [ + 'chinese' => '下游推送域名修复', + 'chinese_tw' => '下游推送域名修復', + 'english' => 'Downstream Domain Fix', + ], + ]; + + public function install() + { + return true; + } + + public function uninstall() + { + return true; + } +} diff --git a/controller/AdminIndexController.php b/controller/AdminIndexController.php new file mode 100644 index 0000000..1c87716 --- /dev/null +++ b/controller/AdminIndexController.php @@ -0,0 +1,90 @@ +request->isPost()) { + $result = $this->fixDomain($uid, $domain); + } + + $this->assign('Title', '下游推送域名修复'); + $this->assign('uid', $uid ?: ''); + $this->assign('domain', $domain); + $this->assign('result', $result); + return $this->fetch('/index'); + } + + private function fixDomain($uid, $domain) + { + $domain = rtrim($domain, '/'); + if ($uid <= 0) { + return ['status' => 400, 'msg' => '客户ID不能为空', 'total' => 0, 'updated' => 0, 'skipped' => 0, 'list' => []]; + } + if (!$this->isValidDomain($domain)) { + return ['status' => 400, 'msg' => '推送域名必须以 http:// 或 https:// 开头', 'total' => 0, 'updated' => 0, 'skipped' => 0, 'list' => []]; + } + + $hosts = \think\Db::name('host') + ->field('id,uid,domain,dedicatedip,domainstatus,stream_info') + ->where('uid', $uid) + ->where('stream_info', '<>', '') + ->select() + ->toArray(); + + $result = ['status' => 200, 'msg' => '处理完成', 'total' => count($hosts), 'updated' => 0, 'skipped' => 0, 'list' => []]; + + foreach ($hosts as $host) { + $streamInfo = json_decode($host['stream_info'], true) ?: []; + if (empty($streamInfo['downstream_url']) || empty($streamInfo['downstream_token']) || empty($streamInfo['downstream_id'])) { + $result['skipped']++; + $result['list'][] = $this->buildRow($host, '', $domain, '跳过:没有完整下游推送信息'); + continue; + } + + $oldDomain = rtrim($streamInfo['downstream_url'], '/'); + if ($oldDomain === $domain) { + $result['skipped']++; + $result['list'][] = $this->buildRow($host, $oldDomain, $domain, '跳过:域名未变化'); + continue; + } + + $streamInfo['downstream_url'] = $domain; + \think\Db::name('host')->where('id', $host['id'])->update([ + 'stream_info' => json_encode($streamInfo, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + ]); + + $result['updated']++; + $result['list'][] = $this->buildRow($host, $oldDomain, $domain, '已更新'); + } + + if (function_exists('active_log')) { + active_log(sprintf('插件批量修复下游推送域名,客户ID:%d,目标域名:%s,更新:%d,跳过:%d', $uid, $domain, $result['updated'], $result['skipped'])); + } + + return $result; + } + + private function isValidDomain($domain) + { + return strpos($domain, 'https://') === 0 || strpos($domain, 'http://') === 0; + } + + private function buildRow($host, $oldDomain, $newDomain, $status) + { + return [ + 'id' => $host['id'], + 'domain' => $host['domain'], + 'dedicatedip' => $host['dedicatedip'], + 'domainstatus' => $host['domainstatus'], + 'old_domain' => $oldDomain, + 'new_domain' => $newDomain, + 'status' => $status, + ]; + } +} diff --git a/lang/en-us.php b/lang/en-us.php new file mode 100644 index 0000000..881ab67 --- /dev/null +++ b/lang/en-us.php @@ -0,0 +1,2 @@ + '修复推送域名', + 'url' => 'DownstreamDomainFix://AdminIndex/index', + 'custom' => 0, + 'lang' => [ + 'chinese' => '修复推送域名', + 'chinese_tw' => '修復推送域名', + 'english' => 'Fix Domain', + ], + ], +]; diff --git a/menuclientarea.php b/menuclientarea.php new file mode 100644 index 0000000..881ab67 --- /dev/null +++ b/menuclientarea.php @@ -0,0 +1,2 @@ + + .ddf-page { + background: linear-gradient(135deg, #f7fbff 0%, #eef5ff 100%); + border-radius: 14px; + padding: 22px; + } + .ddf-hero { + position: relative; + overflow: hidden; + border-radius: 16px; + padding: 28px 32px; + color: #fff; + background: linear-gradient(135deg, #1d4ed8 0%, #0f766e 100%); + box-shadow: 0 14px 34px rgba(20, 82, 160, .18); + margin-bottom: 22px; + } + .ddf-hero:after { + content: ""; + position: absolute; + width: 220px; + height: 220px; + right: -70px; + top: -70px; + border-radius: 50%; + background: rgba(255, 255, 255, .14); + } + .ddf-hero h3 { + margin: 0 0 10px; + font-size: 24px; + font-weight: 700; + letter-spacing: .5px; + } + .ddf-hero p { + margin: 0; + max-width: 760px; + line-height: 1.8; + color: rgba(255, 255, 255, .9); + } + .ddf-form-card, + .ddf-result-card { + border: 1px solid #e6eef8; + border-radius: 16px; + background: #fff; + box-shadow: 0 10px 28px rgba(15, 52, 96, .08); + } + .ddf-form-card { + padding: 26px 28px; + } + .ddf-field label { + color: #26384d; + font-weight: 600; + margin-bottom: 8px; + } + .ddf-field .form-control { + height: 42px; + border-color: #d9e4f2; + border-radius: 10px; + box-shadow: none; + } + .ddf-field .form-control:focus { + border-color: #2563eb; + box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); + } + .ddf-submit { + min-width: 150px; + height: 42px; + border: 0; + border-radius: 10px; + background: linear-gradient(135deg, #2563eb 0%, #0f766e 100%); + box-shadow: 0 10px 20px rgba(37, 99, 235, .2); + font-weight: 600; + } + .ddf-result-card { + margin-top: 22px; + padding: 18px; + } + .ddf-summary { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-bottom: 16px; + } + .ddf-summary-item { + min-width: 150px; + border-radius: 12px; + padding: 14px 16px; + background: #f5f8fc; + } + .ddf-summary-item strong { + display: block; + font-size: 20px; + color: #12304f; + } + .ddf-summary-item span { + color: #6b7a90; + } + .ddf-table { + margin-bottom: 0; + border-radius: 12px; + overflow: hidden; + } + .ddf-table thead th { + border-bottom: 0; + background: #f1f6fd; + color: #34506c; + font-weight: 700; + white-space: nowrap; + } + .ddf-table tbody td { + vertical-align: middle; + color: #34495e; + } + .ddf-badge { + display: inline-block; + border-radius: 999px; + padding: 4px 10px; + background: #e8f5ee; + color: #17834f; + font-size: 12px; + font-weight: 600; + } + + +
+
+
+
+
+
+
{$Title}
+
+ {foreach $PluginsAdminMenu as $v} + {if $v['custom']} + {$v.name} + {else/} + {$v.name} + {/if} + {/foreach} +
+
+ +
+
+

代理推送地址批量修复

+

用于你站点名下代理用户的地址变更后,可通过本插件直接批量更换推送代理新地址。

+
+ +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+
+ + {if $result} +
+
+ {$result.msg};匹配 {$result.total} 台,更新 {$result.updated} 台,跳过 {$result.skipped} 台。 +
+ +
+
{$result.total}匹配服务器
+
{$result.updated}成功更新
+
{$result.skipped}跳过数量
+
+ + {if $result.list} +
+ + + + + + + + + + + + + + {foreach $result.list as $row} + + + + + + + + + + {/foreach} + +
Host ID主机名主IP状态原推送域名新推送域名处理结果
{$row.id}{$row.domain}{$row.dedicatedip}{$row.domainstatus}{$row.old_domain}{$row.new_domain}{$row.status}
+
+ {/if} +
+ {/if} +
+
+
+
+
+