dsh-xueqiu 1.22.0 → 1.22.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/README.en.md +3 -0
- package/README.md +7 -0
- package/dynamic/client.js +41 -24
- package/package.json +1 -7
- package/src/client/index.js +41 -24
package/README.en.md
CHANGED
|
@@ -135,6 +135,9 @@ The data layer is defended in depth — safe to leave open for hours:
|
|
|
135
135
|
|
|
136
136
|
## Changelog
|
|
137
137
|
|
|
138
|
+
- **1.22.2** (2026-08-24) — **Fix: MA / avg-price lines landed in sub-panes instead of overlaying the main chart**. KLineChart v10's `createIndicator('MA')` opens a new pane by default — MAs were not on the candle pane (squeezed to 72px) and the minute chart's avg/prev-close lived in their own sub-pane. The fix passes `{ name, paneId: 'candle_pane' }` to explicitly overlay the main pane (pane id confirmed from engine source). Result: candlestick pane at 173px with MA5/10/30/60 overlaid (volume remains the only sub-pane); minute chart is a single pane with price + avg + prev-close overlaid, matching Xueqiu's layout. Also a Xueqiu-inspired detail-page restyle: hero quote header (large red/green price + change + pct), lighter 16-stat grid (tinted cards, tabular numerals), accent bar on card titles, theme-tinted active states for mode/period buttons, chart height 264→300px, harmonized 4-color MA palette, and high/low duplicate price marks disabled.
|
|
139
|
+
- **1.22.1** (2026-08-24) — chore: drop peerDependencies to silence install warnings; static smoke script falls back to local `npx dsh` (dsh not on PATH under prepublishOnly).
|
|
140
|
+
- **1.22.0** (2026-08-24) — **K-line / minute charts migrated to the KLineChart v10 engine** (canvas rendering, built-in light/dark theming): candles + volume + MA overlays + crosshair legend across 7 periods (5m/15m/30m/60m/day/week/month); wheel zoom, drag pan, and auto-fetch of earlier history on left-drag (500 bars per fetch); minute chart as a price-colored area with avg line and prev-close baseline.
|
|
138
141
|
- **1.21.0** (2025-08-21) — **Windows support**. DSH's Windows shell layer is PowerShell (`pwsh -Command`), whose single-quote literal semantics match POSIX — the original "cmd quoting incompatible" obstacle turned out not to exist. Three adaptations: ① explicit `curl.exe` call (dodges PS 5.1's `curl` = `Invoke-WebRequest` alias; curl.exe ships with Win10+); ② the cookie-seeding `-o /dev/null` becomes `NUL` on Windows; ③ quote characters stripped from Cookie headers against injection. The `realShell` test stub now mirrors the platform (pwsh on win32, same as DSH's win32 layer). CI gains a `windows-latest` job: unit + cookie tests + live.mjs against real Xueqiu (51 assertions incl. anonymous seeding) — all green. README platform requirement updated to macOS / Linux / Windows.
|
|
139
142
|
- **1.20.6** (2025-08-21) — **Cloud watchlist contract test wired into CI** (`qa/contract.mjs`, 7 assertions): hits the real endpoints (`portfolio/list.json`, `portfolio/stock/list.json`, `add.json`, `cancel.json`) including a genuine add→cancel round-trip with restore. Runs daily (UTC 21:00) via the `XQ_COOKIE` repo secret so any Xueqiu API change fails here first — preventing another `watch.json`-style phantom-endpoint incident. Skips automatically on push/PR without the secret; the same scheduled job also runs live.mjs (51 assertions). Requires setting the `XQ_COOKIE` secret (full browser Cookie header containing `xq_a_token`).
|
|
140
143
|
- **1.20.5** (2025-08-21) — **Cloud watchlist dual-write never worked**: the previously used `watch.json` endpoint does not exist (the WAF's blanket 403 on unknown paths was misread as "Xueqiu blocks third-party writes"). The real endpoints are `portfolio/stock/add.json` / `cancel.json` (POST form, symbols param). Fixed and verified with a real-account full round-trip: plugin add → cloud 116 ✓ → plugin remove → cloud restored 115 ✓. Local add/remove now genuinely syncs both ways; the 1.20.4 "writes are blocked" claim is retracted.
|
package/README.md
CHANGED
|
@@ -190,6 +190,13 @@ dsh-xueqiu/
|
|
|
190
190
|
|
|
191
191
|
## 📋 更新日志
|
|
192
192
|
|
|
193
|
+
- **1.22.2**(2026-08-24)
|
|
194
|
+
- 修复:**K线均线 / 分时均价误落附图**。KLineChart v10 的 `createIndicator('MA')` 默认给指标新开 pane——均线不在蜡烛主图上(主图被挤到 72px),分时均价/昨收也在独立附图。须传 `{ name, paneId: 'candle_pane' }` 显式叠加到主图(pane id 从引擎源码确认)。修复后:K线主图 173px 蜡烛+MA5/10/30/60 叠加、附图仅成交量;分时只剩一张主图(分时曲线+均价+昨收全部叠加),与雪球布局一致。
|
|
195
|
+
- 样式:**详情页参考雪球重排版**——顶部行情主标题(大号红/绿现价 + 涨跌额 + 涨跌幅,如 `1304.66 +31.83 +2.50%`);16 格 stat 卡片更轻盈(浅底/圆角/等宽数字/标签次要色);卡片标题左侧主题色强调条;K线/分时与周期按钮选中态改主题色 tint 填充;K线画布 264→300px;MA 均线和谐四色(蓝/橙/紫/青);关闭最高/最低点重复标注(消除窄图顶部杂乱数字)。
|
|
196
|
+
- **1.22.1**(2026-08-24)
|
|
197
|
+
- chore:移除 peerDependencies 避免安装警告;静态冒烟脚本自动兜底本地 `npx dsh`(prepublishOnly 下找不到 dsh 命令)。
|
|
198
|
+
- **1.22.0**(2026-08-24)
|
|
199
|
+
- 新增:**K线/分时切换 KLineChart v10 引擎**(canvas 渲染、内置明暗主题适配):蜡烛图 + 成交量 + MA 均线 + 十字光标,5分/15分/30分/60分/日K/周K/月K 7 档;滚轮缩放、拖拽平移、左拖触底自动加载更早历史(500 根/次);分时面积图(涨跌色)+ 均价线 + 昨收虚线。
|
|
193
200
|
- **1.21.7**(2025-08-24)
|
|
194
201
|
- 修复:**越屏钳制改为逐渲染执行**。1.21.6 的"effect 依赖 badgePos + ResizeObserver"方案在 CI 慢环境仍漏过"渲染后才长高"的时序(数据异步到达→徽章长高→无重触发钳制)。现在 `useLayoutEffect` 每次渲染后钳制(数据到达必伴随重渲染,无时序死角;ui.set 仅在有变更时触发下一轮,收敛不循环)。CI 实测踩坑修复。
|
|
195
202
|
- 新增:**浏览器 E2E 进 CI**(`browser-e2e` job)。此前这层(唯一抓到过钳制死代码真 bug 的测试)只在本机手动跑。`scripts/e2e-ci-boot.sh` 合成"已完成引导"的隔离 DSH 实例(settings 跳过 onboarding + workspace 表 + 含完整一轮对话的逐行 zstd 会话日志——踩坑记录:DSH 逐记录写日志,每 zstd 帧恰好一行;slug 规则 cwd 去首 `/`、余 `/`→`-`、两端包 `--`),agent-browser 跑全部 18 项断言。E2E 脚本兜底:全新实例无活动对话时先展开会话分组再点开一个会话(conversation.input.dock 槽需要对话视图)。
|
package/dynamic/client.js
CHANGED
|
@@ -121,20 +121,25 @@ return {
|
|
|
121
121
|
'.xq-news-time{font-size:10.5px;color:var(--dsw-alias-label-secondary);margin-top:3px;}\n' +
|
|
122
122
|
'.xq-news-more{font-size:11.5px;color:var(--dsw-alias-label-secondary);text-align:center;padding:6px 0 2px;cursor:pointer;user-select:none;}\n' +
|
|
123
123
|
'.xq-news-more:hover{color:var(--dsw-alias-label-primary);}\n' +
|
|
124
|
-
'.xq-detail-head{display:flex;align-items:center;gap:10px;margin-bottom:
|
|
125
|
-
'.xq-detail-name{font-size:
|
|
126
|
-
'.xq-detail-code{font-size:11px;color:var(--dsw-alias-label-
|
|
127
|
-
'.xq-detail-
|
|
128
|
-
'.xq-detail-
|
|
129
|
-
'.xq-
|
|
130
|
-
'.xq-
|
|
131
|
-
'.xq-
|
|
132
|
-
'.xq-
|
|
133
|
-
'.xq-
|
|
134
|
-
'.xq-
|
|
135
|
-
'.xq-
|
|
136
|
-
'.xq-
|
|
137
|
-
'.xq-
|
|
124
|
+
'.xq-detail-head{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap;}\n' +
|
|
125
|
+
'.xq-detail-name{font-size:16px;font-weight:700;letter-spacing:.2px;}\n' +
|
|
126
|
+
'.xq-detail-code{font-size:11px;color:var(--dsw-alias-label-tertiary);letter-spacing:.3px;}\n' +
|
|
127
|
+
'.xq-detail-price{display:flex;align-items:baseline;gap:10px;}\n' +
|
|
128
|
+
'.xq-detail-delta{display:flex;align-items:baseline;gap:6px;}\n' +
|
|
129
|
+
'.xq-detail-cur{font-size:27px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;}\n' +
|
|
130
|
+
'.xq-detail-chg{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;}\n' +
|
|
131
|
+
'.xq-detail-pct{font-size:14px;font-weight:700;font-variant-numeric:tabular-nums;}\n' +
|
|
132
|
+
'.xq-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:12px;}\n' +
|
|
133
|
+
'.xq-stat{background:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 55%, transparent);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:6px 8px;min-width:0;}\n' +
|
|
134
|
+
'.xq-stat-k{font-size:10px;color:var(--dsw-alias-label-tertiary);margin-bottom:3px;letter-spacing:.2px;}\n' +
|
|
135
|
+
'.xq-stat-v{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}\n' +
|
|
136
|
+
'.xq-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;padding:10px 12px;margin-bottom:12px;}\n' +
|
|
137
|
+
'.xq-card-t{font-size:12.5px;font-weight:700;margin-bottom:8px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;}\n' +
|
|
138
|
+
'.xq-card-t::before{content:"";width:3px;height:12px;border-radius:2px;background:var(--dsw-alias-brand-primary);flex:none;}\n' +
|
|
139
|
+
'.xq-periods{display:inline-flex;flex-wrap:wrap;gap:2px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;padding:2px;background:var(--dsw-alias-bg-layer-2);}\n' +
|
|
140
|
+
'.xq-periods button,.xq-modes button{font-size:11.5px;border:none;background:none;color:var(--dsw-alias-label-secondary);padding:3px 9px;border-radius:6px;cursor:pointer;transition:color .12s,background .12s;}\n' +
|
|
141
|
+
'.xq-periods button:hover,.xq-modes button:hover{color:var(--dsw-alias-label-primary);}\n' +
|
|
142
|
+
'.xq-periods button.xq-on,.xq-modes button.xq-on{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 16%, transparent);color:var(--dsw-alias-brand-primary);font-weight:700;}\n' +
|
|
138
143
|
'.xq-chart{width:100%;height:auto;display:block;}\n' +
|
|
139
144
|
'.xq-chart-pan{cursor:crosshair;touch-action:none;}\n' +
|
|
140
145
|
'.xq-chart-pan:active{cursor:grabbing;}\n' +
|
|
@@ -143,10 +148,10 @@ return {
|
|
|
143
148
|
'.xq-tip-d{font-weight:700;}\n' +
|
|
144
149
|
'.xq-tip-r{display:flex;gap:8px;}\n' +
|
|
145
150
|
'.xq-tip-k{color:var(--dsw-alias-label-secondary);}\n' +
|
|
146
|
-
'.xq-chart-labels{display:flex;justify-content:space-between;font-size:10.5px;color:var(--dsw-alias-label-
|
|
151
|
+
'.xq-chart-labels{display:flex;justify-content:space-between;font-size:10.5px;color:var(--dsw-alias-label-tertiary);margin-top:3px;}\n' +
|
|
147
152
|
'.xq-ma-legend{display:flex;gap:10px;font-size:10.5px;color:var(--dsw-alias-label-secondary);}\n' +
|
|
148
|
-
'.xq-klc{height:
|
|
149
|
-
'.xq-klc-min{height:
|
|
153
|
+
'.xq-klc{height:300px;width:100%;min-width:0;}\n' +
|
|
154
|
+
'.xq-klc-min{height:230px;}\n' +
|
|
150
155
|
'.xq-kol{display:flex;flex-wrap:wrap;gap:6px;}\n' +
|
|
151
156
|
'.xq-kol-chip{font-size:12px;padding:4px 10px;border-radius:14px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);cursor:pointer;}\n' +
|
|
152
157
|
'.xq-kol-chip:hover{border-color:var(--dsw-alias-brand-primary);}\n' +
|
|
@@ -351,13 +356,15 @@ return {
|
|
|
351
356
|
upWickColor: pal.up, downWickColor: pal.down, noChangeWickColor: pal.text
|
|
352
357
|
},
|
|
353
358
|
priceMark: {
|
|
354
|
-
|
|
359
|
+
// 关闭最高/最低点重复标注(窄图时易与坐标轴重叠成杂乱数字),保留最新价标
|
|
360
|
+
high: { show: false }, low: { show: false },
|
|
355
361
|
last: { upColor: pal.up, downColor: pal.down, noChangeColor: pal.text, text: { color: pal.text } }
|
|
356
362
|
}
|
|
357
363
|
},
|
|
358
364
|
indicator: {
|
|
359
365
|
bars: [{ upColor: pal.up, downColor: pal.down, noChangeColor: pal.text }],
|
|
360
|
-
|
|
366
|
+
// 和谐 MA 配色:蓝/橙/紫/青,多均线更易区分(对齐雪球观感)
|
|
367
|
+
lines: [{ color: '#3b82f6' }, { color: '#f59e0b' }, { color: '#8b5cf6' }, { color: '#06b6d4' }],
|
|
361
368
|
tooltip: { show: false } // 指标数值走蜡烛 legend,避免双份
|
|
362
369
|
},
|
|
363
370
|
xAxis: { axisLine: { color: pal.grid }, tickLine: { color: pal.grid }, tickText: { color: pal.text } },
|
|
@@ -465,7 +472,8 @@ return {
|
|
|
465
472
|
}, function () { busy = false; done([], { forward: false, backward: false }) })
|
|
466
473
|
}
|
|
467
474
|
})
|
|
468
|
-
|
|
475
|
+
// 均线叠加到主图蜡烛 pane(paneId 指定已有主图,不传则默认新开附图 pane)——与雪球一致
|
|
476
|
+
chart.createIndicator({ name: 'MA', paneId: 'candle_pane' })
|
|
469
477
|
chart.createIndicator('VOL')
|
|
470
478
|
chart.setOffsetRightDistance(16)
|
|
471
479
|
return h.dispose
|
|
@@ -496,7 +504,7 @@ return {
|
|
|
496
504
|
React.useEffect(function () {
|
|
497
505
|
const K = klcLib()
|
|
498
506
|
if (!K || !boxRef.current) { setNoLib(true); return undefined }
|
|
499
|
-
// 自定义指标:昨收虚线 + 均价线(series normal
|
|
507
|
+
// 自定义指标:昨收虚线 + 均价线(series normal → 单独附图,避免干扰价格轴刻度)
|
|
500
508
|
if (K.getSupportedIndicators().indexOf('xq-minute') < 0) {
|
|
501
509
|
K.registerIndicator({
|
|
502
510
|
name: 'xq-minute', shortName: '分时', series: 'normal',
|
|
@@ -541,7 +549,7 @@ return {
|
|
|
541
549
|
const up = lastClose ? last >= lastClose : true
|
|
542
550
|
// 涨跌色改面积线色(palette up 色对A股即"涨")
|
|
543
551
|
chart.setStyles({ candle: { type: 'area', area: { lineColor: up ? klcPalette().up : klcPalette().down, backgroundColor: up ? 'rgba(239,68,68,0.10)' : 'rgba(34,197,94,0.10)' } } })
|
|
544
|
-
chart.createIndicator('xq-minute')
|
|
552
|
+
chart.createIndicator({ name: 'xq-minute', paneId: 'candle_pane' }) // 均价/昨收叠加到主图分时曲线(与雪球一致)
|
|
545
553
|
// 分时固定视角:禁缩放拖拽,全部笔数铺满宽度
|
|
546
554
|
chart.setZoomEnabled(false)
|
|
547
555
|
chart.setScrollEnabled(false)
|
|
@@ -1013,14 +1021,23 @@ return {
|
|
|
1013
1021
|
' · ' + fmtBig(u.followers_count) + '粉'
|
|
1014
1022
|
])
|
|
1015
1023
|
})
|
|
1024
|
+
// 行情主标题:现价 + 涨跌额 + 涨跌幅(参考雪球 ¥18.23 +0.14 +0.77% 层级)
|
|
1025
|
+
const chgRaw = (q.current != null && q.last_close != null) ? (Number(q.current) - Number(q.last_close)) : null
|
|
1026
|
+
const chgStr = (chgRaw != null && isFinite(chgRaw)) ? (chgRaw > 0 ? '+' + fmt(chgRaw) : (chgRaw < 0 ? '-' + fmt(Math.abs(chgRaw)) : '0.00')) : ''
|
|
1027
|
+
const priceCls = colorOf(q.percent)
|
|
1016
1028
|
return el('div', null, [
|
|
1017
1029
|
el('div', { key: 'h', className: 'xq-detail-head' }, [
|
|
1018
1030
|
el('button', { key: 'b', className: 'xq-btn-mini', onClick: function () { setView(null) } }, '← 返回'),
|
|
1019
1031
|
el('span', { key: 'n', className: 'xq-detail-name' }, q.name || view),
|
|
1020
1032
|
el('span', { key: 'c', className: 'xq-detail-code' }, view),
|
|
1021
1033
|
el('span', { key: 'sp', className: 'xq-spacer' }),
|
|
1022
|
-
el('
|
|
1023
|
-
|
|
1034
|
+
el('div', { key: 'px', className: 'xq-detail-price' }, [
|
|
1035
|
+
el('span', { key: 'cur', className: 'xq-detail-cur ' + priceCls }, fmt(q.current)),
|
|
1036
|
+
el('span', { key: 'dl', className: 'xq-detail-delta' }, [
|
|
1037
|
+
chgStr ? el('span', { key: 'chg', className: 'xq-detail-chg ' + priceCls }, chgStr) : null,
|
|
1038
|
+
el('span', { key: 'pct', className: 'xq-detail-pct ' + priceCls }, fmtPct(q.percent))
|
|
1039
|
+
])
|
|
1040
|
+
])
|
|
1024
1041
|
]),
|
|
1025
1042
|
el('div', { key: 'st', className: 'xq-stats' }, stats.map(function (s, i) {
|
|
1026
1043
|
return el('div', { key: i, className: 'xq-stat' }, [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-xueqiu",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.2",
|
|
4
4
|
"description": "雪球 mini 行情面板 — DeepSeek Harness 免登录 A股/港美股实时行情、K线(蜡烛/成交量/均线)、分时图、热榜、搜索、7x24 快讯、热议用户。嵌入式面板 + 可拖拽行情徽标,内置请求节流、TTL 缓存与 Cookie 自动续期。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -41,12 +41,6 @@
|
|
|
41
41
|
"patch": "./cordis.patch.yml"
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
-
"peerDependencies": {
|
|
45
|
-
"@deepseek-ai/cordis": "^4.0.1",
|
|
46
|
-
"@deepseek-ai/dsh-client-connection": "^0.1.0-rc.6",
|
|
47
|
-
"react": "^18.3.1",
|
|
48
|
-
"@deepseek-ai/dsh-tools": ">=0.1.0-rc.1 <0.2.0"
|
|
49
|
-
},
|
|
50
44
|
"files": [
|
|
51
45
|
"src/index.js",
|
|
52
46
|
"src/client/index.js",
|
package/src/client/index.js
CHANGED
|
@@ -152,20 +152,25 @@ exports.default = {
|
|
|
152
152
|
'.xq-news-time{font-size:10.5px;color:var(--dsw-alias-label-secondary);margin-top:3px;}\n' +
|
|
153
153
|
'.xq-news-more{font-size:11.5px;color:var(--dsw-alias-label-secondary);text-align:center;padding:6px 0 2px;cursor:pointer;user-select:none;}\n' +
|
|
154
154
|
'.xq-news-more:hover{color:var(--dsw-alias-label-primary);}\n' +
|
|
155
|
-
'.xq-detail-head{display:flex;align-items:center;gap:10px;margin-bottom:
|
|
156
|
-
'.xq-detail-name{font-size:
|
|
157
|
-
'.xq-detail-code{font-size:11px;color:var(--dsw-alias-label-
|
|
158
|
-
'.xq-detail-
|
|
159
|
-
'.xq-detail-
|
|
160
|
-
'.xq-
|
|
161
|
-
'.xq-
|
|
162
|
-
'.xq-
|
|
163
|
-
'.xq-
|
|
164
|
-
'.xq-
|
|
165
|
-
'.xq-
|
|
166
|
-
'.xq-
|
|
167
|
-
'.xq-
|
|
168
|
-
'.xq-
|
|
155
|
+
'.xq-detail-head{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap;}\n' +
|
|
156
|
+
'.xq-detail-name{font-size:16px;font-weight:700;letter-spacing:.2px;}\n' +
|
|
157
|
+
'.xq-detail-code{font-size:11px;color:var(--dsw-alias-label-tertiary);letter-spacing:.3px;}\n' +
|
|
158
|
+
'.xq-detail-price{display:flex;align-items:baseline;gap:10px;}\n' +
|
|
159
|
+
'.xq-detail-delta{display:flex;align-items:baseline;gap:6px;}\n' +
|
|
160
|
+
'.xq-detail-cur{font-size:27px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;}\n' +
|
|
161
|
+
'.xq-detail-chg{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;}\n' +
|
|
162
|
+
'.xq-detail-pct{font-size:14px;font-weight:700;font-variant-numeric:tabular-nums;}\n' +
|
|
163
|
+
'.xq-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:12px;}\n' +
|
|
164
|
+
'.xq-stat{background:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 55%, transparent);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:6px 8px;min-width:0;}\n' +
|
|
165
|
+
'.xq-stat-k{font-size:10px;color:var(--dsw-alias-label-tertiary);margin-bottom:3px;letter-spacing:.2px;}\n' +
|
|
166
|
+
'.xq-stat-v{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}\n' +
|
|
167
|
+
'.xq-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;padding:10px 12px;margin-bottom:12px;}\n' +
|
|
168
|
+
'.xq-card-t{font-size:12.5px;font-weight:700;margin-bottom:8px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;}\n' +
|
|
169
|
+
'.xq-card-t::before{content:"";width:3px;height:12px;border-radius:2px;background:var(--dsw-alias-brand-primary);flex:none;}\n' +
|
|
170
|
+
'.xq-periods{display:inline-flex;flex-wrap:wrap;gap:2px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;padding:2px;background:var(--dsw-alias-bg-layer-2);}\n' +
|
|
171
|
+
'.xq-periods button,.xq-modes button{font-size:11.5px;border:none;background:none;color:var(--dsw-alias-label-secondary);padding:3px 9px;border-radius:6px;cursor:pointer;transition:color .12s,background .12s;}\n' +
|
|
172
|
+
'.xq-periods button:hover,.xq-modes button:hover{color:var(--dsw-alias-label-primary);}\n' +
|
|
173
|
+
'.xq-periods button.xq-on,.xq-modes button.xq-on{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 16%, transparent);color:var(--dsw-alias-brand-primary);font-weight:700;}\n' +
|
|
169
174
|
'.xq-chart{width:100%;height:auto;display:block;}\n' +
|
|
170
175
|
'.xq-chart-pan{cursor:crosshair;touch-action:none;}\n' +
|
|
171
176
|
'.xq-chart-pan:active{cursor:grabbing;}\n' +
|
|
@@ -174,10 +179,10 @@ exports.default = {
|
|
|
174
179
|
'.xq-tip-d{font-weight:700;}\n' +
|
|
175
180
|
'.xq-tip-r{display:flex;gap:8px;}\n' +
|
|
176
181
|
'.xq-tip-k{color:var(--dsw-alias-label-secondary);}\n' +
|
|
177
|
-
'.xq-chart-labels{display:flex;justify-content:space-between;font-size:10.5px;color:var(--dsw-alias-label-
|
|
182
|
+
'.xq-chart-labels{display:flex;justify-content:space-between;font-size:10.5px;color:var(--dsw-alias-label-tertiary);margin-top:3px;}\n' +
|
|
178
183
|
'.xq-ma-legend{display:flex;gap:10px;font-size:10.5px;color:var(--dsw-alias-label-secondary);}\n' +
|
|
179
|
-
'.xq-klc{height:
|
|
180
|
-
'.xq-klc-min{height:
|
|
184
|
+
'.xq-klc{height:300px;width:100%;min-width:0;}\n' +
|
|
185
|
+
'.xq-klc-min{height:230px;}\n' +
|
|
181
186
|
'.xq-kol{display:flex;flex-wrap:wrap;gap:6px;}\n' +
|
|
182
187
|
'.xq-kol-chip{font-size:12px;padding:4px 10px;border-radius:14px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);cursor:pointer;}\n' +
|
|
183
188
|
'.xq-kol-chip:hover{border-color:var(--dsw-alias-brand-primary);}\n' +
|
|
@@ -382,13 +387,15 @@ exports.default = {
|
|
|
382
387
|
upWickColor: pal.up, downWickColor: pal.down, noChangeWickColor: pal.text
|
|
383
388
|
},
|
|
384
389
|
priceMark: {
|
|
385
|
-
|
|
390
|
+
// 关闭最高/最低点重复标注(窄图时易与坐标轴重叠成杂乱数字),保留最新价标
|
|
391
|
+
high: { show: false }, low: { show: false },
|
|
386
392
|
last: { upColor: pal.up, downColor: pal.down, noChangeColor: pal.text, text: { color: pal.text } }
|
|
387
393
|
}
|
|
388
394
|
},
|
|
389
395
|
indicator: {
|
|
390
396
|
bars: [{ upColor: pal.up, downColor: pal.down, noChangeColor: pal.text }],
|
|
391
|
-
|
|
397
|
+
// 和谐 MA 配色:蓝/橙/紫/青,多均线更易区分(对齐雪球观感)
|
|
398
|
+
lines: [{ color: '#3b82f6' }, { color: '#f59e0b' }, { color: '#8b5cf6' }, { color: '#06b6d4' }],
|
|
392
399
|
tooltip: { show: false } // 指标数值走蜡烛 legend,避免双份
|
|
393
400
|
},
|
|
394
401
|
xAxis: { axisLine: { color: pal.grid }, tickLine: { color: pal.grid }, tickText: { color: pal.text } },
|
|
@@ -496,7 +503,8 @@ exports.default = {
|
|
|
496
503
|
}, function () { busy = false; done([], { forward: false, backward: false }) })
|
|
497
504
|
}
|
|
498
505
|
})
|
|
499
|
-
|
|
506
|
+
// 均线叠加到主图蜡烛 pane(paneId 指定已有主图,不传则默认新开附图 pane)——与雪球一致
|
|
507
|
+
chart.createIndicator({ name: 'MA', paneId: 'candle_pane' })
|
|
500
508
|
chart.createIndicator('VOL')
|
|
501
509
|
chart.setOffsetRightDistance(16)
|
|
502
510
|
return h.dispose
|
|
@@ -527,7 +535,7 @@ exports.default = {
|
|
|
527
535
|
React.useEffect(function () {
|
|
528
536
|
const K = klcLib()
|
|
529
537
|
if (!K || !boxRef.current) { setNoLib(true); return undefined }
|
|
530
|
-
// 自定义指标:昨收虚线 + 均价线(series normal
|
|
538
|
+
// 自定义指标:昨收虚线 + 均价线(series normal → 单独附图,避免干扰价格轴刻度)
|
|
531
539
|
if (K.getSupportedIndicators().indexOf('xq-minute') < 0) {
|
|
532
540
|
K.registerIndicator({
|
|
533
541
|
name: 'xq-minute', shortName: '分时', series: 'normal',
|
|
@@ -572,7 +580,7 @@ exports.default = {
|
|
|
572
580
|
const up = lastClose ? last >= lastClose : true
|
|
573
581
|
// 涨跌色改面积线色(palette up 色对A股即"涨")
|
|
574
582
|
chart.setStyles({ candle: { type: 'area', area: { lineColor: up ? klcPalette().up : klcPalette().down, backgroundColor: up ? 'rgba(239,68,68,0.10)' : 'rgba(34,197,94,0.10)' } } })
|
|
575
|
-
chart.createIndicator('xq-minute')
|
|
583
|
+
chart.createIndicator({ name: 'xq-minute', paneId: 'candle_pane' }) // 均价/昨收叠加到主图分时曲线(与雪球一致)
|
|
576
584
|
// 分时固定视角:禁缩放拖拽,全部笔数铺满宽度
|
|
577
585
|
chart.setZoomEnabled(false)
|
|
578
586
|
chart.setScrollEnabled(false)
|
|
@@ -1044,14 +1052,23 @@ exports.default = {
|
|
|
1044
1052
|
' · ' + fmtBig(u.followers_count) + '粉'
|
|
1045
1053
|
])
|
|
1046
1054
|
})
|
|
1055
|
+
// 行情主标题:现价 + 涨跌额 + 涨跌幅(参考雪球 ¥18.23 +0.14 +0.77% 层级)
|
|
1056
|
+
const chgRaw = (q.current != null && q.last_close != null) ? (Number(q.current) - Number(q.last_close)) : null
|
|
1057
|
+
const chgStr = (chgRaw != null && isFinite(chgRaw)) ? (chgRaw > 0 ? '+' + fmt(chgRaw) : (chgRaw < 0 ? '-' + fmt(Math.abs(chgRaw)) : '0.00')) : ''
|
|
1058
|
+
const priceCls = colorOf(q.percent)
|
|
1047
1059
|
return el('div', null, [
|
|
1048
1060
|
el('div', { key: 'h', className: 'xq-detail-head' }, [
|
|
1049
1061
|
el('button', { key: 'b', className: 'xq-btn-mini', onClick: function () { setView(null) } }, '← 返回'),
|
|
1050
1062
|
el('span', { key: 'n', className: 'xq-detail-name' }, q.name || view),
|
|
1051
1063
|
el('span', { key: 'c', className: 'xq-detail-code' }, view),
|
|
1052
1064
|
el('span', { key: 'sp', className: 'xq-spacer' }),
|
|
1053
|
-
el('
|
|
1054
|
-
|
|
1065
|
+
el('div', { key: 'px', className: 'xq-detail-price' }, [
|
|
1066
|
+
el('span', { key: 'cur', className: 'xq-detail-cur ' + priceCls }, fmt(q.current)),
|
|
1067
|
+
el('span', { key: 'dl', className: 'xq-detail-delta' }, [
|
|
1068
|
+
chgStr ? el('span', { key: 'chg', className: 'xq-detail-chg ' + priceCls }, chgStr) : null,
|
|
1069
|
+
el('span', { key: 'pct', className: 'xq-detail-pct ' + priceCls }, fmtPct(q.percent))
|
|
1070
|
+
])
|
|
1071
|
+
])
|
|
1055
1072
|
]),
|
|
1056
1073
|
el('div', { key: 'st', className: 'xq-stats' }, stats.map(function (s, i) {
|
|
1057
1074
|
return el('div', { key: i, className: 'xq-stat' }, [
|