yidaconnector 2026.6.11

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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +383 -0
  3. package/bin/yida.js +670 -0
  4. package/lib/app/form-navigation.js +58 -0
  5. package/lib/app/get-schema.js +538 -0
  6. package/lib/auth/auth.js +294 -0
  7. package/lib/auth/cdp-browser-login.js +390 -0
  8. package/lib/auth/codex-login.js +71 -0
  9. package/lib/auth/login.js +475 -0
  10. package/lib/auth/org.js +363 -0
  11. package/lib/auth/qr-login.js +1563 -0
  12. package/lib/core/chalk.js +384 -0
  13. package/lib/core/check-update.js +82 -0
  14. package/lib/core/cli-error.js +39 -0
  15. package/lib/core/command-manifest.js +106 -0
  16. package/lib/core/env-cmd.js +545 -0
  17. package/lib/core/env-manager.js +601 -0
  18. package/lib/core/env.js +287 -0
  19. package/lib/core/i18n.js +177 -0
  20. package/lib/core/locales/ar.js +805 -0
  21. package/lib/core/locales/de.js +805 -0
  22. package/lib/core/locales/en.js +1623 -0
  23. package/lib/core/locales/es.js +805 -0
  24. package/lib/core/locales/fr.js +805 -0
  25. package/lib/core/locales/hi.js +805 -0
  26. package/lib/core/locales/ja.js +1197 -0
  27. package/lib/core/locales/ko.js +807 -0
  28. package/lib/core/locales/pt.js +805 -0
  29. package/lib/core/locales/vi.js +805 -0
  30. package/lib/core/locales/zh-HK.js +1233 -0
  31. package/lib/core/locales/zh.js +1584 -0
  32. package/lib/core/query-data.js +781 -0
  33. package/lib/core/redact.js +100 -0
  34. package/lib/core/utils.js +799 -0
  35. package/lib/core/yida-client.js +117 -0
  36. package/package.json +94 -0
  37. package/project/config.json +4 -0
  38. package/project/pages/src/demo-birthday-game.oyd.jsx +832 -0
  39. package/project/pages/src/demo-chip-insight.oyd.jsx +983 -0
  40. package/project/pages/src/demo-compat-smoke.oyd.jsx +58 -0
  41. package/project/pages/src/demo-crm-batch-entry.oyd.jsx +805 -0
  42. package/project/pages/src/demo-crm-dashboard.oyd.jsx +677 -0
  43. package/project/pages/src/demo-future-vision-2026.oyd.jsx +1102 -0
  44. package/project/pages/src/demo-ppt.oyd.jsx +1192 -0
  45. package/project/pages/src/demo-salary-calculator.oyd.jsx +904 -0
  46. package/project/pages/src/yidaconnector-knowledge-doc.oyd.jsx +1714 -0
  47. package/project/prd/demo-birthday-game.md +39 -0
  48. package/project/prd/demo-crm.md +463 -0
  49. package/project/prd/demo-dingtalk-ai-solution-center.md +425 -0
  50. package/project/prd/demo-future-vision-2026.md +78 -0
  51. package/project/prd/demo-salary-calculator.md +101 -0
  52. package/scripts/build-skills-package.js +406 -0
  53. package/scripts/check-syntax.js +59 -0
  54. package/scripts/demo-dws.sh +106 -0
  55. package/scripts/e2e-real/cleanup.js +67 -0
  56. package/scripts/e2e-real/fixtures/form-fields.json +18 -0
  57. package/scripts/e2e-real/full-runner.js +1566 -0
  58. package/scripts/e2e-real/runner.js +293 -0
  59. package/scripts/e2e-real/skill-coverage.js +115 -0
  60. package/scripts/generate-command-docs.js +109 -0
  61. package/scripts/nightly-smoke.js +134 -0
  62. package/scripts/postinstall.js +545 -0
  63. package/scripts/solution-center-runner.js +368 -0
  64. package/scripts/validate-ci.sh +50 -0
  65. package/scripts/validate-command-manifest.js +119 -0
  66. package/scripts/validate-package-size.js +78 -0
  67. package/scripts/validate-skills.js +247 -0
  68. package/scripts/validate-structure.js +66 -0
  69. package/yida-skills/SKILL.md +163 -0
  70. package/yida-skills/references/yida-api.md +1309 -0
  71. package/yida-skills/skills/large-file-write/SKILL.md +91 -0
  72. package/yida-skills/skills/large-file-write/references/write-patterns.md +149 -0
  73. package/yida-skills/skills/large-file-write/scripts/write.js +157 -0
  74. package/yida-skills/skills/yida-data-management/SKILL.md +252 -0
  75. package/yida-skills/skills/yida-data-management/references/api-matrix.md +49 -0
  76. package/yida-skills/skills/yida-data-management/references/data-format-guide.md +159 -0
  77. package/yida-skills/skills/yida-data-management/references/verified-endpoints.md +62 -0
  78. package/yida-skills/skills/yida-login/SKILL.md +159 -0
  79. package/yida-skills/skills/yida-logout/SKILL.md +67 -0
@@ -0,0 +1,983 @@
1
+ // 半导体行业智能洞察平台 - 可视化看板
2
+ // 从表单实时加载数据,展示市场趋势、公司竞争力、行业舆情
3
+
4
+ var FORM_MARKET = 'FORM-8EE55570104D4537BE9C3A86530E5DF05AJ3';
5
+ var FORM_COMPANY = 'FORM-4F328A699E4B4C88A436AD4BFCE62FF0Z7FB';
6
+ var FORM_SENTIMENT = 'FORM-14F9ECC414E24A908AC4179F37751C4DWTXA';
7
+ var APP_TYPE = 'APP_H3SGUZODOIT37NUFJXUO';
8
+
9
+ // 字段映射
10
+ var MF = { year: 'textField_sdei13zi0', marketSize: 'numberField_sdej29dnq', growth: 'textField_sdej3fyou', aiSize: 'numberField_sdej4zb6q', aiRatio: 'textField_sdej5eyvd', note: 'textareaField_sdej6mim5' };
11
+ var CF = { name: 'textField_su5y15ixq', marketCap: 'numberField_su5y2zmtz', revenue: 'numberField_su5y3yvwd', aiRevenue: 'numberField_su5y4tdox', share: 'textField_su5y5a89m', product: 'textField_su5y6z5fq', techRoute: 'textareaField_su5y7c72a', rating: 'selectField_su5z89ksz' };
12
+ var SF = { title: 'textField_t90f17mmk', category: 'selectField_t90f21qco', impact: 'selectField_t90f3jcrk', date: 'dateField_t90f4yl9u', summary: 'textareaField_t90f56bsg', analysis: 'textareaField_t90f6py0o', source: 'textField_t90f7alnc' };
13
+
14
+ var _customState = {
15
+ loading: true,
16
+ activeTab: 'overview',
17
+ marketData: [],
18
+ companyData: [],
19
+ sentimentData: [],
20
+ expandedCard: null,
21
+ echartsLoaded: false,
22
+ chartInstances: {},
23
+ };
24
+
25
+ export function getCustomState(key) {
26
+ if (key) return _customState[key];
27
+ return _.clone(_customState);
28
+ }
29
+
30
+ export function setCustomState(newState) {
31
+ Object.keys(newState).forEach(function(key) {
32
+ _customState[key] = newState[key];
33
+ });
34
+ this.forceUpdate();
35
+ }
36
+
37
+ export function forceUpdate() {
38
+ this.setState({ timestamp: new Date().getTime() });
39
+ }
40
+
41
+ export function didMount() {
42
+ var self = this;
43
+ // 注入覆盖样式(确保在平台 CSS 之后生效)
44
+ var styleTag = document.createElement('style');
45
+ styleTag.textContent = '.vc-deep-container-entry.vc-rootcontent{padding:0!important;margin-top:0!important;margin-right:0!important;margin-bottom:0!important;margin-left:0!important}';
46
+ document.head.appendChild(styleTag);
47
+ // 加载 ECharts 5.5.0
48
+ this.utils.loadScript('https://g.alicdn.com/code/lib/echarts/5.5.0/echarts.min.js').then(function() {
49
+ _customState.echartsLoaded = true;
50
+ self.initCharts();
51
+ }).catch(function(err) {
52
+ console.error('ECharts 加载失败:', err);
53
+ });
54
+ this.loadAllData();
55
+ }
56
+
57
+ export function didUnmount() {}
58
+
59
+ export function loadAllData() {
60
+ var self = this;
61
+ _customState.loading = true;
62
+ self.forceUpdate();
63
+
64
+ var marketPromise = self.utils.yida.searchFormDatas({
65
+ formUuid: FORM_MARKET,
66
+ searchFieldJson: JSON.stringify({}),
67
+ currentPage: 1,
68
+ pageSize: 50,
69
+ });
70
+
71
+ var companyPromise = self.utils.yida.searchFormDatas({
72
+ formUuid: FORM_COMPANY,
73
+ searchFieldJson: JSON.stringify({}),
74
+ currentPage: 1,
75
+ pageSize: 50,
76
+ });
77
+
78
+ var sentimentPromise = self.utils.yida.searchFormDatas({
79
+ formUuid: FORM_SENTIMENT,
80
+ searchFieldJson: JSON.stringify({}),
81
+ currentPage: 1,
82
+ pageSize: 50,
83
+ });
84
+
85
+ Promise.all([marketPromise, companyPromise, sentimentPromise]).then(function(results) {
86
+ var marketRaw = (results[0] && results[0].data) || [];
87
+ var companyRaw = (results[1] && results[1].data) || [];
88
+ var sentimentRaw = (results[2] && results[2].data) || [];
89
+
90
+ var marketList = _.sortBy(marketRaw.map(function(item) {
91
+ var fd = _.get(item, 'formData', {});
92
+ return { year: fd[MF.year] || '', marketSize: fd[MF.marketSize] || 0, growth: fd[MF.growth] || '', aiSize: fd[MF.aiSize] || 0, aiRatio: fd[MF.aiRatio] || '', note: fd[MF.note] || '' };
93
+ }), 'year');
94
+
95
+ var companyList = _.orderBy(companyRaw.map(function(item) {
96
+ var fd = _.get(item, 'formData', {});
97
+ return { name: fd[CF.name] || '', marketCap: fd[CF.marketCap] || 0, revenue: fd[CF.revenue] || 0, aiRevenue: fd[CF.aiRevenue] || 0, share: fd[CF.share] || '', product: fd[CF.product] || '', techRoute: fd[CF.techRoute] || '', rating: fd[CF.rating] || '' };
98
+ }), 'marketCap', 'desc');
99
+
100
+ var sentimentList = _.orderBy(sentimentRaw.map(function(item) {
101
+ var fd = _.get(item, 'formData', {});
102
+ return { title: fd[SF.title] || '', category: fd[SF.category] || '', impact: fd[SF.impact] || '', date: fd[SF.date] || 0, summary: fd[SF.summary] || '', analysis: fd[SF.analysis] || '', source: fd[SF.source] || '' };
103
+ }), 'date', 'desc');
104
+
105
+ self.setCustomState({
106
+ loading: false,
107
+ marketData: marketList,
108
+ companyData: companyList,
109
+ sentimentData: sentimentList,
110
+ });
111
+ self.initCharts();
112
+ }).catch(function(err) {
113
+ console.error('数据加载失败:', err);
114
+ self.setCustomState({ loading: false });
115
+ });
116
+ }
117
+
118
+ // ===== ECharts 图表初始化 =====
119
+ export function initCharts() {
120
+ var self = this;
121
+ if (!_customState.echartsLoaded || typeof echarts === 'undefined') return;
122
+ setTimeout(function() { self.initCurrentTabChart(); }, 100);
123
+ }
124
+
125
+ export function initCurrentTabChart() {
126
+ var activeTab = _customState.activeTab;
127
+ if (!_customState.echartsLoaded || typeof echarts === 'undefined') return;
128
+
129
+ if (activeTab === 'overview') {
130
+ this.initMarketChart();
131
+ this.initAiTrendChart();
132
+ } else if (activeTab === 'company') {
133
+ this.initCompanyChart();
134
+ } else if (activeTab === 'sentiment') {
135
+ this.initImpactPieChart();
136
+ this.initCategoryPieChart();
137
+ }
138
+ }
139
+
140
+ export function initMarketChart() {
141
+ var container = document.getElementById('chart-market-bar');
142
+ if (!container) return;
143
+ if (_customState.chartInstances.marketBar) _customState.chartInstances.marketBar.dispose();
144
+ var chart = echarts.init(container, null, { renderer: 'canvas' });
145
+ _customState.chartInstances.marketBar = chart;
146
+
147
+ var marketData = _customState.marketData;
148
+ var years = marketData.map(function(d) { return d.year; });
149
+ var marketSizes = marketData.map(function(d) { return d.marketSize; });
150
+ var aiSizes = marketData.map(function(d) { return d.aiSize; });
151
+
152
+ chart.setOption({
153
+ backgroundColor: 'transparent',
154
+ tooltip: {
155
+ trigger: 'axis',
156
+ backgroundColor: 'rgba(15, 23, 56, 0.95)',
157
+ borderColor: 'rgba(0, 212, 255, 0.3)',
158
+ textStyle: { color: '#e8f0fe', fontSize: 13 },
159
+ formatter: function(params) {
160
+ var year = params[0].axisValue;
161
+ var result = '<div style="font-weight:700;margin-bottom:6px">' + year + '</div>';
162
+ params.forEach(function(p) {
163
+ result += '<div style="display:flex;align-items:center;gap:6px;margin:3px 0">';
164
+ result += '<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:' + p.color + '"></span>';
165
+ result += p.seriesName + ': <b>' + p.value.toLocaleString() + '</b> 亿美元</div>';
166
+ });
167
+ return result;
168
+ }
169
+ },
170
+ legend: {
171
+ data: ['半导体总市场', 'AI芯片市场'],
172
+ textStyle: { color: 'rgba(200,220,255,0.6)', fontSize: 12 },
173
+ top: 0,
174
+ right: 0,
175
+ },
176
+ grid: { left: 60, right: 20, top: 40, bottom: 40 },
177
+ xAxis: {
178
+ type: 'category',
179
+ data: years,
180
+ axisLabel: { color: 'rgba(200,220,255,0.6)', fontSize: 13, fontWeight: 600 },
181
+ axisLine: { lineStyle: { color: 'rgba(0,212,255,0.15)' } },
182
+ axisTick: { show: false },
183
+ },
184
+ yAxis: {
185
+ type: 'value',
186
+ name: '亿美元',
187
+ nameTextStyle: { color: 'rgba(200,220,255,0.4)', fontSize: 11 },
188
+ axisLabel: { color: 'rgba(200,220,255,0.4)', fontSize: 11, formatter: function(v) { return v.toLocaleString(); } },
189
+ splitLine: { lineStyle: { color: 'rgba(0,212,255,0.06)' } },
190
+ axisLine: { show: false },
191
+ },
192
+ series: [
193
+ {
194
+ name: '半导体总市场',
195
+ type: 'bar',
196
+ data: marketSizes,
197
+ barWidth: '35%',
198
+ itemStyle: {
199
+ borderRadius: [6, 6, 0, 0],
200
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
201
+ { offset: 0, color: '#00d4ff' },
202
+ { offset: 1, color: 'rgba(0,212,255,0.2)' }
203
+ ]),
204
+ },
205
+ emphasis: { itemStyle: { shadowBlur: 20, shadowColor: 'rgba(0,212,255,0.4)' } },
206
+ label: { show: true, position: 'top', color: '#00d4ff', fontSize: 12, fontWeight: 700, formatter: function(p) { return p.value.toLocaleString(); } },
207
+ },
208
+ {
209
+ name: 'AI芯片市场',
210
+ type: 'bar',
211
+ data: aiSizes,
212
+ barWidth: '35%',
213
+ itemStyle: {
214
+ borderRadius: [6, 6, 0, 0],
215
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
216
+ { offset: 0, color: '#7c3aed' },
217
+ { offset: 1, color: 'rgba(124,58,237,0.2)' }
218
+ ]),
219
+ },
220
+ emphasis: { itemStyle: { shadowBlur: 20, shadowColor: 'rgba(124,58,237,0.4)' } },
221
+ label: { show: true, position: 'top', color: '#7c3aed', fontSize: 12, fontWeight: 700 },
222
+ },
223
+ ],
224
+ animationDuration: 1200,
225
+ animationEasing: 'elasticOut',
226
+ });
227
+
228
+ window.addEventListener('resize', function() { chart.resize(); });
229
+ }
230
+
231
+ export function initAiTrendChart() {
232
+ var container = document.getElementById('chart-ai-trend');
233
+ if (!container) return;
234
+ if (_customState.chartInstances.aiTrend) _customState.chartInstances.aiTrend.dispose();
235
+ var chart = echarts.init(container, null, { renderer: 'canvas' });
236
+ _customState.chartInstances.aiTrend = chart;
237
+
238
+ var marketData = _customState.marketData;
239
+ var years = marketData.map(function(d) { return d.year; });
240
+ var aiRatios = marketData.map(function(d) { return parseFloat(d.aiRatio) || 0; });
241
+ var growths = marketData.map(function(d) { return parseFloat(d.growth) || 0; });
242
+
243
+ chart.setOption({
244
+ backgroundColor: 'transparent',
245
+ tooltip: {
246
+ trigger: 'axis',
247
+ backgroundColor: 'rgba(15, 23, 56, 0.95)',
248
+ borderColor: 'rgba(0, 212, 255, 0.3)',
249
+ textStyle: { color: '#e8f0fe', fontSize: 13 },
250
+ },
251
+ legend: {
252
+ data: ['AI芯片占比', '同比增长率'],
253
+ textStyle: { color: 'rgba(200,220,255,0.6)', fontSize: 12 },
254
+ top: 0,
255
+ right: 0,
256
+ },
257
+ grid: { left: 50, right: 50, top: 40, bottom: 40 },
258
+ xAxis: {
259
+ type: 'category',
260
+ data: years,
261
+ axisLabel: { color: 'rgba(200,220,255,0.6)', fontSize: 13 },
262
+ axisLine: { lineStyle: { color: 'rgba(0,212,255,0.15)' } },
263
+ axisTick: { show: false },
264
+ },
265
+ yAxis: [
266
+ {
267
+ type: 'value',
268
+ name: 'AI占比(%)',
269
+ nameTextStyle: { color: 'rgba(200,220,255,0.4)', fontSize: 11 },
270
+ axisLabel: { color: 'rgba(200,220,255,0.4)', fontSize: 11, formatter: '{value}%' },
271
+ splitLine: { lineStyle: { color: 'rgba(0,212,255,0.06)' } },
272
+ axisLine: { show: false },
273
+ },
274
+ {
275
+ type: 'value',
276
+ name: '增长率(%)',
277
+ nameTextStyle: { color: 'rgba(200,220,255,0.4)', fontSize: 11 },
278
+ axisLabel: { color: 'rgba(200,220,255,0.4)', fontSize: 11, formatter: '{value}%' },
279
+ splitLine: { show: false },
280
+ axisLine: { show: false },
281
+ },
282
+ ],
283
+ series: [
284
+ {
285
+ name: 'AI芯片占比',
286
+ type: 'line',
287
+ data: aiRatios,
288
+ smooth: true,
289
+ symbol: 'circle',
290
+ symbolSize: 10,
291
+ lineStyle: { width: 3, color: '#7c3aed' },
292
+ itemStyle: { color: '#7c3aed', borderWidth: 2, borderColor: '#fff' },
293
+ areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(124,58,237,0.3)' }, { offset: 1, color: 'rgba(124,58,237,0.02)' }]) },
294
+ label: { show: true, position: 'top', color: '#7c3aed', fontSize: 12, fontWeight: 600, formatter: '{c}%' },
295
+ },
296
+ {
297
+ name: '同比增长率',
298
+ type: 'line',
299
+ yAxisIndex: 1,
300
+ data: growths,
301
+ smooth: true,
302
+ symbol: 'diamond',
303
+ symbolSize: 10,
304
+ lineStyle: { width: 3, color: '#2ed573', type: 'dashed' },
305
+ itemStyle: { color: '#2ed573', borderWidth: 2, borderColor: '#fff' },
306
+ label: { show: true, position: 'bottom', color: '#2ed573', fontSize: 11, formatter: '{c}%' },
307
+ },
308
+ ],
309
+ animationDuration: 1500,
310
+ });
311
+
312
+ window.addEventListener('resize', function() { chart.resize(); });
313
+ }
314
+
315
+ export function initCompanyChart() {
316
+ var container = document.getElementById('chart-company-bar');
317
+ if (!container) return;
318
+ if (_customState.chartInstances.companyBar) _customState.chartInstances.companyBar.dispose();
319
+ var chart = echarts.init(container, null, { renderer: 'canvas' });
320
+ _customState.chartInstances.companyBar = chart;
321
+
322
+ var companyData = _customState.companyData.slice().reverse();
323
+ var names = companyData.map(function(d) { return d.name; });
324
+ var marketCaps = companyData.map(function(d) { return d.marketCap; });
325
+ var revenues = companyData.map(function(d) { return d.revenue; });
326
+ var aiRevenues = companyData.map(function(d) { return d.aiRevenue; });
327
+
328
+ chart.setOption({
329
+ backgroundColor: 'transparent',
330
+ tooltip: {
331
+ trigger: 'axis',
332
+ axisPointer: { type: 'shadow' },
333
+ backgroundColor: 'rgba(15, 23, 56, 0.95)',
334
+ borderColor: 'rgba(0, 212, 255, 0.3)',
335
+ textStyle: { color: '#e8f0fe', fontSize: 13 },
336
+ formatter: function(params) {
337
+ var name = params[0].axisValue;
338
+ var result = '<div style="font-weight:700;margin-bottom:6px">' + name + '</div>';
339
+ params.forEach(function(p) {
340
+ result += '<div style="display:flex;align-items:center;gap:6px;margin:3px 0">';
341
+ result += '<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:' + p.color + '"></span>';
342
+ result += p.seriesName + ': <b>' + p.value.toLocaleString() + '</b> 亿美元</div>';
343
+ });
344
+ return result;
345
+ }
346
+ },
347
+ legend: {
348
+ data: ['市值', '年营收', 'AI营收'],
349
+ textStyle: { color: 'rgba(200,220,255,0.6)', fontSize: 12 },
350
+ top: 0,
351
+ right: 0,
352
+ },
353
+ grid: { left: 100, right: 30, top: 40, bottom: 20 },
354
+ xAxis: {
355
+ type: 'value',
356
+ name: '亿美元',
357
+ nameTextStyle: { color: 'rgba(200,220,255,0.4)', fontSize: 11 },
358
+ axisLabel: { color: 'rgba(200,220,255,0.4)', fontSize: 11, formatter: function(v) { return v >= 10000 ? (v / 10000).toFixed(0) + '万' : v.toLocaleString(); } },
359
+ splitLine: { lineStyle: { color: 'rgba(0,212,255,0.06)' } },
360
+ },
361
+ yAxis: {
362
+ type: 'category',
363
+ data: names,
364
+ axisLabel: { color: '#e8f0fe', fontSize: 13, fontWeight: 600 },
365
+ axisLine: { lineStyle: { color: 'rgba(0,212,255,0.15)' } },
366
+ axisTick: { show: false },
367
+ },
368
+ series: [
369
+ {
370
+ name: '市值',
371
+ type: 'bar',
372
+ data: marketCaps,
373
+ barWidth: '25%',
374
+ itemStyle: {
375
+ borderRadius: [0, 6, 6, 0],
376
+ color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
377
+ { offset: 0, color: 'rgba(0,212,255,0.3)' },
378
+ { offset: 1, color: '#00d4ff' }
379
+ ]),
380
+ },
381
+ emphasis: { itemStyle: { shadowBlur: 15, shadowColor: 'rgba(0,212,255,0.4)' } },
382
+ },
383
+ {
384
+ name: '年营收',
385
+ type: 'bar',
386
+ data: revenues,
387
+ barWidth: '25%',
388
+ itemStyle: {
389
+ borderRadius: [0, 6, 6, 0],
390
+ color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
391
+ { offset: 0, color: 'rgba(46,213,115,0.3)' },
392
+ { offset: 1, color: '#2ed573' }
393
+ ]),
394
+ },
395
+ },
396
+ {
397
+ name: 'AI营收',
398
+ type: 'bar',
399
+ data: aiRevenues,
400
+ barWidth: '25%',
401
+ itemStyle: {
402
+ borderRadius: [0, 6, 6, 0],
403
+ color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
404
+ { offset: 0, color: 'rgba(124,58,237,0.3)' },
405
+ { offset: 1, color: '#7c3aed' }
406
+ ]),
407
+ },
408
+ },
409
+ ],
410
+ animationDuration: 1200,
411
+ animationEasing: 'elasticOut',
412
+ });
413
+
414
+ window.addEventListener('resize', function() { chart.resize(); });
415
+ }
416
+
417
+ export function initImpactPieChart() {
418
+ var container = document.getElementById('chart-impact-pie');
419
+ if (!container) return;
420
+ if (_customState.chartInstances.impactPie) _customState.chartInstances.impactPie.dispose();
421
+ var chart = echarts.init(container, null, { renderer: 'canvas' });
422
+ _customState.chartInstances.impactPie = chart;
423
+
424
+ var sentimentData = _customState.sentimentData;
425
+ var impactCount = { '重大': 0, '较大': 0, '一般': 0, '轻微': 0 };
426
+ sentimentData.forEach(function(item) {
427
+ if (impactCount.hasOwnProperty(item.impact)) impactCount[item.impact]++;
428
+ });
429
+
430
+ var pieData = Object.keys(impactCount).map(function(level) {
431
+ return { name: level, value: impactCount[level] };
432
+ }).filter(function(d) { return d.value > 0; });
433
+
434
+ var colorMap = { '重大': '#ff4757', '较大': '#ffa502', '一般': '#2ed573', '轻微': '#747d8c' };
435
+
436
+ chart.setOption({
437
+ backgroundColor: 'transparent',
438
+ tooltip: {
439
+ trigger: 'item',
440
+ backgroundColor: 'rgba(15, 23, 56, 0.95)',
441
+ borderColor: 'rgba(0, 212, 255, 0.3)',
442
+ textStyle: { color: '#e8f0fe', fontSize: 13 },
443
+ formatter: '{b}: {c}条 ({d}%)',
444
+ },
445
+ series: [{
446
+ type: 'pie',
447
+ radius: ['45%', '75%'],
448
+ center: ['50%', '55%'],
449
+ avoidLabelOverlap: true,
450
+ itemStyle: {
451
+ borderRadius: 8,
452
+ borderColor: '#0a0e27',
453
+ borderWidth: 3,
454
+ },
455
+ label: {
456
+ show: true,
457
+ color: '#e8f0fe',
458
+ fontSize: 13,
459
+ fontWeight: 600,
460
+ formatter: '{b}\n{c}条',
461
+ },
462
+ emphasis: {
463
+ label: { show: true, fontSize: 16, fontWeight: 'bold' },
464
+ itemStyle: { shadowBlur: 20, shadowColor: 'rgba(0,0,0,0.5)' },
465
+ },
466
+ data: pieData.map(function(d) {
467
+ return { name: d.name, value: d.value, itemStyle: { color: colorMap[d.name] || '#747d8c' } };
468
+ }),
469
+ animationType: 'scale',
470
+ animationEasing: 'elasticOut',
471
+ animationDelay: function(idx) { return idx * 200; },
472
+ }],
473
+ });
474
+
475
+ window.addEventListener('resize', function() { chart.resize(); });
476
+ }
477
+
478
+ export function initCategoryPieChart() {
479
+ var container = document.getElementById('chart-category-pie');
480
+ if (!container) return;
481
+ if (_customState.chartInstances.categoryPie) _customState.chartInstances.categoryPie.dispose();
482
+ var chart = echarts.init(container, null, { renderer: 'canvas' });
483
+ _customState.chartInstances.categoryPie = chart;
484
+
485
+ var sentimentData = _customState.sentimentData;
486
+ var categoryCount = {};
487
+ sentimentData.forEach(function(item) {
488
+ categoryCount[item.category] = (categoryCount[item.category] || 0) + 1;
489
+ });
490
+
491
+ var categoryColors = ['#00d4ff', '#7c3aed', '#2ed573', '#ffa502', '#ff4757', '#ff6b81'];
492
+ var pieData = Object.keys(categoryCount).map(function(cat, idx) {
493
+ return { name: cat, value: categoryCount[cat], itemStyle: { color: categoryColors[idx % categoryColors.length] } };
494
+ });
495
+
496
+ chart.setOption({
497
+ backgroundColor: 'transparent',
498
+ tooltip: {
499
+ trigger: 'item',
500
+ backgroundColor: 'rgba(15, 23, 56, 0.95)',
501
+ borderColor: 'rgba(0, 212, 255, 0.3)',
502
+ textStyle: { color: '#e8f0fe', fontSize: 13 },
503
+ formatter: '{b}: {c}条 ({d}%)',
504
+ },
505
+ series: [{
506
+ type: 'pie',
507
+ radius: ['0%', '70%'],
508
+ center: ['50%', '55%'],
509
+ roseType: 'area',
510
+ itemStyle: {
511
+ borderRadius: 6,
512
+ borderColor: '#0a0e27',
513
+ borderWidth: 2,
514
+ },
515
+ label: {
516
+ show: true,
517
+ color: '#e8f0fe',
518
+ fontSize: 12,
519
+ formatter: '{b}: {c}',
520
+ },
521
+ emphasis: {
522
+ label: { show: true, fontSize: 14, fontWeight: 'bold' },
523
+ itemStyle: { shadowBlur: 20, shadowColor: 'rgba(0,0,0,0.5)' },
524
+ },
525
+ data: pieData,
526
+ animationType: 'scale',
527
+ animationEasing: 'elasticOut',
528
+ animationDelay: function(idx) { return idx * 150; },
529
+ }],
530
+ });
531
+
532
+ window.addEventListener('resize', function() { chart.resize(); });
533
+ }
534
+
535
+ // ===== 工具函数 =====
536
+ function formatNumber(num) {
537
+ if (num >= 10000) return (num / 10000).toFixed(1) + '万';
538
+ if (num >= 1000) return (num / 1000).toFixed(1) + 'k';
539
+ return String(num);
540
+ }
541
+
542
+ function formatDate(timestamp) {
543
+ if (!timestamp) return '';
544
+ var d = new Date(Number(timestamp));
545
+ var month = d.getMonth() + 1;
546
+ var day = d.getDate();
547
+ return d.getFullYear() + '-' + (month < 10 ? '0' + month : '' + month) + '-' + (day < 10 ? '0' + day : '' + day);
548
+ }
549
+
550
+ function getImpactColor(impact) {
551
+ if (impact === '重大') return '#ff4757';
552
+ if (impact === '较大') return '#ffa502';
553
+ if (impact === '一般') return '#2ed573';
554
+ return '#747d8c';
555
+ }
556
+
557
+ function getCategoryIcon(category) {
558
+ if (category === '技术突破') return '🔬';
559
+ if (category === '政策法规') return '📋';
560
+ if (category === '市场动态') return '📈';
561
+ if (category === '供应链') return '🔗';
562
+ if (category === '竞争格局') return '⚔️';
563
+ return '📰';
564
+ }
565
+
566
+ function getRatingColor(rating) {
567
+ if (rating === '领导者') return '#00d4ff';
568
+ if (rating === '挑战者') return '#ffa502';
569
+ if (rating === '追随者') return '#747d8c';
570
+ return '#a4b0be';
571
+ }
572
+
573
+ // ===== 样式常量 =====
574
+ var COLORS = {
575
+ bg: '#0a0e27',
576
+ cardBg: 'rgba(15, 23, 56, 0.85)',
577
+ cardBorder: 'rgba(0, 212, 255, 0.12)',
578
+ cardHoverBorder: 'rgba(0, 212, 255, 0.35)',
579
+ accent: '#00d4ff',
580
+ accentGlow: 'rgba(0, 212, 255, 0.15)',
581
+ text: '#e8f0fe',
582
+ textSecondary: 'rgba(200, 220, 255, 0.6)',
583
+ gradient1: '#00d4ff',
584
+ gradient2: '#7c3aed',
585
+ success: '#2ed573',
586
+ warning: '#ffa502',
587
+ danger: '#ff4757',
588
+ };
589
+
590
+ // ===== 渲染入口 =====
591
+ export function renderJsx() {
592
+ var timestamp = this.state.timestamp;
593
+ var loading = _customState.loading;
594
+ var activeTab = _customState.activeTab;
595
+ var self = this;
596
+
597
+ if (loading) {
598
+ return (
599
+ <div style={{ background: COLORS.bg, minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: "'PingFang SC', 'Helvetica Neue', sans-serif" }}>
600
+ <div style={{ textAlign: 'center' }}>
601
+ <div style={{ fontSize: '48px', marginBottom: '20px', animation: 'pulse 2s infinite' }}>🔬</div>
602
+ <div style={{ color: COLORS.accent, fontSize: '18px', fontWeight: '600' }}>正在加载行业洞察数据...</div>
603
+ </div>
604
+ </div>
605
+ );
606
+ }
607
+
608
+ return (
609
+ <div style={{ background: COLORS.bg, minHeight: '100vh', fontFamily: "'PingFang SC', 'Helvetica Neue', sans-serif", color: COLORS.text, padding: '0' }}>
610
+ <div style={{ display: 'none' }}>{timestamp}</div>
611
+
612
+ {self.renderHeader()}
613
+ {self.renderKPICards()}
614
+ {self.renderTabBar()}
615
+
616
+ <div style={{ maxWidth: '1400px', margin: '0 auto', padding: '0 24px 40px' }}>
617
+ {activeTab === 'overview' ? self.renderOverview() : null}
618
+ {activeTab === 'company' ? self.renderCompanyView() : null}
619
+ {activeTab === 'sentiment' ? self.renderSentimentView() : null}
620
+ </div>
621
+ </div>
622
+ );
623
+ }
624
+
625
+ // ===== 头部 =====
626
+ export function renderHeader() {
627
+ return (
628
+ <div style={{ background: 'linear-gradient(135deg, rgba(0,212,255,0.08) 0%, rgba(124,58,237,0.08) 100%)', borderBottom: '1px solid ' + COLORS.cardBorder, padding: '32px 24px 24px', marginBottom: '0' }}>
629
+ <div style={{ maxWidth: '1400px', margin: '0 auto' }}>
630
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap' }}>
631
+ <div>
632
+ <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '8px' }}>
633
+ <span style={{ fontSize: '32px' }}>🔬</span>
634
+ <h1 style={{ margin: 0, fontSize: '28px', fontWeight: '700', background: 'linear-gradient(135deg, ' + COLORS.gradient1 + ', ' + COLORS.gradient2 + ')', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>半导体行业智能洞察</h1>
635
+ </div>
636
+ <p style={{ margin: 0, color: COLORS.textSecondary, fontSize: '14px' }}>Semiconductor Industry Intelligence Dashboard · 2026</p>
637
+ </div>
638
+ <div style={{ display: 'flex', alignItems: 'center', gap: '16px', marginTop: '8px' }}>
639
+ <div style={{ padding: '8px 16px', background: 'rgba(46,213,115,0.15)', border: '1px solid rgba(46,213,115,0.3)', borderRadius: '20px', fontSize: '13px', color: COLORS.success }}>
640
+ ● 数据实时同步
641
+ </div>
642
+ <div style={{ padding: '8px 16px', background: COLORS.accentGlow, border: '1px solid rgba(0,212,255,0.3)', borderRadius: '20px', fontSize: '13px', color: COLORS.accent, cursor: 'pointer' }} onClick={(e) => { this.loadAllData(); }}>
643
+ 🔄 刷新数据
644
+ </div>
645
+ </div>
646
+ </div>
647
+ </div>
648
+ </div>
649
+ );
650
+ }
651
+
652
+ // ===== KPI 卡片 =====
653
+ export function renderKPICards() {
654
+ var marketData = _customState.marketData;
655
+ var companyData = _customState.companyData;
656
+ var sentimentData = _customState.sentimentData;
657
+ var self = this;
658
+
659
+ var latestMarket = marketData.length > 0 ? marketData[marketData.length - 1] : {};
660
+ var prevMarket = marketData.length > 1 ? marketData[marketData.length - 2] : {};
661
+ var totalMarketCap = _.sumBy(companyData, 'marketCap');
662
+ var criticalNews = sentimentData.filter(function(item) { return item.impact === '重大'; }).length;
663
+
664
+ var kpis = [
665
+ { icon: '💰', label: '全球半导体市场规模', value: (latestMarket.marketSize || 0) + '亿$', sub: latestMarket.year || '', color: COLORS.accent },
666
+ { icon: '🤖', label: 'AI芯片市场规模', value: (latestMarket.aiSize || 0) + '亿$', sub: '占比 ' + (latestMarket.aiRatio || 'N/A'), color: '#7c3aed' },
667
+ { icon: '📈', label: '同比增长率', value: latestMarket.growth || 'N/A', sub: '较上年 ' + (prevMarket.growth || ''), color: COLORS.success },
668
+ { icon: '🏢', label: '跟踪企业总市值', value: formatNumber(totalMarketCap) + '亿$', sub: companyData.length + ' 家核心企业', color: COLORS.warning },
669
+ { icon: '🔥', label: '重大舆情事件', value: String(criticalNews), sub: '共 ' + sentimentData.length + ' 条舆情', color: COLORS.danger },
670
+ ];
671
+
672
+ return (
673
+ <div style={{ maxWidth: '1400px', margin: '0 auto', padding: '24px 24px 0' }}>
674
+ <div style={{ display: 'flex', gap: '16px', overflowX: 'auto', paddingBottom: '8px' }}>
675
+ {kpis.map(function(kpi, index) {
676
+ return (
677
+ <div key={index} style={{ flex: '1 0 200px', background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '20px', position: 'relative', overflow: 'hidden', minWidth: '200px' }}>
678
+ <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '3px', background: 'linear-gradient(90deg, ' + kpi.color + ', transparent)' }}></div>
679
+ <div style={{ fontSize: '24px', marginBottom: '8px' }}>{kpi.icon}</div>
680
+ <div style={{ fontSize: '12px', color: COLORS.textSecondary, marginBottom: '8px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>{kpi.label}</div>
681
+ <div style={{ fontSize: '24px', fontWeight: '700', color: kpi.color, marginBottom: '4px' }}>{kpi.value}</div>
682
+ <div style={{ fontSize: '12px', color: COLORS.textSecondary }}>{kpi.sub}</div>
683
+ </div>
684
+ );
685
+ })}
686
+ </div>
687
+ </div>
688
+ );
689
+ }
690
+
691
+ // ===== Tab 栏 =====
692
+ export function renderTabBar() {
693
+ var activeTab = _customState.activeTab;
694
+ var self = this;
695
+
696
+ var tabs = [
697
+ { key: 'overview', label: '📊 市场总览', desc: '市场规模与趋势' },
698
+ { key: 'company', label: '🏢 竞争格局', desc: '核心企业分析' },
699
+ { key: 'sentiment', label: '📰 行业舆情', desc: '最新动态追踪' },
700
+ ];
701
+
702
+ return (
703
+ <div style={{ maxWidth: '1400px', margin: '0 auto', padding: '24px 24px 0' }}>
704
+ <div style={{ display: 'flex', gap: '12px', borderBottom: '1px solid ' + COLORS.cardBorder, paddingBottom: '0' }}>
705
+ {tabs.map(function(tab) {
706
+ var isActive = activeTab === tab.key;
707
+ return (
708
+ <div
709
+ key={tab.key}
710
+ style={{
711
+ padding: '12px 24px',
712
+ cursor: 'pointer',
713
+ borderBottom: isActive ? '2px solid ' + COLORS.accent : '2px solid transparent',
714
+ color: isActive ? COLORS.accent : COLORS.textSecondary,
715
+ fontSize: '15px',
716
+ fontWeight: isActive ? '600' : '400',
717
+ transition: 'all 0.2s',
718
+ }}
719
+ onClick={(e) => { this.setCustomState({ activeTab: tab.key }); setTimeout(() => { this.initCurrentTabChart(); }, 150); }}
720
+ >
721
+ {tab.label}
722
+ </div>
723
+ );
724
+ })}
725
+ </div>
726
+ </div>
727
+ );
728
+ }
729
+
730
+ // ===== 市场总览 =====
731
+ export function renderOverview() {
732
+ var marketData = _customState.marketData;
733
+ var self = this;
734
+
735
+ if (marketData.length === 0) {
736
+ return <div style={{ textAlign: 'center', padding: '60px', color: COLORS.textSecondary }}>暂无市场数据</div>;
737
+ }
738
+
739
+ return (
740
+ <div style={{ paddingTop: '24px' }}>
741
+ {/* ECharts 市场规模趋势图 */}
742
+ <div style={{ background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '28px', marginBottom: '24px' }}>
743
+ <h3 style={{ margin: '0 0 8px', fontSize: '18px', fontWeight: '600', color: COLORS.text }}>
744
+ 📊 全球半导体市场规模趋势(亿美元)
745
+ </h3>
746
+ <div id="chart-market-bar" style={{ width: '100%', height: '360px' }}></div>
747
+ </div>
748
+
749
+ {/* ECharts AI芯片占比 & 增长率趋势 */}
750
+ <div style={{ background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '28px', marginBottom: '24px' }}>
751
+ <h3 style={{ margin: '0 0 8px', fontSize: '18px', fontWeight: '600', color: COLORS.text }}>
752
+ 🤖 AI芯片占比 & 市场增长率趋势
753
+ </h3>
754
+ <div id="chart-ai-trend" style={{ width: '100%', height: '320px' }}></div>
755
+ </div>
756
+
757
+ {/* 年度详情卡片 */}
758
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', gap: '16px' }}>
759
+ {marketData.map(function(item, index) {
760
+ var isEstimate = item.year.indexOf('E') >= 0;
761
+ return (
762
+ <div key={index} style={{ background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '24px', position: 'relative', overflow: 'hidden' }}>
763
+ <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '3px', background: isEstimate ? 'linear-gradient(90deg, ' + COLORS.warning + ', transparent)' : 'linear-gradient(90deg, ' + COLORS.accent + ', transparent)' }}></div>
764
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
765
+ <span style={{ fontSize: '20px', fontWeight: '700', color: isEstimate ? COLORS.warning : COLORS.accent }}>{item.year}</span>
766
+ {isEstimate ? <span style={{ fontSize: '11px', padding: '2px 8px', background: 'rgba(255,165,2,0.15)', color: COLORS.warning, borderRadius: '10px' }}>预测</span> : null}
767
+ </div>
768
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px', marginBottom: '16px' }}>
769
+ <div>
770
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary }}>市场规模</div>
771
+ <div style={{ fontSize: '18px', fontWeight: '700', color: COLORS.text }}>{item.marketSize.toLocaleString()}亿$</div>
772
+ </div>
773
+ <div>
774
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary }}>同比增长</div>
775
+ <div style={{ fontSize: '18px', fontWeight: '700', color: COLORS.success }}>{item.growth}</div>
776
+ </div>
777
+ <div>
778
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary }}>AI芯片规模</div>
779
+ <div style={{ fontSize: '18px', fontWeight: '700', color: '#7c3aed' }}>{item.aiSize}亿$</div>
780
+ </div>
781
+ <div>
782
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary }}>AI芯片占比</div>
783
+ <div style={{ fontSize: '18px', fontWeight: '700', color: '#7c3aed' }}>{item.aiRatio}</div>
784
+ </div>
785
+ </div>
786
+ <div style={{ fontSize: '13px', color: COLORS.textSecondary, lineHeight: '1.6', borderTop: '1px solid ' + COLORS.cardBorder, paddingTop: '12px' }}>
787
+ {item.note}
788
+ </div>
789
+ </div>
790
+ );
791
+ })}
792
+ </div>
793
+ </div>
794
+ );
795
+ }
796
+
797
+ // ===== 竞争格局 =====
798
+ export function renderCompanyView() {
799
+ var companyData = _customState.companyData;
800
+ var expandedCard = _customState.expandedCard;
801
+ var self = this;
802
+
803
+ if (companyData.length === 0) {
804
+ return <div style={{ textAlign: 'center', padding: '60px', color: COLORS.textSecondary }}>暂无公司数据</div>;
805
+ }
806
+
807
+ var maxRevenue = Math.max.apply(null, companyData.map(function(d) { return d.revenue; }));
808
+
809
+ return (
810
+ <div style={{ paddingTop: '24px' }}>
811
+ {/* ECharts 企业对比图 */}
812
+ <div style={{ background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '28px', marginBottom: '24px' }}>
813
+ <h3 style={{ margin: '0 0 8px', fontSize: '18px', fontWeight: '600', color: COLORS.text }}>
814
+ 🏆 核心企业综合对比(市值 / 营收 / AI营收,亿美元)
815
+ </h3>
816
+ <div id="chart-company-bar" style={{ width: '100%', height: '380px' }}></div>
817
+ </div>
818
+
819
+ {/* 公司详情卡片 */}
820
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(420px, 1fr))', gap: '16px' }}>
821
+ {companyData.map(function(item, index) {
822
+ var isExpanded = expandedCard === index;
823
+ var ratingColor = getRatingColor(item.rating);
824
+ var revenueBarWidth = maxRevenue > 0 ? (item.revenue / maxRevenue * 100) : 0;
825
+ var aiRevenueBarWidth = maxRevenue > 0 ? (item.aiRevenue / maxRevenue * 100) : 0;
826
+
827
+ return (
828
+ <div
829
+ key={index}
830
+ style={{
831
+ background: COLORS.cardBg,
832
+ border: '1px solid ' + (isExpanded ? COLORS.cardHoverBorder : COLORS.cardBorder),
833
+ borderRadius: '16px',
834
+ padding: '24px',
835
+ cursor: 'pointer',
836
+ transition: 'all 0.3s',
837
+ position: 'relative',
838
+ overflow: 'hidden',
839
+ }}
840
+ onClick={(e) => { this.setCustomState({ expandedCard: isExpanded ? null : index }); }}
841
+ >
842
+ <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '3px', background: 'linear-gradient(90deg, ' + ratingColor + ', transparent)' }}></div>
843
+
844
+ {/* 公司头部 */}
845
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '16px' }}>
846
+ <div>
847
+ <div style={{ fontSize: '18px', fontWeight: '700', color: COLORS.text, marginBottom: '4px' }}>{item.name}</div>
848
+ <div style={{ fontSize: '12px', color: COLORS.textSecondary }}>{item.product}</div>
849
+ </div>
850
+ <div style={{ padding: '4px 12px', background: ratingColor + '20', border: '1px solid ' + ratingColor + '40', borderRadius: '12px', fontSize: '12px', color: ratingColor, fontWeight: '600' }}>
851
+ {item.rating}
852
+ </div>
853
+ </div>
854
+
855
+ {/* 核心指标 */}
856
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '12px', marginBottom: '16px' }}>
857
+ <div style={{ textAlign: 'center', padding: '12px 8px', background: 'rgba(0,212,255,0.05)', borderRadius: '10px' }}>
858
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary, marginBottom: '4px' }}>市值</div>
859
+ <div style={{ fontSize: '16px', fontWeight: '700', color: COLORS.accent }}>{formatNumber(item.marketCap)}</div>
860
+ </div>
861
+ <div style={{ textAlign: 'center', padding: '12px 8px', background: 'rgba(46,213,115,0.05)', borderRadius: '10px' }}>
862
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary, marginBottom: '4px' }}>年营收</div>
863
+ <div style={{ fontSize: '16px', fontWeight: '700', color: COLORS.success }}>{item.revenue}亿</div>
864
+ </div>
865
+ <div style={{ textAlign: 'center', padding: '12px 8px', background: 'rgba(124,58,237,0.05)', borderRadius: '10px' }}>
866
+ <div style={{ fontSize: '11px', color: COLORS.textSecondary, marginBottom: '4px' }}>AI营收</div>
867
+ <div style={{ fontSize: '16px', fontWeight: '700', color: '#7c3aed' }}>{item.aiRevenue}亿</div>
868
+ </div>
869
+ </div>
870
+
871
+ {/* 营收对比条 */}
872
+ <div style={{ marginBottom: '12px' }}>
873
+ <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px' }}>
874
+ <span style={{ fontSize: '11px', color: COLORS.textSecondary }}>营收结构</span>
875
+ <span style={{ fontSize: '11px', color: COLORS.textSecondary }}>市场份额: {item.share}</span>
876
+ </div>
877
+ <div style={{ height: '8px', background: 'rgba(0,212,255,0.06)', borderRadius: '4px', overflow: 'hidden', position: 'relative' }}>
878
+ <div style={{ position: 'absolute', height: '100%', width: revenueBarWidth + '%', background: 'rgba(0,212,255,0.3)', borderRadius: '4px' }}></div>
879
+ <div style={{ position: 'absolute', height: '100%', width: aiRevenueBarWidth + '%', background: '#7c3aed', borderRadius: '4px' }}></div>
880
+ </div>
881
+ </div>
882
+
883
+ {/* 展开详情 */}
884
+ {isExpanded ? (
885
+ <div style={{ borderTop: '1px solid ' + COLORS.cardBorder, paddingTop: '16px', marginTop: '8px' }}>
886
+ <div style={{ fontSize: '13px', fontWeight: '600', color: COLORS.accent, marginBottom: '8px' }}>🔬 技术路线与战略分析</div>
887
+ <div style={{ fontSize: '13px', color: COLORS.textSecondary, lineHeight: '1.8' }}>{item.techRoute}</div>
888
+ </div>
889
+ ) : (
890
+ <div style={{ textAlign: 'center', fontSize: '12px', color: COLORS.textSecondary, marginTop: '8px' }}>
891
+ 点击展开详情 ▼
892
+ </div>
893
+ )}
894
+ </div>
895
+ );
896
+ })}
897
+ </div>
898
+ </div>
899
+ );
900
+ }
901
+
902
+ // ===== 行业舆情 =====
903
+ export function renderSentimentView() {
904
+ var sentimentData = _customState.sentimentData;
905
+ var self = this;
906
+
907
+ if (sentimentData.length === 0) {
908
+ return <div style={{ textAlign: 'center', padding: '60px', color: COLORS.textSecondary }}>暂无舆情数据</div>;
909
+ }
910
+
911
+ return (
912
+ <div style={{ paddingTop: '24px' }}>
913
+ {/* ECharts 舆情统计概览 */}
914
+ <div style={{ display: 'flex', gap: '16px', marginBottom: '24px', flexWrap: 'wrap' }}>
915
+ {/* 影响等级分布 - 环形图 */}
916
+ <div style={{ flex: '1 1 300px', background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '24px' }}>
917
+ <h4 style={{ margin: '0 0 8px', fontSize: '15px', fontWeight: '600', color: COLORS.text }}>⚡ 影响等级分布</h4>
918
+ <div id="chart-impact-pie" style={{ width: '100%', height: '280px' }}></div>
919
+ </div>
920
+
921
+ {/* 类别分布 - 南丁格尔玫瑰图 */}
922
+ <div style={{ flex: '1 1 300px', background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '24px' }}>
923
+ <h4 style={{ margin: '0 0 8px', fontSize: '15px', fontWeight: '600', color: COLORS.text }}>📂 舆情类别分布</h4>
924
+ <div id="chart-category-pie" style={{ width: '100%', height: '280px' }}></div>
925
+ </div>
926
+ </div>
927
+
928
+ {/* 舆情时间线 */}
929
+ <div style={{ background: COLORS.cardBg, border: '1px solid ' + COLORS.cardBorder, borderRadius: '16px', padding: '28px' }}>
930
+ <h3 style={{ margin: '0 0 24px', fontSize: '18px', fontWeight: '600', color: COLORS.text }}>
931
+ 📰 行业舆情动态
932
+ </h3>
933
+
934
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0' }}>
935
+ {sentimentData.map(function(item, index) {
936
+ var impactColor = getImpactColor(item.impact);
937
+ var isLast = index === sentimentData.length - 1;
938
+
939
+ return (
940
+ <div key={index} style={{ display: 'flex', gap: '20px', position: 'relative' }}>
941
+ {/* 时间线 */}
942
+ <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0, width: '20px' }}>
943
+ <div style={{ width: '12px', height: '12px', borderRadius: '50%', background: impactColor, border: '2px solid ' + COLORS.bg, zIndex: 1, flexShrink: 0 }}></div>
944
+ {!isLast ? <div style={{ width: '2px', flex: 1, background: 'rgba(0,212,255,0.1)', minHeight: '20px' }}></div> : null}
945
+ </div>
946
+
947
+ {/* 内容 */}
948
+ <div style={{ flex: 1, paddingBottom: '24px' }}>
949
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '8px', flexWrap: 'wrap' }}>
950
+ <span style={{ fontSize: '12px', color: COLORS.textSecondary }}>{formatDate(item.date)}</span>
951
+ <span style={{ padding: '2px 8px', background: impactColor + '20', color: impactColor, fontSize: '11px', borderRadius: '10px', fontWeight: '600' }}>{item.impact}</span>
952
+ <span style={{ padding: '2px 8px', background: 'rgba(0,212,255,0.1)', color: COLORS.accent, fontSize: '11px', borderRadius: '10px' }}>{getCategoryIcon(item.category)} {item.category}</span>
953
+ </div>
954
+
955
+ <div style={{ fontSize: '16px', fontWeight: '600', color: COLORS.text, marginBottom: '8px', lineHeight: '1.5' }}>
956
+ {item.title}
957
+ </div>
958
+
959
+ <div style={{ fontSize: '13px', color: COLORS.textSecondary, lineHeight: '1.7', marginBottom: '8px' }}>
960
+ {item.summary}
961
+ </div>
962
+
963
+ {item.analysis ? (
964
+ <div style={{ padding: '12px 16px', background: 'rgba(124,58,237,0.06)', borderLeft: '3px solid #7c3aed', borderRadius: '0 8px 8px 0', marginBottom: '8px' }}>
965
+ <div style={{ fontSize: '12px', fontWeight: '600', color: '#7c3aed', marginBottom: '4px' }}>💡 影响分析</div>
966
+ <div style={{ fontSize: '13px', color: COLORS.textSecondary, lineHeight: '1.6' }}>{item.analysis}</div>
967
+ </div>
968
+ ) : null}
969
+
970
+ {item.source ? (
971
+ <div style={{ fontSize: '12px', color: COLORS.textSecondary }}>
972
+ 📎 来源: {item.source}
973
+ </div>
974
+ ) : null}
975
+ </div>
976
+ </div>
977
+ );
978
+ })}
979
+ </div>
980
+ </div>
981
+ </div>
982
+ );
983
+ }