Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
892d31d
[App] 换肤对齐 design-system v2:蓝调深色主题、状态标签画刷、数据等宽字体
MayueCif Aug 25, 2026
b5a764b
[App] MainWindow 常驻顶栏与分段市场切换器,导航活跃态对齐原型
MayueCif Aug 25, 2026
30bbb7e
[App] 首页三列布局对齐原型:热门标的最宽置左
MayueCif Aug 25, 2026
5927fde
[Docs] design-system v2.1:与原型 v5 的六项裁决回写
MayueCif Aug 25, 2026
9571922
[App] 批次2页面对齐:收藏页数据等宽字体、选股页暗色遮罩修复、首页价格等宽
MayueCif Aug 25, 2026
fd22e55
[App] 批次3:语义面板画刷主题感知化,修复报告/进度/选股页暗色突兀浅色块
MayueCif Aug 25, 2026
5377368
[App] 批次4:告警/资产详情/选股页数据等宽字体与语义标签主题感知化
MayueCif Aug 25, 2026
87a6ef5
[App] 批次5:设置页重置按钮改用 btn-secondary,交易实盘警告文字主题感知
MayueCif Aug 25, 2026
f604bad
[App] 补完三项:导航左指示条、首页热门标的单行布局、K线图暗色化与红涨绿跌
MayueCif Aug 25, 2026
2fe7bfc
Refactor Trading UI: Enhance TradeMonitorView layout, improve Trading…
MayueCif Aug 27, 2026
3688f69
添加钱包图标 SVG,更新 K 线图样式以支持浅色主题,重构按钮样式以统一浅色卡片风格,优化关于页面和资产页面的布局,增强交易监控视图的操…
MayueCif Aug 27, 2026
786f359
[App.Services] 修复 .gitignore 误伤 MarketAnalysis/Artifacts 源码目录导致 CI 编译失败
MayueCif Aug 27, 2026
2922339
[App] MCP配置页优化:ListBox选择态、必填校验反馈、合并传输表单、未保存修改确认
MayueCif Aug 27, 2026
12eb7b7
[App] 首页搜索优化:修复搜索竞态、键盘高亮入VM、点击改Tapped并补充单元测试
MayueCif Aug 27, 2026
203846c
[全库] dotnet format 统一空白与缩进
MayueCif Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# 仅忽略仓库根目录的构建产物目录,避免误伤源码子目录(如 Agents/MarketAnalysis/Artifacts/)
/artifacts/

# ASP.NET Scaffolding
ScaffoldingReadMe.txt
Expand Down
10 changes: 9 additions & 1 deletion docs/design-system.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# MarketAssistant UI 设计系统

> **版本**: 2.0
> **版本**: 2.1
> **平台**: Avalonia 11.x 跨平台桌面应用
> **产品**: 金融市场数据终端 (A股 + 虚拟币)
> **设计方向**: 清晰专业风 — Bloomberg Terminal 的严谨 × 现代 SaaS 的优雅
>
> **v2.1 变更(与 design-prototype.html v5 的裁决)**:
> 1. 深色背景以本文档色值为准(`bg-root #0A0E17` / `bg-surface #111722` / `bg-elevated #161C2A`),原型中更深的 `#080C14/#0E1320/#141B2A` 弃用;
> 2. 导航活跃指示条采用**左侧 3px 竖条**,不采用原型的底部横条;选中项背景使用 `bg-selected` 浅色填充而非整块品牌蓝;
> 3. 首页不放 K 线区,采用 Bento Grid(热门标的置左最宽 + 快讯 + 最近查看);K 线保留在资产详情页。原型中的"AI 市场概览横幅"待数据源就绪后再引入;
> 4. 涨跌标签一律带约 12% 透明度背景(`BullishTagBackgroundBrush` 等),靠色块而非纯文字色区分语义;
> 5. 响应式简化为两档:≥1100px 完整布局,<1100px 单列隐藏详情面板;
> 6. TopBar 常驻:标题/返回 + A股/虚拟币分段切换器(复用 Ctrl+M 同一逻辑);行情 ticker 需真实指数数据源,无数据时整段隐藏。

---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using System.Runtime.CompilerServices;
using System.Text;

namespace MarketAssistant.Agents.Analysts;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Text;

namespace MarketAssistant.Services.Agents.MarketAnalysis.Artifacts;

/// <summary>
/// 分析师产物存储(P1-07):按 Run 隔离保存每位分析师的完整产物,
/// 协调阶段只传摘要,全文通过工具按需读取。
/// </summary>
public interface IAnalystArtifactStore
{
/// <summary>写入/覆盖指定 Run 下某分析师的产物全文。</summary>
Task SaveAsync(Guid runId, string analystName, string content, CancellationToken cancellationToken = default);

/// <summary>读取指定 Run 下某分析师的产物全文;不存在时返回 null。</summary>
Task<string?> GetAsync(Guid runId, string analystName, CancellationToken cancellationToken = default);
}

/// <summary>
/// 基于文件系统的产物存储实现:%APPDATA%/MarketAssistant/analyst-artifacts/{runId}/{analystName}.md
/// </summary>
public sealed class FileAnalystArtifactStore : IAnalystArtifactStore
{
private readonly string _rootDirectory;

public FileAnalystArtifactStore(string rootDirectory)
{
ArgumentException.ThrowIfNullOrWhiteSpace(rootDirectory);
_rootDirectory = rootDirectory;
}

public async Task SaveAsync(Guid runId, string analystName, string content, CancellationToken cancellationToken = default)
{
var path = GetPath(runId, analystName);
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
await File.WriteAllTextAsync(path, content ?? string.Empty, Encoding.UTF8, cancellationToken);
}

public async Task<string?> GetAsync(Guid runId, string analystName, CancellationToken cancellationToken = default)
{
var path = GetPath(runId, analystName);
if (!File.Exists(path))
return null;

return await File.ReadAllTextAsync(path, Encoding.UTF8, cancellationToken);
}

private string GetPath(Guid runId, string analystName)
{
// analystName 为 MAF Agent ASCII Name,仅允许安全字符
var safeName = string.Concat(analystName.Where(char.IsLetterOrDigit));
if (string.IsNullOrEmpty(safeName))
throw new ArgumentException("分析师名称不能为空", nameof(analystName));

return Path.Combine(_rootDirectory, runId.ToString("N"), $"{safeName}.md");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using MarketAssistant.DataProviders.AShare;
using MarketAssistant.Infrastructure.Core;
using Microsoft.Extensions.Logging;
using System.Globalization;

namespace MarketAssistant.Applications.Assets;

Expand Down Expand Up @@ -84,7 +83,7 @@ public async Task<AssetInfo> GetAssetInfoAsync(string code, string market = "",
}

// 当前价格
assetInfo.CurrentPrice = data.LastPrice.ToString(CultureInfo.InvariantCulture);
assetInfo.CurrentPrice = PriceFormatter.Format(data.LastPrice);

// 涨跌幅(CLS 的 change 为小数比率,如 -0.0082 表示 -0.82%)
var changeRatio = data.Change;
Expand All @@ -103,7 +102,7 @@ public async Task<List<HotAsset>> GetHotAssetsAsync()
// HTTP 访问、GBK 解码与解析由 SinaFundFlowClient 负责;此处仅做业务映射。
try
{
var items = await _sinaFundFlowClient.GetTopNetInflowAsync(8);
var items = await _sinaFundFlowClient.GetTopNetInflowAsync(12);

return items.Select(item =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public async Task<AssetInfo> GetAssetInfoAsync(string code, string market = "",
Name = ExtractBaseCurrency(ticker.Symbol), // 提取基础币种
MarketType = MarketType.Crypto,
Market = "Binance",
CurrentPrice = FormatPrice(ticker.LastPrice),
CurrentPrice = PriceFormatter.Format(ticker.LastPrice),
ChangePercentage = FormatPercentage(ticker.PriceChangePercent),
Volume24h = FormatVolume(ticker.Volume),
MarketCap = await FetchMarketCapAsync(ExtractBaseCurrency(ticker.Symbol), cancellationToken)
Expand All @@ -109,7 +109,7 @@ public async Task<List<HotAsset>> GetHotAssetsAsync()
// 稳定币列表(用于过滤稳定币互换交易对)
var stablecoins = new[] { "USDT", "USDC", "BUSD", "FDUSD", "DAI", "TUSD", "USDP" };

// 筛选USDT交易对,排除稳定币互换(需同时满足:基础币种是稳定币 且 价格接近1.0),按24小时交易量排序,取前8个
// 筛选USDT交易对,排除稳定币互换(需同时满足:基础币种是稳定币 且 价格接近1.0),按24小时交易量排序,取前12个
var hotAssets = tickers
.Where(t => t.Symbol.EndsWith("USDT") && t.Symbol != "USDT")
// 过滤稳定币互换交易对(基础币种是稳定币 且 价格接近1.0,同时满足才过滤)
Expand All @@ -123,13 +123,13 @@ public async Task<List<HotAsset>> GetHotAssetsAsync()
return !(isStablecoin && isPriceNearOne);
})
.OrderByDescending(t => t.QuoteVolume)
.Take(8)
.Take(12)
.Select(t => new HotAsset
{
Name = ExtractBaseCurrency(t.Symbol),
Code = t.Symbol,
Market = "Binance",
CurrentPrice = FormatPrice(t.LastPrice),
CurrentPrice = PriceFormatter.Format(t.LastPrice),
ChangePercentage = FormatOpenClosePercentage(t.OpenPrice, t.LastPrice),
MarketType = MarketType.Crypto,
MetricLabel = "交易量",
Expand Down Expand Up @@ -201,26 +201,6 @@ private async Task<List<BinanceSymbolInfo>> GetSymbolsAsync(CancellationToken ca
return tradingSymbols;
}

/// <summary>
/// 格式化价格显示
/// </summary>
private string FormatPrice(decimal price)
{
// 根据价格大小选择精度
if (price >= 1000)
{
return price.ToString("N2"); // 1000+ 显示2位小数
}
else if (price >= 1)
{
return price.ToString("N4"); // 1-1000 显示4位小数
}
else
{
return price.ToString("N6"); // <1 显示6位小数
}
}

/// <summary>
/// 格式化百分比显示
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ public class AssetItem
/// </summary>
public string Code { get; set; } = string.Empty;

/// <summary>
/// 当前价格(仅用于首页最近查看等场景的展示,历史记录不依赖)
/// </summary>
public string CurrentPrice { get; set; } = string.Empty;

/// <summary>
/// 涨跌幅百分比(如 "+1.26%",仅用于展示)
/// </summary>
public string ChangePercentage { get; set; } = string.Empty;

public override string ToString() => string.IsNullOrEmpty(Name) ? Code : $"{Name} ({Code})";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public class HotAsset
/// </summary>
public string FormattedMetric => FormatMetric(MetricValue);

/// <summary>
/// 行尾标签文本:A 股显示所属板块,加密货币显示核心指标(如"24h量 2.41B")
/// </summary>
public string TagText => MarketType == MarketType.Crypto
? $"{MetricLabel} {FormattedMetric}"
: SectorName ?? string.Empty;

private static string FormatMetric(string? value)
{
if (string.IsNullOrWhiteSpace(value))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace MarketAssistant.Applications.Assets;

/// <summary>
/// 价格展示格式化工具(按价格量级选择小数位),供资产信息服务与实时行情刷新共用。
/// </summary>
public static class PriceFormatter
{
/// <summary>
/// 按量级格式化价格:千及以上 2 位小数,1 及以上 4 位,小于 1 取 6 位(适配低价币)。
/// </summary>
public static string Format(decimal price)
{
if (price >= 1000)
{
return price.ToString("N2");
}

if (price >= 1)
{
return price.ToString("N4");
}

return price.ToString("N6");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,6 @@ public bool LoadKnowledge
set => SetProperty(ref _loadKnowledge, value);
}

private bool _enableExperimentalTrading;
/// <summary>
/// 是否启用实验性自主交易。默认关闭;仅虚拟币等支持交易的市场生效。
/// 开启即表示用户理解实盘风险、密钥与不可撤销操作。
/// </summary>
public bool EnableExperimentalTrading
{
get => _enableExperimentalTrading;
set => SetProperty(ref _enableExperimentalTrading, value);
}

[JsonIgnore]
public const string VectorCollectionName = "knowledge";

Expand Down
3 changes: 3 additions & 0 deletions src/MarketAssistant.App/Assets/Images/wallet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading