@lynn123411/dsh-a6api 1.5.6 → 1.5.8

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/lib/client.js CHANGED
@@ -51,6 +51,7 @@ function formatRelativeNow(tsSec) {
51
51
  }
52
52
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
53
53
  var RATE_LIMIT_RE = /\b429\b|Too Many Requests|rate\s*limit/i;
54
+ var PROBE_RESULT_GUARD_MS = 2e4;
54
55
  var A6ApiStore = class {
55
56
  state = {
56
57
  loading: true,
@@ -117,19 +118,35 @@ var A6ApiStore = class {
117
118
  const data = json.data;
118
119
  this.state.config = data.config;
119
120
  this.state.balance = data.balance;
121
+ const localModels = this.state.models;
120
122
  this.state.models = data.models;
121
123
  const snapshot = this.probeAllSnapshot;
122
- if (this.state.probeAllActive && snapshot) {
123
- this.state.models = this.state.models.map((m) => {
124
- if (this.state.probingModelNames.has(m.model_name)) {
125
- return { ...m, probeStatus: "probing" };
126
- }
127
- if (snapshot.includes(m.model_name) && !this.probeAllDone.has(m.model_name)) {
128
- return { ...m, probeStatus: "queued", probeError: void 0 };
129
- }
130
- return m;
131
- });
132
- }
124
+ const localByName = new Map(localModels.map((m) => [m.model_name, m]));
125
+ const nowMs = Date.now();
126
+ this.state.models = this.state.models.map((m) => {
127
+ const local = localByName.get(m.model_name);
128
+ if (!local) return m;
129
+ if (this.state.probingModelNames.has(m.model_name)) {
130
+ return { ...m, probeStatus: "probing" };
131
+ }
132
+ if (local.lastProbedAt && nowMs - local.lastProbedAt < PROBE_RESULT_GUARD_MS) {
133
+ return {
134
+ ...m,
135
+ merchant: local.merchant,
136
+ probeStatus: local.probeStatus,
137
+ probeError: local.probeError,
138
+ probeLatencyMs: local.probeLatencyMs,
139
+ lastProbedAt: local.lastProbedAt,
140
+ // 探测请求本身会写路由日志,本地乐观时效不早于旧快照,优先保留
141
+ lastRoutedAt: local.lastRoutedAt ?? m.lastRoutedAt,
142
+ lastRoutedText: local.lastRoutedText ?? m.lastRoutedText
143
+ };
144
+ }
145
+ if (this.state.probeAllActive && snapshot && snapshot.includes(m.model_name) && !this.probeAllDone.has(m.model_name)) {
146
+ return { ...m, probeStatus: "queued", probeError: void 0 };
147
+ }
148
+ return m;
149
+ });
133
150
  this.state.dshConfiguredModels = data.dshConfiguredModels;
134
151
  if (Array.isArray(data.pins)) {
135
152
  this.state.pins = data.pins;
@@ -531,7 +548,7 @@ var A6ApiStore = class {
531
548
  * 固定 / 取消固定 / 禁用 / 恢复 的统一执行器。
532
549
  * 成功后会刷新 /state(服务端会把平台固定记录叠加回卡片,跟随官网状态)。
533
550
  */
534
- async runMarketplaceAction(modelName, endpoint, busySet) {
551
+ async runMarketplaceAction(modelName, endpoint, busySet, extraBody) {
535
552
  if (busySet.has(modelName)) return { ok: false, error: "\u64CD\u4F5C\u8FDB\u884C\u4E2D" };
536
553
  busySet.add(modelName);
537
554
  this.notify();
@@ -539,7 +556,7 @@ var A6ApiStore = class {
539
556
  const res = await fetch(`/api/dsh-a6api/${endpoint}`, {
540
557
  method: "POST",
541
558
  headers: { "Content-Type": "application/json" },
542
- body: JSON.stringify({ modelName })
559
+ body: JSON.stringify({ modelName, ...extraBody })
543
560
  });
544
561
  const json = await res.json().catch(() => null);
545
562
  if (res.ok && json?.ok) {
@@ -567,9 +584,14 @@ var A6ApiStore = class {
567
584
  pinModel(modelName) {
568
585
  return this.runMarketplaceAction(modelName, "pin", this.state.actionBusyModels);
569
586
  }
570
- /** 取消该模型的固定 */
571
- unpinModel(modelName) {
572
- return this.runMarketplaceAction(modelName, "unpin", this.state.actionBusyModels);
587
+ /** 取消该模型的固定(上游 pr195 起需要固定所属渠道 ID,随请求透传,服务端另做卡片缓存兜底) */
588
+ unpinModel(modelName, channelId) {
589
+ return this.runMarketplaceAction(
590
+ modelName,
591
+ "unpin",
592
+ this.state.actionBusyModels,
593
+ channelId && channelId > 0 ? { channelId } : void 0
594
+ );
573
595
  }
574
596
  /** 禁用卡片当前商家对该模型的服务 */
575
597
  disableModel(modelName) {
@@ -641,6 +663,27 @@ var MerchantCard = ({ model }) => {
641
663
  const [pinConfirmOpen, setPinConfirmOpen] = (0, import_react.useState)(false);
642
664
  const [actionError, setActionError] = (0, import_react.useState)(null);
643
665
  const errorTimerRef = (0, import_react.useRef)(null);
666
+ const REFRESH_FLASH_MS = 1600;
667
+ const prevProbeStatus = (0, import_react.useRef)(model.probeStatus);
668
+ const [refreshFlash, setRefreshFlash] = (0, import_react.useState)(null);
669
+ const flashTimerRef = (0, import_react.useRef)(null);
670
+ (0, import_react.useEffect)(() => {
671
+ const prev = prevProbeStatus.current;
672
+ const cur = model.probeStatus;
673
+ if (prev === cur) return;
674
+ prevProbeStatus.current = cur;
675
+ if (prev === "probing" && (cur === "success" || cur === "error")) {
676
+ setRefreshFlash(cur === "success" ? "ok" : "err");
677
+ if (flashTimerRef.current) clearTimeout(flashTimerRef.current);
678
+ flashTimerRef.current = setTimeout(() => setRefreshFlash(null), REFRESH_FLASH_MS);
679
+ }
680
+ }, [model.probeStatus]);
681
+ (0, import_react.useEffect)(
682
+ () => () => {
683
+ if (flashTimerRef.current) clearTimeout(flashTimerRef.current);
684
+ },
685
+ []
686
+ );
644
687
  const isProbing = model.probeStatus === "probing";
645
688
  const isQueued = model.probeStatus === "queued";
646
689
  const merchant = model.merchant;
@@ -684,7 +727,8 @@ var MerchantCard = ({ model }) => {
684
727
  const handleUnpin = async (e) => {
685
728
  e.stopPropagation();
686
729
  setActionError(null);
687
- const r = await store.unpinModel(model.model_name);
730
+ const channelId = Number(model.pinnedChannelId || model.merchant?.channel_id || 0) || void 0;
731
+ const r = await store.unpinModel(model.model_name, channelId);
688
732
  if (!r.ok) flashActionError(r.error || "\u53D6\u6D88\u56FA\u5B9A\u5931\u8D25");
689
733
  };
690
734
  const handleDisable = async (e) => {
@@ -767,315 +811,322 @@ var MerchantCard = ({ model }) => {
767
811
  = \xA5${Number(per1m.toPrecision(4))} /1M \u2248 \xA5${fmtSig(blend100m)} /1\u4EBF tokens
768
812
  \u547D\u4E2D\u7387\u53D6\u5361\u7247 24h \u5B9E\u6D4B\u7F13\u5B58\u547D\u4E2D\u7387`;
769
813
  })() : void 0;
770
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `dsh-a6-official-card ${model.inDsh ? "in-dsh" : ""}`, children: [
771
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-card-main-bar", onClick: () => setExpanded(!expanded), children: [
772
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-identity", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-col", children: [
773
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-line", children: [
774
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-name-text", children: model.model_name }),
775
- merchant?.channel_id && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dot-sep", children: "\xB7" }),
777
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-merchant-id-text", children: [
778
- "\u5546\u6237ID ",
779
- merchant.channel_id
780
- ] })
781
- ] }),
782
- isPinnedHere && !isChannelDisabled && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
783
- "span",
784
- {
785
- className: "dsh-a6-pin-badge here",
786
- "data-tooltip": `\u8BE5\u6A21\u578B\u5DF2\u56FA\u5B9A\u5230\u5F53\u524D\u5546\u5BB6${model.pinnedFallback === false ? "\uFF08\u4E25\u683C\u56FA\u5B9A\uFF09" : "\uFF0C\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009"}${pinTokenNote}`,
787
- "data-tooltip-pos": "down",
788
- children: "\u5DF2\u56FA\u5B9A"
789
- }
790
- ),
791
- isPinnedElsewhere && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
792
- "span",
814
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
815
+ "div",
816
+ {
817
+ className: `dsh-a6-official-card${model.inDsh ? " in-dsh" : ""}${refreshFlash ? ` dsh-a6-card-refresh ${refreshFlash === "ok" ? "refresh-ok" : "refresh-err"}` : ""}`,
818
+ children: [
819
+ refreshFlash && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-refresh-flag ${refreshFlash === "ok" ? "ok" : "err"}`, "aria-hidden": "true", children: refreshFlash === "ok" ? "\u2713 \u5546\u6237\u6570\u636E\u5DF2\u66F4\u65B0" : "\u2715 \u63A2\u6D4B\u5931\u8D25" }),
820
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-card-main-bar", onClick: () => setExpanded(!expanded), children: [
821
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-identity", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-col", children: [
822
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-line", children: [
823
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-name-text", children: model.model_name }),
824
+ merchant?.channel_id && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
825
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dot-sep", children: "\xB7" }),
826
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-merchant-id-text", children: [
827
+ "\u5546\u6237ID ",
828
+ merchant.channel_id
829
+ ] })
830
+ ] }),
831
+ isPinnedHere && !isChannelDisabled && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
832
+ "span",
833
+ {
834
+ className: "dsh-a6-pin-badge here",
835
+ "data-tooltip": `\u8BE5\u6A21\u578B\u5DF2\u56FA\u5B9A\u5230\u5F53\u524D\u5546\u5BB6${model.pinnedFallback === false ? "\uFF08\u4E25\u683C\u56FA\u5B9A\uFF09" : "\uFF0C\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009"}${pinTokenNote}`,
836
+ "data-tooltip-pos": "down",
837
+ children: "\u5DF2\u56FA\u5B9A"
838
+ }
839
+ ),
840
+ isPinnedElsewhere && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
841
+ "span",
842
+ {
843
+ className: "dsh-a6-pin-badge elsewhere",
844
+ "data-tooltip": `\u8BE5\u6A21\u578B\u5DF2\u56FA\u5B9A\u5230${model.pinnedChannelId ? `\u5546\u6237 #${model.pinnedChannelId}` : "\u5176\u4ED6\u5546\u5BB6"}${model.pinnedSupplierName ? `\uFF08${model.pinnedSupplierName}\uFF09` : ""}${!hasMerchant ? "\uFF1B\u5F53\u524D\u6682\u65E0\u5546\u5BB6\u6570\u636E" : ""}${pinTokenNote}`,
845
+ "data-tooltip-pos": "down",
846
+ children: !hasMerchant && model.pinnedChannelId ? `\u5DF2\u56FA\u5B9A\u5230\u5546\u6237 #${model.pinnedChannelId}` : "\u5DF2\u56FA\u5B9A\u5230\u5176\u4ED6\u5546\u5BB6"
847
+ }
848
+ ),
849
+ isChannelDisabled && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-badge disabled", "data-tooltip": "\u5F53\u524D\u5546\u5BB6\u5DF2\u5BF9\u8BE5\u6A21\u578B\u7981\u7528\uFF0C\u8DEF\u7531\u4E0D\u4F1A\u547D\u4E2D\u6B64\u6E20\u9053", "data-tooltip-pos": "down", children: "\u5DF2\u7981\u7528" })
850
+ ] }),
851
+ merchant?.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-sub-desc", children: merchant.description })
852
+ ] }) }),
853
+ merchant ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-pricing", children: [
854
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-price-col", children: [
855
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u5165\u4EF7 (1M)", children: merchant.input_price_cny }),
856
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u8BFB (1M)", children: merchant.cache_read_price_cny })
857
+ ] }),
858
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-price-col", children: [
859
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u51FA\u4EF7 (1M)", children: merchant.output_price_cny }),
860
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u5199 (1M)", children: merchant.cache_write_price_cny })
861
+ ] }),
862
+ blend100mValid && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-blend-pill", title: blendTitle, children: [
863
+ "\u2248 \xA5",
864
+ fmtSig(blend100m),
865
+ "/\u4EBF"
866
+ ] }),
867
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-ratio-pill", title: "\u5B9E\u65F6\u500D\u7387\u6BD4\u5B98\u65B9\u4EF7", children: ratioText })
868
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-pricing unprobed", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
869
+ "div",
793
870
  {
794
- className: "dsh-a6-pin-badge elsewhere",
795
- "data-tooltip": `\u8BE5\u6A21\u578B\u5DF2\u56FA\u5B9A\u5230${model.pinnedChannelId ? `\u5546\u6237 #${model.pinnedChannelId}` : "\u5176\u4ED6\u5546\u5BB6"}${model.pinnedSupplierName ? `\uFF08${model.pinnedSupplierName}\uFF09` : ""}${!hasMerchant ? "\uFF1B\u5F53\u524D\u6682\u65E0\u5546\u5BB6\u6570\u636E" : ""}${pinTokenNote}`,
871
+ className: `dsh-a6-unprobed-hint ${model.probeError ? "error" : ""}`,
872
+ "data-tooltip": model.probeError || void 0,
796
873
  "data-tooltip-pos": "down",
797
- children: !hasMerchant && model.pinnedChannelId ? `\u5DF2\u56FA\u5B9A\u5230\u5546\u6237 #${model.pinnedChannelId}` : "\u5DF2\u56FA\u5B9A\u5230\u5176\u4ED6\u5546\u5BB6"
874
+ children: isProbing ? "\u5546\u5BB6\u63A2\u6D4B\u4E2D..." : isQueued ? "\u6392\u961F\u7B49\u5F85\u63A2\u6D4B..." : model.probeError ? "\u63A2\u6D4B\u5931\u8D25" : "\u5C1A\u672A\u63A2\u6D4B\u5546\u5BB6"
798
875
  }
799
- ),
800
- isChannelDisabled && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-badge disabled", "data-tooltip": "\u5F53\u524D\u5546\u5BB6\u5DF2\u5BF9\u8BE5\u6A21\u578B\u7981\u7528\uFF0C\u8DEF\u7531\u4E0D\u4F1A\u547D\u4E2D\u6B64\u6E20\u9053", "data-tooltip-pos": "down", children: "\u5DF2\u7981\u7528" })
801
- ] }),
802
- merchant?.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-sub-desc", children: merchant.description })
803
- ] }) }),
804
- merchant ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-pricing", children: [
805
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-price-col", children: [
806
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u5165\u4EF7 (1M)", children: merchant.input_price_cny }),
807
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u8BFB (1M)", children: merchant.cache_read_price_cny })
808
- ] }),
809
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-price-col", children: [
810
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u51FA\u4EF7 (1M)", children: merchant.output_price_cny }),
811
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u5199 (1M)", children: merchant.cache_write_price_cny })
812
- ] }),
813
- blend100mValid && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-blend-pill", title: blendTitle, children: [
814
- "\u2248 \xA5",
815
- fmtSig(blend100m),
816
- "/\u4EBF"
817
- ] }),
818
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-ratio-pill", title: "\u5B9E\u65F6\u500D\u7387\u6BD4\u5B98\u65B9\u4EF7", children: ratioText })
819
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-pricing unprobed", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
820
- "div",
821
- {
822
- className: `dsh-a6-unprobed-hint ${model.probeError ? "error" : ""}`,
823
- "data-tooltip": model.probeError || void 0,
824
- "data-tooltip-pos": "down",
825
- children: isProbing ? "\u5546\u5BB6\u63A2\u6D4B\u4E2D..." : isQueued ? "\u6392\u961F\u7B49\u5F85\u63A2\u6D4B..." : model.probeError ? "\u63A2\u6D4B\u5931\u8D25" : "\u5C1A\u672A\u63A2\u6D4B\u5546\u5BB6"
826
- }
827
- ) }),
828
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-uptime", children: [
829
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
830
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "\u5B9E\u65F6" }),
831
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: renderRealtimeDots() }),
832
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant ? `${merchant.recent_success_rate_pct.toFixed(1)}%` : "100.0%" })
833
- ] }),
834
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
835
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "24h" }),
836
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: render24hDots() }),
837
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant ? `${merchant.success_rate_24h_pct.toFixed(1)}%` : "99.3%" })
838
- ] }),
839
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
840
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "7d" }),
841
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: render7dDots() }),
842
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant?.sr_7d_state === "no_data" ? "-" : merchant?.success_rate_7d_pct ? `${merchant.success_rate_7d_pct.toFixed(1)}%` : "-" })
843
- ] })
844
- ] }),
845
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-perf", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-perf-row", children: [
846
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-latency-text", children: latencySec }),
847
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-cache-hit-text", children: [
848
- cacheHitPct.toFixed(1),
849
- "%"
876
+ ) }),
877
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-uptime", children: [
878
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
879
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "\u5B9E\u65F6" }),
880
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: renderRealtimeDots() }),
881
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant ? `${merchant.recent_success_rate_pct.toFixed(1)}%` : "100.0%" })
882
+ ] }),
883
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
884
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "24h" }),
885
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: render24hDots() }),
886
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant ? `${merchant.success_rate_24h_pct.toFixed(1)}%` : "99.3%" })
887
+ ] }),
888
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
889
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "7d" }),
890
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: render7dDots() }),
891
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant?.sr_7d_state === "no_data" ? "-" : merchant?.success_rate_7d_pct ? `${merchant.success_rate_7d_pct.toFixed(1)}%` : "-" })
892
+ ] })
893
+ ] }),
894
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-perf", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-perf-row", children: [
895
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-latency-text", children: latencySec }),
896
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-cache-hit-text", children: [
897
+ cacheHitPct.toFixed(1),
898
+ "%"
899
+ ] }),
900
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-hit-track", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
901
+ "div",
902
+ {
903
+ className: "dsh-a6-hit-fill",
904
+ style: { width: `${Math.min(100, Math.max(0, cacheHitPct))}%` }
905
+ }
906
+ ) })
907
+ ] }) }),
908
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-tags", children: (merchant?.labels || ["\u7A33\u5B9A", "\u4F4E\u4EF7", "\u9AD8\u901F", "\u9AD8\u8D28"]).map((lbl, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `dsh-a6-smart-pill ${getTagClass(lbl)}`, children: lbl }, idx)) })
850
909
  ] }),
851
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-hit-track", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
852
- "div",
853
- {
854
- className: "dsh-a6-hit-fill",
855
- style: { width: `${Math.min(100, Math.max(0, cacheHitPct))}%` }
856
- }
857
- ) })
858
- ] }) }),
859
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-tags", children: (merchant?.labels || ["\u7A33\u5B9A", "\u4F4E\u4EF7", "\u9AD8\u901F", "\u9AD8\u8D28"]).map((lbl, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `dsh-a6-smart-pill ${getTagClass(lbl)}`, children: lbl }, idx)) })
860
- ] }),
861
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-card-footer", children: [
862
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-time-stack", children: [
863
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
864
- "span",
865
- {
866
- className: "dsh-a6-time-ago",
867
- "data-tooltip": "\u8BE5\u5546\u6237\u8DEF\u7EBF\u5168\u7F51\u6700\u8FD1\u4E00\u6B21\u6210\u529F\u54CD\u5E94\u65F6\u95F4",
868
- children: [
869
- "\u5168\u7F51\u6700\u8FD1\uFF1A",
870
- merchant?.last_success_text || "\u521A\u521A"
871
- ]
872
- }
873
- ),
874
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
875
- "span",
876
- {
877
- className: `dsh-a6-time-ago dsh-a6-route-snapshot${model.lastRoutedAt ? "" : " never"}`,
878
- "data-tooltip": model.lastRoutedAt ? `\u4E2A\u4EBA\u6700\u540E\u4E00\u6B21\u8BF7\u6C42\u8BE5\u5546\u5BB6\u7684\u8BE5\u6A21\u578B ${formatAbsolute(model.lastRoutedAt)}` : "\u65E5\u5FD7\u4E2D\u6682\u65E0\u8BE5\u5546\u5BB6\u7684\u8BE5\u6A21\u578B\u8DEF\u7531\u8BB0\u5F55",
879
- children: [
880
- "\u4E2A\u4EBA\u6700\u8FD1\uFF1A",
881
- model.lastRoutedText || "\u4ECE\u672A\u8DEF\u7531"
882
- ]
883
- }
884
- )
885
- ] }),
886
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-actions", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-actions-btns", children: [
887
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
888
- "button",
889
- {
890
- type: "button",
891
- className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
892
- onClick: handleProbe,
893
- disabled: isProbing || isQueued,
894
- "data-tooltip": isQueued ? "\u6B63\u5728\u5168\u91CF\u63A2\u6D4B\u961F\u5217\u4E2D\u7B49\u5F85\uFF0C\u8BF7\u52FF\u91CD\u590D\u70B9\u51FB" : "\u5411\u8BE5\u6A21\u578B\u53D1\u9001\u4E00\u6B21\u8BF7\u6C42\u4EE5\u63A2\u6D4B\u5E76\u6355\u83B7\u5176\u5B9E\u9645\u547D\u4E2D\u7684\u5546\u6237 ID\u3001\u4EF7\u683C\u53CA\u5065\u5EB7\u5EA6\u6307\u6807\uFF08\u6D88\u8017\u5C11\u91CFToken\uFF09",
895
- children: isProbing ? "\u63A2\u6D4B\u4E2D..." : isQueued ? "\u7B49\u5F85\u63A2\u6D4B" : "\u63A2\u6D4B\u5546\u5BB6"
896
- }
897
- ),
898
- isPinnedHere ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
899
- "button",
900
- {
901
- type: "button",
902
- className: "dsh-a6-btn dsh-a6-btn-danger dsh-a6-btn-sm",
903
- onClick: handleUnpin,
904
- disabled: isBusy || !canWebAction || model.pinTokenMatched === false || isProbing || isQueued,
905
- "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u53D6\u6D88\u56FA\u5B9A" : model.pinTokenMatched === false ? "\u8BE5\u56FA\u5B9A\u5C5E\u4E8E\u5176\u4ED6\u4EE4\u724C\uFF0C\u65E0\u6CD5\u5728\u6B64\u53D6\u6D88\uFF1B\u5982\u9700\u53D6\u6D88\u8BF7\u5230\u5B98\u7F51\u6216\u5148\u4E3A\u5F53\u524D\u4EE4\u724C\u56FA\u5B9A\u6B64\u5546\u5BB6" : !canWebAction ? "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD" : model.pinTokenMatched === void 0 ? "\u672A\u80FD\u786E\u8BA4\u8BE5\u56FA\u5B9A\u662F\u5426\u5C5E\u4E8E\u5F53\u524D\u4EE4\u724C\uFF0C\u70B9\u51FB\u540E\u5C06\u91CD\u65B0\u89E3\u6790\u5E76\u5C1D\u8BD5\u53D6\u6D88\uFF1B\u82E5\u5931\u8D25\u53EF\u5148\u63A2\u6D4B\u4E00\u6B21\u540E\u91CD\u8BD5\uFF0C\u6216\u5230\u5B98\u7F51\u624B\u52A8\u53D6\u6D88" : "\u53D6\u6D88\u56FA\u5B9A\u540E\u6062\u590D\u667A\u80FD\u4F18\u9009\u8DEF\u7531\uFF0C\u53EF\u91CD\u65B0\u63A2\u6D4B\u540E\u518D\u51B3\u5B9A\u662F\u5426\u56FA\u5B9A",
906
- children: isBusy ? "\u5904\u7406\u4E2D..." : "\u53D6\u6D88\u56FA\u5B9A"
907
- }
908
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
909
- "button",
910
- {
911
- type: "button",
912
- className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
913
- onClick: handleOpenPinConfirm,
914
- disabled: isBusy || !hasMerchant || !canWebAction || isProbing || isQueued,
915
- "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u56FA\u5B9A\u5546\u5BB6" : !hasMerchant ? "\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D" : !canWebAction ? "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD" : "\u628A\u5F53\u524D\u5546\u5BB6\u56FA\u5B9A\u4E3A\u8BE5\u6A21\u578B\u7684\u670D\u52A1\u6E20\u9053\uFF08\u4F18\u5148\u8DEF\u7531\uFF0C\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009\uFF09",
916
- children: isBusy ? "\u5904\u7406\u4E2D..." : "\u56FA\u5B9A\u5546\u5BB6"
917
- }
918
- ),
919
- isChannelDisabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
920
- "button",
921
- {
922
- type: "button",
923
- className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
924
- onClick: handleRestore,
925
- disabled: isBusy || !canWebAction || isProbing || isQueued,
926
- "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u6062\u590D" : canWebAction ? "\u6062\u590D\u8BE5\u5546\u5BB6\u5BF9\u6B64\u6A21\u578B\u7684\u670D\u52A1" : "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD",
927
- children: isBusy ? "\u5904\u7406\u4E2D..." : "\u6062\u590D"
928
- }
929
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
930
- "button",
931
- {
932
- type: "button",
933
- className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
934
- onClick: handleDisable,
935
- disabled: isBusy || !hasMerchant || !canWebAction || isProbing || isQueued,
936
- "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u7981\u7528" : !hasMerchant ? "\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D" : !canWebAction ? "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD" : "\u7981\u7528\u5F53\u524D\u5546\u5BB6\u5BF9\u8BE5\u6A21\u578B\u7684\u670D\u52A1\uFF0C\u8DEF\u7531\u5C06\u4E0D\u518D\u547D\u4E2D\u6B64\u6E20\u9053",
937
- children: isBusy ? "\u5904\u7406\u4E2D..." : "\u7981\u7528"
938
- }
939
- ),
940
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
941
- "button",
942
- {
943
- type: "button",
944
- className: `dsh-a6-btn dsh-a6-btn-sm ${model.inDsh ? "dsh-a6-btn-in-dsh" : "dsh-a6-btn-primary"}`,
945
- onClick: handleToggleDsh,
946
- "data-tooltip": model.inDsh ? "\u5DF2\u52A0\u5165 DSH \u6A21\u578B\u9009\u62E9\u5668 (\u70B9\u51FB\u79FB\u9664)" : "\u6DFB\u52A0\u81F3 DSH \u6A21\u578B\u9009\u62E9\u5668",
947
- children: model.inDsh ? "\u79FB\u9664\u6A21\u578B" : "\u6DFB\u52A0\u6A21\u578B"
948
- }
949
- ),
950
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
951
- "button",
952
- {
953
- type: "button",
954
- className: `dsh-a6-expand-toggle-btn ${expanded ? "open" : ""}`,
955
- onClick: () => setExpanded(!expanded),
956
- "data-tooltip": expanded ? "\u6536\u8D77\u4EF7\u683C\u8BE6\u60C5" : "\u5C55\u5F00\u5B98\u65B9\u57FA\u51C6\u4EF7\u4E0E\u5546\u6237\u5B9E\u65F6\u4EF7\u5BF9\u6BD4\u8868",
957
- "data-tooltip-pos": "left",
958
- children: expanded ? "\u6536\u8D77" : "\u8BE6\u60C5"
959
- }
960
- )
961
- ] }) }),
962
- actionError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-action-error", role: "alert", children: actionError })
963
- ] }),
964
- expanded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-container", children: [
965
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-top-row", children: [
966
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-dt-left", children: [
967
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-label", children: "\u6E20\u9053\u8BF4\u660E" }),
968
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-desc", children: merchant?.description || "\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A" })
910
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-card-footer", children: [
911
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-time-stack", children: [
912
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
913
+ "span",
914
+ {
915
+ className: "dsh-a6-time-ago",
916
+ "data-tooltip": "\u8BE5\u5546\u6237\u8DEF\u7EBF\u5168\u7F51\u6700\u8FD1\u4E00\u6B21\u6210\u529F\u54CD\u5E94\u65F6\u95F4",
917
+ children: [
918
+ "\u5168\u7F51\u6700\u8FD1\uFF1A",
919
+ merchant?.last_success_text || "\u521A\u521A"
920
+ ]
921
+ }
922
+ ),
923
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
924
+ "span",
925
+ {
926
+ className: `dsh-a6-time-ago dsh-a6-route-snapshot${model.lastRoutedAt ? "" : " never"}`,
927
+ "data-tooltip": model.lastRoutedAt ? `\u4E2A\u4EBA\u6700\u540E\u4E00\u6B21\u8BF7\u6C42\u8BE5\u5546\u5BB6\u7684\u8BE5\u6A21\u578B ${formatAbsolute(model.lastRoutedAt)}` : "\u65E5\u5FD7\u4E2D\u6682\u65E0\u8BE5\u5546\u5BB6\u7684\u8BE5\u6A21\u578B\u8DEF\u7531\u8BB0\u5F55",
928
+ children: [
929
+ "\u4E2A\u4EBA\u6700\u8FD1\uFF1A",
930
+ model.lastRoutedText || "\u4ECE\u672A\u8DEF\u7531"
931
+ ]
932
+ }
933
+ )
934
+ ] }),
935
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-actions", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-actions-btns", children: [
936
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
937
+ "button",
938
+ {
939
+ type: "button",
940
+ className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
941
+ onClick: handleProbe,
942
+ disabled: isProbing || isQueued,
943
+ "data-tooltip": isQueued ? "\u6B63\u5728\u5168\u91CF\u63A2\u6D4B\u961F\u5217\u4E2D\u7B49\u5F85\uFF0C\u8BF7\u52FF\u91CD\u590D\u70B9\u51FB" : "\u5411\u8BE5\u6A21\u578B\u53D1\u9001\u4E00\u6B21\u8BF7\u6C42\u4EE5\u63A2\u6D4B\u5E76\u6355\u83B7\u5176\u5B9E\u9645\u547D\u4E2D\u7684\u5546\u6237 ID\u3001\u4EF7\u683C\u53CA\u5065\u5EB7\u5EA6\u6307\u6807\uFF08\u6D88\u8017\u5C11\u91CFToken\uFF09",
944
+ children: isProbing ? "\u63A2\u6D4B\u4E2D..." : isQueued ? "\u7B49\u5F85\u63A2\u6D4B" : "\u63A2\u6D4B\u5546\u5BB6"
945
+ }
946
+ ),
947
+ isPinnedHere ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
948
+ "button",
949
+ {
950
+ type: "button",
951
+ className: "dsh-a6-btn dsh-a6-btn-danger dsh-a6-btn-sm",
952
+ onClick: handleUnpin,
953
+ disabled: isBusy || !canWebAction || model.pinTokenMatched === false || isProbing || isQueued,
954
+ "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u53D6\u6D88\u56FA\u5B9A" : model.pinTokenMatched === false ? "\u8BE5\u56FA\u5B9A\u5C5E\u4E8E\u5176\u4ED6\u4EE4\u724C\uFF0C\u65E0\u6CD5\u5728\u6B64\u53D6\u6D88\uFF1B\u5982\u9700\u53D6\u6D88\u8BF7\u5230\u5B98\u7F51\u6216\u5148\u4E3A\u5F53\u524D\u4EE4\u724C\u56FA\u5B9A\u6B64\u5546\u5BB6" : !canWebAction ? "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD" : model.pinTokenMatched === void 0 ? "\u672A\u80FD\u786E\u8BA4\u8BE5\u56FA\u5B9A\u662F\u5426\u5C5E\u4E8E\u5F53\u524D\u4EE4\u724C\uFF0C\u70B9\u51FB\u540E\u5C06\u91CD\u65B0\u89E3\u6790\u5E76\u5C1D\u8BD5\u53D6\u6D88\uFF1B\u82E5\u5931\u8D25\u53EF\u5148\u63A2\u6D4B\u4E00\u6B21\u540E\u91CD\u8BD5\uFF0C\u6216\u5230\u5B98\u7F51\u624B\u52A8\u53D6\u6D88" : "\u53D6\u6D88\u56FA\u5B9A\u540E\u6062\u590D\u667A\u80FD\u4F18\u9009\u8DEF\u7531\uFF0C\u53EF\u91CD\u65B0\u63A2\u6D4B\u540E\u518D\u51B3\u5B9A\u662F\u5426\u56FA\u5B9A",
955
+ children: isBusy ? "\u5904\u7406\u4E2D..." : "\u53D6\u6D88\u56FA\u5B9A"
956
+ }
957
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
958
+ "button",
959
+ {
960
+ type: "button",
961
+ className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
962
+ onClick: handleOpenPinConfirm,
963
+ disabled: isBusy || !hasMerchant || !canWebAction || isProbing || isQueued,
964
+ "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u56FA\u5B9A\u5546\u5BB6" : !hasMerchant ? "\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D" : !canWebAction ? "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD" : "\u628A\u5F53\u524D\u5546\u5BB6\u56FA\u5B9A\u4E3A\u8BE5\u6A21\u578B\u7684\u670D\u52A1\u6E20\u9053\uFF08\u4F18\u5148\u8DEF\u7531\uFF0C\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009\uFF09",
965
+ children: isBusy ? "\u5904\u7406\u4E2D..." : "\u56FA\u5B9A\u5546\u5BB6"
966
+ }
967
+ ),
968
+ isChannelDisabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
969
+ "button",
970
+ {
971
+ type: "button",
972
+ className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
973
+ onClick: handleRestore,
974
+ disabled: isBusy || !canWebAction || isProbing || isQueued,
975
+ "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u6062\u590D" : canWebAction ? "\u6062\u590D\u8BE5\u5546\u5BB6\u5BF9\u6B64\u6A21\u578B\u7684\u670D\u52A1" : "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD",
976
+ children: isBusy ? "\u5904\u7406\u4E2D..." : "\u6062\u590D"
977
+ }
978
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
979
+ "button",
980
+ {
981
+ type: "button",
982
+ className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
983
+ onClick: handleDisable,
984
+ disabled: isBusy || !hasMerchant || !canWebAction || isProbing || isQueued,
985
+ "data-tooltip": isProbing || isQueued ? "\u63A2\u6D4B\u5B8C\u6210\u540E\u518D\u7981\u7528" : !hasMerchant ? "\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D" : !canWebAction ? "\u9700\u5148\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD" : "\u7981\u7528\u5F53\u524D\u5546\u5BB6\u5BF9\u8BE5\u6A21\u578B\u7684\u670D\u52A1\uFF0C\u8DEF\u7531\u5C06\u4E0D\u518D\u547D\u4E2D\u6B64\u6E20\u9053",
986
+ children: isBusy ? "\u5904\u7406\u4E2D..." : "\u7981\u7528"
987
+ }
988
+ ),
989
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
990
+ "button",
991
+ {
992
+ type: "button",
993
+ className: `dsh-a6-btn dsh-a6-btn-sm ${model.inDsh ? "dsh-a6-btn-in-dsh" : "dsh-a6-btn-primary"}`,
994
+ onClick: handleToggleDsh,
995
+ "data-tooltip": model.inDsh ? "\u5DF2\u52A0\u5165 DSH \u6A21\u578B\u9009\u62E9\u5668 (\u70B9\u51FB\u79FB\u9664)" : "\u6DFB\u52A0\u81F3 DSH \u6A21\u578B\u9009\u62E9\u5668",
996
+ children: model.inDsh ? "\u79FB\u9664\u6A21\u578B" : "\u6DFB\u52A0\u6A21\u578B"
997
+ }
998
+ ),
999
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1000
+ "button",
1001
+ {
1002
+ type: "button",
1003
+ className: `dsh-a6-expand-toggle-btn ${expanded ? "open" : ""}`,
1004
+ onClick: () => setExpanded(!expanded),
1005
+ "data-tooltip": expanded ? "\u6536\u8D77\u4EF7\u683C\u8BE6\u60C5" : "\u5C55\u5F00\u5B98\u65B9\u57FA\u51C6\u4EF7\u4E0E\u5546\u6237\u5B9E\u65F6\u4EF7\u5BF9\u6BD4\u8868",
1006
+ "data-tooltip-pos": "left",
1007
+ children: expanded ? "\u6536\u8D77" : "\u8BE6\u60C5"
1008
+ }
1009
+ )
1010
+ ] }) }),
1011
+ actionError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-action-error", role: "alert", children: actionError })
969
1012
  ] }),
970
- merchant?.channel_name && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-dt-right", children: [
971
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-label", children: "\u547D\u4E2D\u7EBF\u8DEF" }),
972
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-dt-channel-name", children: [
973
- merchant.channel_name,
974
- " (ID: ",
975
- merchant.channel_id,
976
- ")"
977
- ] })
978
- ] })
979
- ] }),
980
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dt-divider" }),
981
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dt-table-col", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "dsh-a6-price-table", children: [
982
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
983
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "dsh-a6-th-blank" }),
984
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u5165\u4EF7 (1M)" }),
985
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u51FA\u4EF7 (1M)" }),
986
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7F13\u5B58\u8BFB (1M)" }),
987
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7F13\u5B58\u5199 (1M)" })
988
- ] }) }),
989
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
990
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "dsh-a6-tr-official", children: [
991
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-label", children: "\u5B98\u65B9\u4EF7" }),
992
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.input_cny || "\xA526.884" }),
993
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.output_cny || "\xA5134.418" }),
994
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.cache_read_cny || "\xA52.688" }),
995
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.cache_write_cny || "\xA533.605" })
1013
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-container", children: [
1014
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-top-row", children: [
1015
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-dt-left", children: [
1016
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-label", children: "\u6E20\u9053\u8BF4\u660E" }),
1017
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-desc", children: merchant?.description || "\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A" })
1018
+ ] }),
1019
+ merchant?.channel_name && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-dt-right", children: [
1020
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-label", children: "\u547D\u4E2D\u7EBF\u8DEF" }),
1021
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-dt-channel-name", children: [
1022
+ merchant.channel_name,
1023
+ " (ID: ",
1024
+ merchant.channel_id,
1025
+ ")"
1026
+ ] })
1027
+ ] })
996
1028
  ] }),
997
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "dsh-a6-tr-merchant", children: [
998
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-label", children: "\u5546\u6237\u4EF7" }),
999
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.input_price_cny || "\xA50.1364" }),
1000
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.output_price_cny || "\xA50.6822" }),
1001
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.cache_read_price_cny || "\xA50.0136" }),
1002
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.cache_write_price_cny || "\xA50.1705" })
1003
- ] })
1004
- ] })
1005
- ] }) })
1006
- ] }),
1007
- pinConfirmOpen && merchant && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1008
- "div",
1009
- {
1010
- className: "dsh-a6-pin-modal-overlay",
1011
- onClick: (e) => {
1012
- e.stopPropagation();
1013
- setPinConfirmOpen(false);
1014
- },
1015
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1029
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dt-divider" }),
1030
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dt-table-col", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "dsh-a6-price-table", children: [
1031
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
1032
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "dsh-a6-th-blank" }),
1033
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u5165\u4EF7 (1M)" }),
1034
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u51FA\u4EF7 (1M)" }),
1035
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7F13\u5B58\u8BFB (1M)" }),
1036
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7F13\u5B58\u5199 (1M)" })
1037
+ ] }) }),
1038
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
1039
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "dsh-a6-tr-official", children: [
1040
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-label", children: "\u5B98\u65B9\u4EF7" }),
1041
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.input_cny || "\xA526.884" }),
1042
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.output_cny || "\xA5134.418" }),
1043
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.cache_read_cny || "\xA52.688" }),
1044
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.cache_write_cny || "\xA533.605" })
1045
+ ] }),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "dsh-a6-tr-merchant", children: [
1047
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-label", children: "\u5546\u6237\u4EF7" }),
1048
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.input_price_cny || "\xA50.1364" }),
1049
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.output_price_cny || "\xA50.6822" }),
1050
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.cache_read_price_cny || "\xA50.0136" }),
1051
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.cache_write_price_cny || "\xA50.1705" })
1052
+ ] })
1053
+ ] })
1054
+ ] }) })
1055
+ ] }),
1056
+ pinConfirmOpen && merchant && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1016
1057
  "div",
1017
1058
  {
1018
- className: "dsh-a6-pin-modal",
1019
- role: "dialog",
1020
- "aria-modal": "true",
1021
- "aria-label": "\u56FA\u5B9A\u5546\u5BB6\u786E\u8BA4",
1022
- onClick: (e) => e.stopPropagation(),
1023
- children: [
1024
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-pin-modal-title", children: "\u56FA\u5B9A\u5546\u5BB6" }),
1025
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-body", children: [
1026
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-row", children: [
1027
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-label", children: "\u6A21\u578B" }),
1028
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-value", children: model.model_name })
1029
- ] }),
1030
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-row", children: [
1031
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-label", children: "\u5546\u5BB6" }),
1032
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-pin-modal-value", children: [
1033
- merchant.channel_name,
1034
- " (ID: ",
1035
- merchant.channel_id,
1036
- ")"
1037
- ] })
1038
- ] }),
1039
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-row", children: [
1040
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-label", children: "\u5F53\u524D\u4EF7" }),
1041
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-pin-modal-value", children: [
1042
- "\u8F93\u5165 ",
1043
- merchant.input_price_cny,
1044
- " \xB7 \u8F93\u51FA ",
1045
- merchant.output_price_cny
1059
+ className: "dsh-a6-pin-modal-overlay",
1060
+ onClick: (e) => {
1061
+ e.stopPropagation();
1062
+ setPinConfirmOpen(false);
1063
+ },
1064
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1065
+ "div",
1066
+ {
1067
+ className: "dsh-a6-pin-modal",
1068
+ role: "dialog",
1069
+ "aria-modal": "true",
1070
+ "aria-label": "\u56FA\u5B9A\u5546\u5BB6\u786E\u8BA4",
1071
+ onClick: (e) => e.stopPropagation(),
1072
+ children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-pin-modal-title", children: "\u56FA\u5B9A\u5546\u5BB6" }),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-body", children: [
1075
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-row", children: [
1076
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-label", children: "\u6A21\u578B" }),
1077
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-value", children: model.model_name })
1078
+ ] }),
1079
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-row", children: [
1080
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-label", children: "\u5546\u5BB6" }),
1081
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-pin-modal-value", children: [
1082
+ merchant.channel_name,
1083
+ " (ID: ",
1084
+ merchant.channel_id,
1085
+ ")"
1086
+ ] })
1087
+ ] }),
1088
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-row", children: [
1089
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-pin-modal-label", children: "\u5F53\u524D\u4EF7" }),
1090
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-pin-modal-value", children: [
1091
+ "\u8F93\u5165 ",
1092
+ merchant.input_price_cny,
1093
+ " \xB7 \u8F93\u51FA ",
1094
+ merchant.output_price_cny
1095
+ ] })
1096
+ ] }),
1097
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-a6-pin-modal-note", children: "\u56FA\u5B9A\u540E\u8BE5\u6A21\u578B\u7684\u6D41\u91CF\u4F18\u5148\u8D70\u6B64\u5546\u5BB6\uFF1B\u5546\u5BB6\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009\uFF08\u5E73\u53F0\u9ED8\u8BA4\uFF09\u3002\u56FA\u5B9A\u751F\u6548\u4E8E\u5F53\u524D API Key \u4EE4\u724C\uFF0C\u53EF\u968F\u65F6\u53D6\u6D88\u3002" }),
1098
+ actionError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-action-error", children: actionError })
1099
+ ] }),
1100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-foot", children: [
1101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1102
+ "button",
1103
+ {
1104
+ type: "button",
1105
+ className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
1106
+ onClick: () => setPinConfirmOpen(false),
1107
+ disabled: isBusy,
1108
+ children: "\u53D6\u6D88"
1109
+ }
1110
+ ),
1111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1112
+ "button",
1113
+ {
1114
+ type: "button",
1115
+ className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
1116
+ onClick: handleConfirmPin,
1117
+ disabled: isBusy,
1118
+ children: isBusy ? "\u56FA\u5B9A\u4E2D..." : "\u786E\u8BA4\u56FA\u5B9A"
1119
+ }
1120
+ )
1046
1121
  ] })
1047
- ] }),
1048
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-a6-pin-modal-note", children: "\u56FA\u5B9A\u540E\u8BE5\u6A21\u578B\u7684\u6D41\u91CF\u4F18\u5148\u8D70\u6B64\u5546\u5BB6\uFF1B\u5546\u5BB6\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009\uFF08\u5E73\u53F0\u9ED8\u8BA4\uFF09\u3002\u56FA\u5B9A\u751F\u6548\u4E8E\u5F53\u524D API Key \u4EE4\u724C\uFF0C\u53EF\u968F\u65F6\u53D6\u6D88\u3002" }),
1049
- actionError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-action-error", children: actionError })
1050
- ] }),
1051
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-pin-modal-foot", children: [
1052
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1053
- "button",
1054
- {
1055
- type: "button",
1056
- className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
1057
- onClick: () => setPinConfirmOpen(false),
1058
- disabled: isBusy,
1059
- children: "\u53D6\u6D88"
1060
- }
1061
- ),
1062
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1063
- "button",
1064
- {
1065
- type: "button",
1066
- className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
1067
- onClick: handleConfirmPin,
1068
- disabled: isBusy,
1069
- children: isBusy ? "\u56FA\u5B9A\u4E2D..." : "\u786E\u8BA4\u56FA\u5B9A"
1070
- }
1071
- )
1072
- ] })
1073
- ]
1122
+ ]
1123
+ }
1124
+ )
1074
1125
  }
1075
1126
  )
1076
- }
1077
- )
1078
- ] });
1127
+ ]
1128
+ }
1129
+ );
1079
1130
  };
1080
1131
 
1081
1132
  // src/client/components/BalanceCard.tsx
@@ -4746,6 +4797,161 @@ body.dsh-a6api-tooltip-active [data-tooltip]::before {
4746
4797
  border-color: #ef4444 !important;
4747
4798
  color: #ffffff !important;
4748
4799
  }
4800
+
4801
+ /* ============================================================
4802
+ * \u63A2\u6D4B\u5B8C\u6210 \u2192 \u5361\u7247\u5237\u65B0\u52A8\u753B\uFF08MerchantCard\uFF0C\u4FA7\u8FB9\u680F\u6D6E\u5C42\u4E0E\u8BBE\u7F6E\u9875\u5171\u7528\uFF09
4803
+ * \u89E6\u53D1\uFF1AprobeStatus \u7531 probing \u8DC3\u8FC1\u5230 success/error \u65F6\u6302 .dsh-a6-card-refresh
4804
+ * refresh-ok = \u6210\u529F\u53D6\u5230\u5546\u6237\uFF1Brefresh-err = \u63A2\u6D4B\u5931\u8D25
4805
+ * \u6839\u8282\u70B9\u4EC5\u6539 box-shadow/::after\uFF08\u4E0D\u52A0 transform/filter\uFF09\uFF0C\u907F\u514D\u628A\u5185\u90E8
4806
+ * position:fixed \u7684\u56FA\u5B9A\u5F39\u7A97\u5377\u5165\u81EA\u8EAB containing block\u3002
4807
+ * ============================================================ */
4808
+ .dsh-a6-official-card.dsh-a6-card-refresh {
4809
+ position: relative;
4810
+ z-index: 0;
4811
+ overflow: hidden;
4812
+ }
4813
+
4814
+ /* 1) \u5149\u5E26\u4ECE\u5DE6\u4FA7\u626B\u8FC7\u6574\u5361 */
4815
+ .dsh-a6-card-refresh::before {
4816
+ content: '';
4817
+ position: absolute;
4818
+ top: 0;
4819
+ bottom: 0;
4820
+ left: 0;
4821
+ width: 55%;
4822
+ z-index: 3;
4823
+ pointer-events: none;
4824
+ background: linear-gradient(
4825
+ 100deg,
4826
+ rgba(56, 189, 248, 0) 0%,
4827
+ rgba(56, 189, 248, 0.12) 45%,
4828
+ rgba(125, 211, 252, 0.22) 50%,
4829
+ rgba(56, 189, 248, 0.12) 55%,
4830
+ rgba(56, 189, 248, 0) 100%
4831
+ );
4832
+ transform: translateX(-120%);
4833
+ animation: dsh-a6-refresh-sweep 0.85s cubic-bezier(0.4, 0, 0.2, 1) forwards;
4834
+ }
4835
+
4836
+ @keyframes dsh-a6-refresh-sweep {
4837
+ 0% { transform: translateX(-120%); }
4838
+ 100% { transform: translateX(230%); }
4839
+ }
4840
+
4841
+ /* 2) \u5361\u7247\u8FB9\u6846/\u5916\u53D1\u5149\u8109\u51B2\uFF08\u7EFF=\u6210\u529F\uFF0C\u7EA2=\u5931\u8D25\uFF09 */
4842
+ .dsh-a6-card-refresh.refresh-ok {
4843
+ animation: dsh-a6-refresh-glow-ok 1.15s ease-out;
4844
+ }
4845
+ .dsh-a6-card-refresh.refresh-err {
4846
+ animation: dsh-a6-refresh-glow-err 1.15s ease-out;
4847
+ }
4848
+
4849
+ @keyframes dsh-a6-refresh-glow-ok {
4850
+ 0% {
4851
+ border-color: #10b981;
4852
+ box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.45), 0 1px 3px rgba(0, 0, 0, 0.02);
4853
+ }
4854
+ 35% {
4855
+ box-shadow: 0 0 0 5px rgba(16, 185, 129, 0.12), 0 2px 10px rgba(16, 185, 129, 0.22);
4856
+ }
4857
+ 100% {
4858
+ border-color: var(--dsw-alias-border-l2, #e2e8f0);
4859
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
4860
+ }
4861
+ }
4862
+ @keyframes dsh-a6-refresh-glow-err {
4863
+ 0% {
4864
+ border-color: #ef4444;
4865
+ box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.45), 0 1px 3px rgba(0, 0, 0, 0.02);
4866
+ }
4867
+ 35% {
4868
+ box-shadow: 0 0 0 5px rgba(239, 68, 68, 0.12), 0 2px 10px rgba(239, 68, 68, 0.22);
4869
+ }
4870
+ 100% {
4871
+ border-color: var(--dsw-alias-border-l2, #e2e8f0);
4872
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
4873
+ }
4874
+ }
4875
+
4876
+ /* 3) \u53F3\u4E0A\u89D2\u77AC\u65F6\u72B6\u6001\u5FBD\u6807\u6DE1\u5165\u4E0A\u6D6E */
4877
+ .dsh-a6-refresh-flag {
4878
+ position: absolute;
4879
+ top: 8px;
4880
+ right: 12px;
4881
+ z-index: 4;
4882
+ font-size: 11px;
4883
+ font-weight: 600;
4884
+ line-height: 1;
4885
+ padding: 4px 8px;
4886
+ border-radius: 999px;
4887
+ pointer-events: none;
4888
+ white-space: nowrap;
4889
+ opacity: 0;
4890
+ animation: dsh-a6-refresh-flag-in 1.45s ease-out forwards;
4891
+ }
4892
+ .dsh-a6-refresh-flag.ok {
4893
+ color: #059669;
4894
+ background: rgba(16, 185, 129, 0.12);
4895
+ border: 1px solid rgba(16, 185, 129, 0.4);
4896
+ }
4897
+ .dsh-a6-refresh-flag.err {
4898
+ color: #b91c1c;
4899
+ background: rgba(239, 68, 68, 0.1);
4900
+ border: 1px solid rgba(239, 68, 68, 0.38);
4901
+ }
4902
+
4903
+ @keyframes dsh-a6-refresh-flag-in {
4904
+ 0% { opacity: 0; transform: translateY(6px); }
4905
+ 22% { opacity: 1; transform: translateY(0); }
4906
+ 78% { opacity: 1; }
4907
+ 100% { opacity: 0; }
4908
+ }
4909
+
4910
+ /* 4) \u4E3B\u4F53\u4FE1\u606F\u5217\u8F7B\u5FAE\u4E0A\u6D6E\u6DE1\u5165\uFF08\u9519\u5CF0\uFF09 */
4911
+ .dsh-a6-card-refresh .dsh-a6-bar-identity {
4912
+ animation: dsh-a6-refresh-rise 0.42s ease-out 0.05s both;
4913
+ }
4914
+ .dsh-a6-card-refresh .dsh-a6-bar-pricing {
4915
+ animation: dsh-a6-refresh-rise 0.42s ease-out 0.12s both;
4916
+ }
4917
+ .dsh-a6-card-refresh .dsh-a6-bar-uptime {
4918
+ animation: dsh-a6-refresh-rise 0.42s ease-out 0.19s both;
4919
+ }
4920
+ .dsh-a6-card-refresh .dsh-a6-bar-perf {
4921
+ animation: dsh-a6-refresh-rise 0.42s ease-out 0.26s both;
4922
+ }
4923
+ .dsh-a6-card-refresh .dsh-a6-bar-tags {
4924
+ animation: dsh-a6-refresh-rise 0.42s ease-out 0.32s both;
4925
+ }
4926
+
4927
+ @keyframes dsh-a6-refresh-rise {
4928
+ 0% { opacity: 0.35; transform: translateY(6px); }
4929
+ 100% { opacity: 1; transform: translateY(0); }
4930
+ }
4931
+
4932
+ /* \u65E0\u969C\u788D\uFF1A\u5C0A\u91CD\u7CFB\u7EDF\u300C\u51CF\u5F31\u52A8\u6001\u6548\u679C\u300D\uFF0C\u4EC5\u4FDD\u7559\u8FB9\u6846\u989C\u8272\u8109\u51B2 */
4933
+ @media (prefers-reduced-motion: reduce) {
4934
+ .dsh-a6-card-refresh::before,
4935
+ .dsh-a6-card-refresh .dsh-a6-bar-identity,
4936
+ .dsh-a6-card-refresh .dsh-a6-bar-pricing,
4937
+ .dsh-a6-card-refresh .dsh-a6-bar-uptime,
4938
+ .dsh-a6-card-refresh .dsh-a6-bar-perf,
4939
+ .dsh-a6-card-refresh .dsh-a6-bar-tags {
4940
+ animation: none !important;
4941
+ }
4942
+ .dsh-a6-card-refresh.refresh-ok,
4943
+ .dsh-a6-card-refresh.refresh-err {
4944
+ animation-duration: 0.01ms !important;
4945
+ }
4946
+ .dsh-a6-refresh-flag {
4947
+ animation-duration: 1.45s !important;
4948
+ animation-name: dsh-a6-refresh-flag-fade !important;
4949
+ }
4950
+ @keyframes dsh-a6-refresh-flag-fade {
4951
+ 0%, 100% { opacity: 0; }
4952
+ 22%, 78% { opacity: 1; }
4953
+ }
4954
+ }
4749
4955
  `;
4750
4956
 
4751
4957
  // src/client/index.ts