fix:按html的假数据demo
This commit is contained in:
@@ -0,0 +1,493 @@
|
||||
import '../models/models.dart';
|
||||
import 'report_data_source.dart';
|
||||
|
||||
class MockReportDataSource implements ReportDataSource {
|
||||
MockReportDataSource();
|
||||
|
||||
static final Institution _wgcSummary = _institutionSummary(
|
||||
id: 'wgc',
|
||||
nameCn: '世界黄金协会',
|
||||
nameEn: 'World Gold Council',
|
||||
logoUrl: 'https://www.google.com/s2/favicons?domain=www.gold.org&sz=128',
|
||||
institutionType: 'industry_org',
|
||||
sourceTier: 'A',
|
||||
websiteUrl: 'https://www.gold.org',
|
||||
coveredTopics: ['贵金属', '央行', '跨资产'],
|
||||
reportCount: 6,
|
||||
introCn: '世界黄金协会致力于推动黄金市场研究与应用,常发布黄金需求、投资与央行购金相关分析。',
|
||||
credibilityNote: '公开数据、央行储备与 ETF 流量交叉验证,适合跟踪黄金需求结构变化。',
|
||||
);
|
||||
|
||||
static final Institution _bisSummary = _institutionSummary(
|
||||
id: 'bis',
|
||||
nameCn: '国际清算银行 BIS',
|
||||
nameEn: 'Bank for International Settlements',
|
||||
logoUrl: 'https://www.google.com/s2/favicons?domain=www.bis.org&sz=128',
|
||||
institutionType: 'official',
|
||||
sourceTier: 'A',
|
||||
websiteUrl: 'https://www.bis.org',
|
||||
coveredTopics: ['宏观', '货币政策'],
|
||||
reportCount: 4,
|
||||
introCn: 'BIS 关注全球金融稳定、资本流动和银行体系结构,是宏观与金融市场观察的重要来源。',
|
||||
credibilityNote: '跨国监管机构,通常以统计和制度性框架解释市场变化。',
|
||||
);
|
||||
|
||||
static final Institution _ieaSummary = _institutionSummary(
|
||||
id: 'iea',
|
||||
nameCn: '国际能源署 IEA',
|
||||
nameEn: 'International Energy Agency',
|
||||
logoUrl: 'https://www.google.com/s2/favicons?domain=www.iea.org&sz=128',
|
||||
institutionType: 'official',
|
||||
sourceTier: 'A',
|
||||
websiteUrl: 'https://www.iea.org',
|
||||
coveredTopics: ['能源', '大宗'],
|
||||
reportCount: 5,
|
||||
introCn: 'IEA 主要跟踪全球原油、天然气、电力与能源转型相关供需变化。',
|
||||
credibilityNote: '统计频率高,适合配合库存、产量与政策节奏观察。',
|
||||
);
|
||||
|
||||
static final Institution _worldBankSummary = _institutionSummary(
|
||||
id: 'worldbank',
|
||||
nameCn: '世界银行',
|
||||
nameEn: 'World Bank',
|
||||
logoUrl:
|
||||
'https://www.google.com/s2/favicons?domain=www.worldbank.org&sz=128',
|
||||
institutionType: 'official',
|
||||
sourceTier: 'A',
|
||||
websiteUrl: 'https://www.worldbank.org',
|
||||
coveredTopics: ['大宗', '全球增长'],
|
||||
reportCount: 3,
|
||||
introCn: '世界银行常通过大宗商品展望、全球增长与贫困相关研究提供宏观视角。',
|
||||
credibilityNote: '跨国公共机构,适合作为全球价格和增长基准参考。',
|
||||
);
|
||||
|
||||
static final Institution _ssgaSummary = _institutionSummary(
|
||||
id: 'ssga',
|
||||
nameCn: '道富环球投资管理',
|
||||
nameEn: 'State Street Global Advisors',
|
||||
logoUrl: 'https://www.google.com/s2/favicons?domain=www.ssga.com&sz=128',
|
||||
institutionType: 'asset_manager',
|
||||
sourceTier: 'A',
|
||||
websiteUrl: 'https://www.ssga.com',
|
||||
coveredTopics: ['贵金属', '跨资产'],
|
||||
reportCount: 4,
|
||||
introCn: '道富的市场观点常围绕资产配置、黄金投资和 ETF 流向展开。',
|
||||
credibilityNote: '资产管理机构视角偏市场化,适合观察投资者行为和资金流。',
|
||||
);
|
||||
|
||||
static final ReportDetail _gold = ReportDetail(
|
||||
id: 'gold-demand-q2-2026',
|
||||
titleCn: '黄金需求趋势:央行与亚洲买家的双轮驱动',
|
||||
institution: _wgcSummary,
|
||||
oneLiner: '央行购金与亚洲投资需求,构成本季黄金需求的双轮。',
|
||||
source: const {'source_tier': 'A', 'source_name': 'World Gold Council'},
|
||||
topics: const ['贵金属', '央行', '跨资产'],
|
||||
hasAudio: true,
|
||||
releasedAt: '2026-05-30',
|
||||
modules: [
|
||||
_module('gold-basic', 'basic_info', '基本信息', {
|
||||
'summary_cn': '央行持续买入黄金,叠加亚洲投资需求回暖,支撑本季金价中枢。',
|
||||
'topics': ['贵金属', '央行', '跨资产'],
|
||||
}),
|
||||
_module('gold-insights', 'core_insights', '核心洞察', {
|
||||
'points': [
|
||||
{'kind': 'view', 'text': '央行购金从战术操作转向结构性配置,已成为黄金需求底层支撑。'},
|
||||
{'kind': 'number', 'text': '金价重回高位后,ETF 与亚洲实物买盘接续承接,波动被更广泛的资金流吸收。'},
|
||||
{'kind': 'risk', 'text': '若美元和实际利率同步抬升,黄金的防御属性仍会面临短期回撤。'},
|
||||
],
|
||||
}, hasDetailPage: true),
|
||||
_module('gold-audio', 'audio', '音频解读', {
|
||||
'audio_id': 'audio_gold_q2_2026',
|
||||
'title_cn': '黄金需求趋势:央行与亚洲买家的双轮驱动',
|
||||
'duration_sec': 860,
|
||||
}),
|
||||
_module('gold-timeline', 'timeline', '时间线', {
|
||||
'events': [
|
||||
{'date': '2026-03', 'event': '央行购金维持高位', 'impact': '储备资产配置继续偏向黄金。'},
|
||||
{'date': '2026-04', 'event': '亚洲投资需求回升', 'impact': '零售和机构买盘共同抬升需求。'},
|
||||
{
|
||||
'date': '2026-05',
|
||||
'event': '金价刷新阶段高位',
|
||||
'impact': '高位波动加大,但下方买盘承接仍强。',
|
||||
},
|
||||
],
|
||||
}, hasDetailPage: true),
|
||||
_module('gold-key-data', 'key_data', '关键数据', {
|
||||
'rows': [
|
||||
{
|
||||
'metric': '央行净买入',
|
||||
'value': '800+',
|
||||
'unit': '吨',
|
||||
'judgment': '仍处高位,支撑黄金中期结构性需求。',
|
||||
},
|
||||
{
|
||||
'metric': 'ETF 流向',
|
||||
'value': '净流入',
|
||||
'unit': '',
|
||||
'judgment': '投资盘开始重新接力。',
|
||||
},
|
||||
{
|
||||
'metric': '亚洲实物需求',
|
||||
'value': '回升',
|
||||
'unit': '',
|
||||
'judgment': '节庆和资产配置需求叠加。',
|
||||
},
|
||||
],
|
||||
}),
|
||||
_module('gold-study', 'study_guide', '研读指南', {
|
||||
'intro_cn': '如果你只想看结论,先读核心洞察;如果你想跟踪驱动因素,继续看时间线与关键数据。',
|
||||
'faq_items': [
|
||||
{
|
||||
'question': '为什么央行购金重要?',
|
||||
'answer': '央行购金往往具有中长期配置属性,可以给金价提供比短线投机更稳定的需求锚。',
|
||||
},
|
||||
{
|
||||
'question': '亚洲买盘如何影响金价?',
|
||||
'answer': '当亚洲需求在价格高位仍然保持韧性时,金价上方空间通常更容易被市场重新定价。',
|
||||
},
|
||||
],
|
||||
'glossary': [
|
||||
{'term': 'ETF', 'definition': '交易型开放式基金,常用于观察机构资金流向。'},
|
||||
{'term': '央行购金', 'definition': '中央银行增持黄金储备的行为。'},
|
||||
],
|
||||
}, hasDetailPage: true),
|
||||
_module('gold-sources', 'related_sources', '相关来源', {
|
||||
'items': [
|
||||
{'title': '世界黄金协会季度需求报告', 'summary_cn': '黄金首饰、央行和投资需求的总览。'},
|
||||
{'title': '道富黄金配置观点', 'summary_cn': '从资产配置角度看黄金在组合中的角色。'},
|
||||
],
|
||||
}),
|
||||
_module('gold-weaknesses', 'weaknesses', '风险与验证', {
|
||||
'disclaimer_cn': '以下内容不构成投资建议,需结合自身风险承受能力判断。',
|
||||
'items': [
|
||||
{
|
||||
'topic': '美元波动',
|
||||
'weakness': '若美元在短期内持续走强,黄金可能承压。',
|
||||
'counter_evidence': '实际利率仍处下行或中性,黄金下方支撑尚在。',
|
||||
},
|
||||
{
|
||||
'topic': '投机拥挤',
|
||||
'weakness': '当资金快速涌入时,行情容易出现脉冲式回调。',
|
||||
'counter_evidence': '央行和长期配置资金可部分对冲短线拥挤。',
|
||||
},
|
||||
],
|
||||
'verification_notes': ['关注央行月度购金变化。', '关注 ETF 净流入是否持续两周以上。'],
|
||||
}),
|
||||
_module('gold-compliance', 'source_compliance', '来源与合规', {
|
||||
'source_note': '来源以公开研报、统计口径和机构原文为准,结构化内容用于中文解读。',
|
||||
'copyright_cn': '版权归原始发布机构与作者所有。',
|
||||
'disclaimer': '本内容为公开/授权研报的结构化解读,不构成投资建议。',
|
||||
}),
|
||||
_module('gold-institution', 'institution', '机构', {
|
||||
'name_cn': '世界黄金协会',
|
||||
'report_count': 6,
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
static final ReportDetail _bis = ReportDetail(
|
||||
id: 'bis-quarterly-2026-q1',
|
||||
titleCn: 'BIS 季报 2026年3月:市场重新校准',
|
||||
institution: _bisSummary,
|
||||
oneLiner: '表面平静之下,全球金融市场正经历深刻的流向切换与重新校准。',
|
||||
source: const {'source_tier': 'A', 'source_name': 'BIS'},
|
||||
topics: const ['宏观', '货币政策'],
|
||||
hasAudio: true,
|
||||
releasedAt: '2026-03-05',
|
||||
modules: [
|
||||
_module('bis-basic', 'basic_info', '基本信息', {
|
||||
'summary_cn': 'BIS 关注全球宏观流动、资本配置和金融体系的再平衡。',
|
||||
'topics': ['宏观', '货币政策'],
|
||||
}),
|
||||
_module('bis-insights', 'core_insights', '核心洞察', {
|
||||
'points': [
|
||||
{'kind': 'view', 'text': '市场定价已从单一利率路径转向对增长、通胀和资本流动的综合校准。'},
|
||||
{'kind': 'number', 'text': '跨境资本流向的再分配比利率本身更能解释当下的市场分化。'},
|
||||
],
|
||||
}, hasDetailPage: true),
|
||||
_module('bis-audio', 'audio', '音频解读', {
|
||||
'audio_id': 'audio_bis_q1_2026',
|
||||
'title_cn': 'BIS 季报 2026年3月:市场重新校准',
|
||||
'duration_sec': 1040,
|
||||
}),
|
||||
_module('bis-compliance', 'source_compliance', '来源与合规', {
|
||||
'source_note': '该模块用于展示机构原文与结构化解读的对应关系。',
|
||||
'copyright_cn': '版权归 BIS 原始报告与作者所有。',
|
||||
'disclaimer': '本内容为公开/授权研报的结构化解读,不构成投资建议。',
|
||||
}),
|
||||
_module('bis-institution', 'institution', '机构', {
|
||||
'name_cn': '国际清算银行 BIS',
|
||||
'report_count': 4,
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
static final ReportDetail _iea = ReportDetail(
|
||||
id: 'iea-oil-monthly-2026-05',
|
||||
titleCn: '石油市场月报:需求放缓,供给为何仍偏紧?',
|
||||
institution: _ieaSummary,
|
||||
oneLiner: '需求增速放缓,但减产纪律与库存偏低支撑油价下方。',
|
||||
source: const {'source_tier': 'A', 'source_name': 'IEA'},
|
||||
topics: const ['能源', '大宗'],
|
||||
hasAudio: true,
|
||||
releasedAt: '2026-05-20',
|
||||
modules: [
|
||||
_module('iea-basic', 'basic_info', '基本信息', {
|
||||
'summary_cn': 'IEA 月报聚焦全球原油供需、库存和宏观风险。',
|
||||
'topics': ['能源', '大宗'],
|
||||
}),
|
||||
_module('iea-insights', 'core_insights', '核心洞察', {
|
||||
'points': [
|
||||
{'kind': 'view', 'text': '需求放缓并不自动意味着价格回落,关键还是供给纪律和库存水平。'},
|
||||
{'kind': 'number', 'text': '库存偏低时,价格对中短期扰动的敏感度明显提高。'},
|
||||
],
|
||||
}, hasDetailPage: true),
|
||||
_module('iea-audio', 'audio', '音频解读', {
|
||||
'audio_id': 'audio_iea_2026_05',
|
||||
'title_cn': '石油市场月报:需求放缓,供给为何仍偏紧?',
|
||||
'duration_sec': 1120,
|
||||
}),
|
||||
_module('iea-key-data', 'key_data', '关键数据', {
|
||||
'rows': [
|
||||
{
|
||||
'metric': '需求增速',
|
||||
'value': '放缓',
|
||||
'unit': '',
|
||||
'judgment': '不代表价格立刻下行。',
|
||||
},
|
||||
{
|
||||
'metric': '供给纪律',
|
||||
'value': '偏紧',
|
||||
'unit': '',
|
||||
'judgment': '减产执行仍在延续。',
|
||||
},
|
||||
{'metric': '库存', 'value': '偏低', 'unit': '', 'judgment': '对价格形成支撑。'},
|
||||
],
|
||||
}),
|
||||
_module('iea-compliance', 'source_compliance', '来源与合规', {
|
||||
'source_note': 'IEA 原文与统计框架保持一致,中文内容仅用于结构化阅读。',
|
||||
'copyright_cn': '版权归原始发布机构与作者所有。',
|
||||
'disclaimer': '本内容为公开/授权研报的结构化解读,不构成投资建议。',
|
||||
}),
|
||||
_module('iea-institution', 'institution', '机构', {
|
||||
'name_cn': '国际能源署',
|
||||
'report_count': 5,
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
static final ReportDetail _worldBank = ReportDetail(
|
||||
id: 'worldbank-commodities-2026-04',
|
||||
titleCn: '世界银行大宗商品展望:价格见顶了吗?',
|
||||
institution: _worldBankSummary,
|
||||
oneLiner: '全球增长预期放缓,但价格路径仍受供给侧扰动影响。',
|
||||
source: const {'source_tier': 'A', 'source_name': 'World Bank'},
|
||||
topics: const ['大宗', '全球增长'],
|
||||
hasAudio: true,
|
||||
releasedAt: '2026-04-18',
|
||||
modules: [
|
||||
_module('wb-basic', 'basic_info', '基本信息', {
|
||||
'summary_cn': '世界银行展望通常从全球增长、贸易和大宗商品价格三个层面展开。',
|
||||
'topics': ['大宗', '全球增长'],
|
||||
}),
|
||||
_module('wb-insights', 'core_insights', '核心洞察', {
|
||||
'points': [
|
||||
{'kind': 'view', 'text': '价格是否见顶,往往取决于供给扰动能否被需求放缓完全吸收。'},
|
||||
{'kind': 'risk', 'text': '若全球增长进一步放缓,大宗商品的边际弹性会显著下降。'},
|
||||
],
|
||||
}, hasDetailPage: true),
|
||||
_module('wb-audio', 'audio', '音频解读', {
|
||||
'audio_id': 'audio_worldbank_2026_04',
|
||||
'title_cn': '世界银行大宗商品展望:价格见顶了吗?',
|
||||
'duration_sec': 980,
|
||||
}),
|
||||
_module('wb-compliance', 'source_compliance', '来源与合规', {
|
||||
'source_note': '世界银行报告适合作为全球商品价格的基准视角。',
|
||||
'copyright_cn': '版权归原始发布机构与作者所有。',
|
||||
'disclaimer': '本内容为公开/授权研报的结构化解读,不构成投资建议。',
|
||||
}),
|
||||
_module('wb-institution', 'institution', '机构', {
|
||||
'name_cn': '世界银行',
|
||||
'report_count': 3,
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
static final List<ReportDetail> _details = [_gold, _bis, _iea, _worldBank];
|
||||
|
||||
static final Map<String, ReportDetail> _detailById = {
|
||||
for (final detail in _details) detail.id: detail,
|
||||
};
|
||||
|
||||
static final Map<String, Institution> _institutionDetails = {
|
||||
'wgc': _institutionDetail(
|
||||
base: _wgcSummary,
|
||||
recentReports: [_gold.asCard()],
|
||||
),
|
||||
'bis': _institutionDetail(
|
||||
base: _bisSummary,
|
||||
recentReports: [_bis.asCard()],
|
||||
),
|
||||
'iea': _institutionDetail(
|
||||
base: _ieaSummary,
|
||||
recentReports: [_iea.asCard()],
|
||||
),
|
||||
'worldbank': _institutionDetail(
|
||||
base: _worldBankSummary,
|
||||
recentReports: [_worldBank.asCard()],
|
||||
),
|
||||
'ssga': _institutionDetail(
|
||||
base: _ssgaSummary,
|
||||
recentReports: [_gold.asCard()],
|
||||
),
|
||||
};
|
||||
|
||||
static final Map<String, ModuleDetail> _moduleDetails = {
|
||||
'gold-insights': _moduleDetail(_gold.modules[1]),
|
||||
'gold-timeline': _moduleDetail(_gold.modules[3]),
|
||||
'gold-study': _moduleDetail(_gold.modules[5]),
|
||||
'bis-insights': _moduleDetail(_bis.modules[1]),
|
||||
'iea-insights': _moduleDetail(_iea.modules[1]),
|
||||
'wb-insights': _moduleDetail(_worldBank.modules[1]),
|
||||
};
|
||||
|
||||
@override
|
||||
Future<List<ReportCardModel>> recommended() async => [
|
||||
_gold.asCard(),
|
||||
_bis.asCard(),
|
||||
_iea.asCard(),
|
||||
];
|
||||
|
||||
@override
|
||||
Future<List<ReportCardModel>> reports() async =>
|
||||
_details.map((d) => d.asCard()).toList();
|
||||
|
||||
@override
|
||||
Future<List<Institution>> institutions() async {
|
||||
return _institutionDetails.values.toList()
|
||||
..sort((a, b) => b.reportCount.compareTo(a.reportCount));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Institution> institutionDetail(String institutionId) async {
|
||||
return _institutionDetails[institutionId] ?? _institutionDetails['wgc']!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<AudioItem>> listen() async {
|
||||
return [
|
||||
_audioFromReport(_gold, 860),
|
||||
_audioFromReport(_bis, 1040),
|
||||
_audioFromReport(_iea, 1120),
|
||||
_audioFromReport(_worldBank, 980),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ReportDetail> reportDetail(String reportId) async {
|
||||
return _detailById[reportId] ?? _gold;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ModuleDetail> moduleDetail(String reportId, String moduleId) async {
|
||||
return _moduleDetails[moduleId] ??
|
||||
ModuleDetail(
|
||||
id: moduleId,
|
||||
type: 'basic_info',
|
||||
titleCn: '模块详情',
|
||||
content: const {'preview_summary': '该模块暂无单独详情数据。'},
|
||||
);
|
||||
}
|
||||
|
||||
static Institution _institutionSummary({
|
||||
required String id,
|
||||
required String nameCn,
|
||||
required String nameEn,
|
||||
required String logoUrl,
|
||||
required String institutionType,
|
||||
required String sourceTier,
|
||||
required String websiteUrl,
|
||||
required List<String> coveredTopics,
|
||||
required int reportCount,
|
||||
required String introCn,
|
||||
required String credibilityNote,
|
||||
}) {
|
||||
return Institution(
|
||||
id: id,
|
||||
nameCn: nameCn,
|
||||
nameEn: nameEn,
|
||||
logoUrl: logoUrl,
|
||||
institutionType: institutionType,
|
||||
sourceTier: sourceTier,
|
||||
websiteUrl: websiteUrl,
|
||||
coveredTopics: coveredTopics,
|
||||
reportCount: reportCount,
|
||||
introCn: introCn,
|
||||
credibilityNote: credibilityNote,
|
||||
);
|
||||
}
|
||||
|
||||
static Institution _institutionDetail({
|
||||
required Institution base,
|
||||
required List<ReportCardModel> recentReports,
|
||||
}) {
|
||||
return Institution(
|
||||
id: base.id,
|
||||
nameCn: base.nameCn,
|
||||
nameEn: base.nameEn,
|
||||
logoUrl: base.logoUrl,
|
||||
institutionType: base.institutionType,
|
||||
sourceTier: base.sourceTier,
|
||||
websiteUrl: base.websiteUrl,
|
||||
coveredTopics: base.coveredTopics,
|
||||
reportCount: base.reportCount,
|
||||
latestReportAt: base.latestReportAt,
|
||||
credibilityNote: base.credibilityNote,
|
||||
introCn: base.introCn,
|
||||
recentReports: recentReports,
|
||||
);
|
||||
}
|
||||
|
||||
static DisplayModule _module(
|
||||
String id,
|
||||
String type,
|
||||
String titleCn,
|
||||
JsonMap content, {
|
||||
bool hasDetailPage = false,
|
||||
String renderMode = 'inline',
|
||||
}) {
|
||||
return DisplayModule(
|
||||
id: id,
|
||||
type: type,
|
||||
titleCn: titleCn,
|
||||
renderMode: renderMode,
|
||||
hasDetailPage: hasDetailPage,
|
||||
content: content,
|
||||
preview: content,
|
||||
);
|
||||
}
|
||||
|
||||
static ModuleDetail _moduleDetail(DisplayModule module) {
|
||||
return ModuleDetail(
|
||||
id: module.id,
|
||||
type: module.type,
|
||||
titleCn: module.titleCn,
|
||||
content: module.content,
|
||||
contentEtag: 'mock',
|
||||
cacheVersion: 'mock',
|
||||
);
|
||||
}
|
||||
|
||||
static AudioItem _audioFromReport(ReportDetail report, int duration) {
|
||||
return AudioItem(
|
||||
audioId: 'audio_${report.id}',
|
||||
reportId: report.id,
|
||||
titleCn: report.titleCn,
|
||||
reportTitleCn: report.titleCn,
|
||||
durationSec: duration,
|
||||
institution: report.institution,
|
||||
releasedAt: report.releasedAt,
|
||||
cacheVersion: 'mock',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,16 @@ List<String> asStringList(Object? value) {
|
||||
|
||||
JsonMap asMap(Object? value) {
|
||||
if (value is Map<String, dynamic>) return value;
|
||||
if (value is Map) return value.map((key, val) => MapEntry(key.toString(), val));
|
||||
if (value is Map) {
|
||||
return value.map((key, val) => MapEntry(key.toString(), val));
|
||||
}
|
||||
return const {};
|
||||
}
|
||||
|
||||
List<JsonMap> asMapList(Object? value) {
|
||||
if (value is List) return value.map(asMap).where((item) => item.isNotEmpty).toList();
|
||||
if (value is List) {
|
||||
return value.map(asMap).where((item) => item.isNotEmpty).toList();
|
||||
}
|
||||
return const [];
|
||||
}
|
||||
|
||||
@@ -46,6 +50,7 @@ class Institution {
|
||||
required this.id,
|
||||
required this.nameCn,
|
||||
this.nameEn = '',
|
||||
this.logoUrl = '',
|
||||
this.institutionType = '',
|
||||
this.sourceTier = '',
|
||||
this.websiteUrl = '',
|
||||
@@ -60,6 +65,7 @@ class Institution {
|
||||
final String id;
|
||||
final String nameCn;
|
||||
final String nameEn;
|
||||
final String logoUrl;
|
||||
final String institutionType;
|
||||
final String sourceTier;
|
||||
final String websiteUrl;
|
||||
@@ -75,6 +81,7 @@ class Institution {
|
||||
id: asString(json['institution_id']),
|
||||
nameCn: asString(json['name_cn']),
|
||||
nameEn: asString(json['name_en']),
|
||||
logoUrl: asString(json['logo_url']),
|
||||
institutionType: asString(json['institution_type']),
|
||||
sourceTier: asString(json['source_tier']),
|
||||
websiteUrl: asString(json['website_url']),
|
||||
@@ -83,9 +90,9 @@ class Institution {
|
||||
latestReportAt: json['latest_report_at']?.toString(),
|
||||
credibilityNote: asString(json['credibility_note']),
|
||||
introCn: asString(json['intro_cn']),
|
||||
recentReports: asMapList(json['recent_reports'])
|
||||
.map(ReportCardModel.fromJson)
|
||||
.toList(),
|
||||
recentReports: asMapList(
|
||||
json['recent_reports'],
|
||||
).map(ReportCardModel.fromJson).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -161,7 +168,10 @@ class AudioItem {
|
||||
audioId: asString(json['audio_id']),
|
||||
reportId: asString(json['report_id']),
|
||||
titleCn: asString(json['title_cn']),
|
||||
reportTitleCn: asString(json['report_title_cn'], asString(json['title_cn'])),
|
||||
reportTitleCn: asString(
|
||||
json['report_title_cn'],
|
||||
asString(json['title_cn']),
|
||||
),
|
||||
durationSec: asInt(json['duration_sec']),
|
||||
institution: Institution.fromJson(asMap(json['institution'])),
|
||||
releasedAt: json['released_at']?.toString(),
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import 'api/mock_report_data_source.dart';
|
||||
import 'api/report_data_source.dart';
|
||||
import 'audio_player_controller.dart';
|
||||
import '../widgets/mini_player.dart';
|
||||
|
||||
final reportDataSourceProvider = Provider<ReportDataSource>((ref) {
|
||||
const useMock = bool.fromEnvironment('YANTING_USE_MOCK', defaultValue: true);
|
||||
if (useMock) {
|
||||
return MockReportDataSource();
|
||||
}
|
||||
return RnbApiDataSource();
|
||||
});
|
||||
|
||||
final audioPlayerControllerProvider =
|
||||
StateNotifierProvider<AudioPlayerController, PlayerStateModel>((ref) {
|
||||
return AudioPlayerController();
|
||||
});
|
||||
return AudioPlayerController();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user