protocol-proxy 2.2.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "protocol-proxy",
3
- "version": "2.2.0",
3
+ "version": "2.3.2",
4
4
  "description": "OpenAI / Anthropic 协议转换透明代理",
5
5
  "main": "server.js",
6
6
  "bin": {
@@ -27,8 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "cors": "^2.8.5",
30
- "express": "^4.19.2",
31
- "puppeteer-core": "^24.43.0"
30
+ "express": "^4.19.2"
32
31
  },
33
32
  "devDependencies": {
34
33
  "pkg": "^5.8.1"
package/public/app.js CHANGED
@@ -211,6 +211,8 @@ function selectProvider(id) {
211
211
  const models = provider?.models || [];
212
212
  selectModel(models[0] || '');
213
213
  updateModelAddState();
214
+ // 同步 API Key placeholder
215
+ document.getElementById('target-key').placeholder = provider?.apiKey ? '已设置(留空则不修改)' : 'sk-...';
214
216
  // 同步 Azure 字段
215
217
  document.getElementById('target-azure-deployment').value = provider?.azureDeployment || '';
216
218
  document.getElementById('target-azure-version').value = provider?.azureApiVersion || '';
@@ -440,11 +442,16 @@ async function confirmImport() {
440
442
 
441
443
  async function restartAllProxies() {
442
444
  try {
443
- for (const p of proxies) {
444
- if (p.running) {
445
- await fetch(`/api/proxies/${p.id}/stop`, { method: 'POST' });
446
- }
445
+ // 先停掉所有运行中的代理(不管 ID 是否匹配新配置)
446
+ const statusRes = await fetch('/api/status');
447
+ const status = await statusRes.json();
448
+ const runningIds = (status.running || []).map(r => r.id);
449
+ for (const id of runningIds) {
450
+ await fetch(`/api/proxies/${id}/stop`, { method: 'POST' });
447
451
  }
452
+ // 重新加载配置
453
+ await loadProxies();
454
+ // 按新配置启动所有代理
448
455
  for (const p of proxies) {
449
456
  await fetch(`/api/proxies/${p.id}/start`, { method: 'POST' });
450
457
  }
@@ -466,6 +473,10 @@ async function loadStats() {
466
473
  try {
467
474
  const params = new URLSearchParams({ range: statsRange });
468
475
  if (statsProxyId) params.set('proxyId', statsProxyId);
476
+ const startDate = document.getElementById('stats-start-date')?.value;
477
+ const endDate = document.getElementById('stats-end-date')?.value;
478
+ if (startDate) params.set('startDate', startDate);
479
+ if (endDate) params.set('endDate', endDate);
469
480
  const res = await fetch('/api/stats?' + params);
470
481
  const data = await res.json();
471
482
  renderStatsSummary(data.summary);
@@ -577,9 +588,15 @@ function initStatsRangeBtns() {
577
588
  document.querySelectorAll('.stats-range-btn').forEach(b => b.classList.remove('active'));
578
589
  btn.classList.add('active');
579
590
  statsRange = btn.dataset.range;
591
+ // 清空日期选择器,显示全部数据
592
+ document.getElementById('stats-start-date').value = '';
593
+ document.getElementById('stats-end-date').value = '';
580
594
  loadStats();
581
595
  });
582
596
  });
597
+ // 日期选择器变化时自动加载
598
+ document.getElementById('stats-start-date').addEventListener('change', loadStats);
599
+ document.getElementById('stats-end-date').addEventListener('change', loadStats);
583
600
  }
584
601
 
585
602
  function generateToken() {
@@ -635,6 +652,9 @@ async function init() {
635
652
  initSimpleDropdown('protocol-dropdown', (val) => {
636
653
  document.getElementById('azure-fields').style.display = val === 'openai' ? '' : 'none';
637
654
  });
655
+ // 初始状态:根据当前协议值决定 Azure 字段显示
656
+ const initProto = document.getElementById('target-protocol').value;
657
+ document.getElementById('azure-fields').style.display = initProto === 'openai' ? '' : 'none';
638
658
  }
639
659
 
640
660
  // ==================== 代理地址复制 ====================
package/public/index.html CHANGED
@@ -42,6 +42,10 @@
42
42
  <button class="btn btn-sm stats-range-btn active" data-range="daily">每日</button>
43
43
  <button class="btn btn-sm stats-range-btn" data-range="monthly">每月</button>
44
44
  <button class="btn btn-sm stats-range-btn" data-range="yearly">每年</button>
45
+ <span class="stats-date-sep">|</span>
46
+ <input type="date" id="stats-start-date" class="stats-date-input" placeholder="开始日期">
47
+ <span class="stats-date-sep">~</span>
48
+ <input type="date" id="stats-end-date" class="stats-date-input" placeholder="结束日期">
45
49
  </div>
46
50
  </div>
47
51
  </div>
@@ -160,6 +164,7 @@
160
164
  <div class="model-dropdown-options" id="protocol-dropdown-options">
161
165
  <div class="model-option selected" data-value="openai"><span class="model-option-name">OpenAI</span></div>
162
166
  <div class="model-option" data-value="anthropic"><span class="model-option-name">Anthropic</span></div>
167
+ <div class="model-option" data-value="gemini"><span class="model-option-name">Gemini</span></div>
163
168
  </div>
164
169
  </div>
165
170
  </div>
@@ -190,12 +195,12 @@
190
195
  </div>
191
196
  <div class="form-row" id="azure-fields" style="display:none">
192
197
  <div class="form-group">
193
- <label>Azure Deployment</label>
194
- <input type="text" id="target-azure-deployment" placeholder="gpt-4o">
198
+ <label>Azure Deployment <span style="color:#64748b;font-size:0.75rem">(仅 Azure 用户填写)</span></label>
199
+ <input type="text" id="target-azure-deployment" placeholder="仅 Azure 用户填写">
195
200
  </div>
196
201
  <div class="form-group">
197
- <label>Azure API Version</label>
198
- <input type="text" id="target-azure-version" placeholder="2024-02-01">
202
+ <label>Azure API Version <span style="color:#64748b;font-size:0.75rem">(仅 Azure 用户填写)</span></label>
203
+ <input type="text" id="target-azure-version" placeholder="仅 Azure 用户填写">
199
204
  </div>
200
205
  </div>
201
206
  </div>
package/public/style.css CHANGED
@@ -954,7 +954,8 @@ form {
954
954
  .stats-controls {
955
955
  display: flex;
956
956
  gap: 12px;
957
- align-items: center;
957
+ flex-wrap: wrap;
958
+ justify-content: flex-end; align-items: center;
958
959
  }
959
960
 
960
961
  .stats-controls .model-dropdown {
@@ -970,6 +971,7 @@ form {
970
971
  .stats-range-btns {
971
972
  display: flex;
972
973
  gap: 4px;
974
+ align-items: center;
973
975
  background: rgba(6, 8, 15, 0.4);
974
976
  border-radius: 10px;
975
977
  padding: 3px;
@@ -995,7 +997,38 @@ form {
995
997
  .stats-range-btn.active {
996
998
  background: rgba(59, 130, 246, 0.2) !important;
997
999
  color: #60a5fa !important;
998
- box-shadow: 0 0 8px rgba(59, 130, 246, 0.15) !important;
1000
+ }
1001
+
1002
+ .stats-date-range {
1003
+ display: flex;
1004
+ align-items: center;
1005
+ gap: 4px;
1006
+ }
1007
+
1008
+ .stats-date-input {
1009
+ background: rgba(15, 23, 42, 0.6);
1010
+ border: 1px solid rgba(51, 65, 85, 0.5);
1011
+ border-radius: 6px;
1012
+ color: #e2e8f0;
1013
+ padding: 6px 8px;
1014
+ font-size: 0.78rem;
1015
+ outline: none;
1016
+ transition: border-color 0.2s;
1017
+ width: 125px;
1018
+ }
1019
+
1020
+ .stats-date-input:focus {
1021
+ border-color: #3b82f6;
1022
+ }
1023
+
1024
+ .stats-date-input::-webkit-calendar-picker-indicator {
1025
+ filter: invert(0.7);
1026
+ cursor: pointer;
1027
+ }
1028
+
1029
+ .stats-date-sep {
1030
+ color: #475569;
1031
+ font-size: 0.85rem;
999
1032
  }
1000
1033
 
1001
1034
  .stats-summary {
@@ -1123,6 +1156,15 @@ form {
1123
1156
  .stats-controls .model-dropdown {
1124
1157
  width: 100%;
1125
1158
  }
1159
+
1160
+ .stats-date-range {
1161
+ width: 100%;
1162
+ }
1163
+
1164
+ .stats-date-input {
1165
+ flex: 1;
1166
+ min-width: 0;
1167
+ }
1126
1168
  }
1127
1169
 
1128
1170
  /* Responsive */
package/server.js CHANGED
@@ -596,6 +596,8 @@ process.on('SIGINT', async () => {
596
596
  removePid();
597
597
  try {
598
598
  const proxyManager = require('./lib/proxy-manager');
599
+ const statsStore = require('./lib/stats-store');
600
+ statsStore.flush();
599
601
  await proxyManager.stopAll();
600
602
  } catch (err) {
601
603
  console.error('[Shutdown] stopAll error:', err.message);
@@ -607,6 +609,8 @@ process.on('SIGTERM', async () => {
607
609
  removePid();
608
610
  try {
609
611
  const proxyManager = require('./lib/proxy-manager');
612
+ const statsStore = require('./lib/stats-store');
613
+ statsStore.flush();
610
614
  await proxyManager.stopAll();
611
615
  } catch (err) {
612
616
  console.error('[Shutdown] stopAll error:', err.message);