system-settings.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. // 扩展Window接口以包含echarts属性
  2. declare global {
  3. interface Window {
  4. echarts: any;
  5. }
  6. }
  7. import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
  8. import { CommonModule } from '@angular/common';
  9. import { RouterModule } from '@angular/router';
  10. import { FormsModule } from '@angular/forms';
  11. import { SettingDialogComponent } from './setting-dialog/setting-dialog'; // @ts-ignore: Component used in code but not in template
  12. import { MatDialog } from '@angular/material/dialog';
  13. import { MatSelectModule } from '@angular/material/select';
  14. import { MatFormFieldModule } from '@angular/material/form-field';
  15. import { MatSlideToggleModule } from '@angular/material/slide-toggle';
  16. // 定义工作流阶段接口
  17. interface WorkflowStage {
  18. id: string;
  19. name: string;
  20. order: number;
  21. description: string;
  22. isActive: boolean;
  23. }
  24. // 定义SOP模板接口
  25. interface SOPTemplate {
  26. id: string;
  27. name: string;
  28. description: string;
  29. steps: string[];
  30. isActive: boolean;
  31. }
  32. // 定义报价规则接口
  33. interface PricingRule {
  34. id: string;
  35. name: string;
  36. description: string;
  37. condition: string;
  38. price: number;
  39. isActive: boolean;
  40. }
  41. // 定义绩效规则接口
  42. interface PerformanceRule {
  43. id: string;
  44. name: string;
  45. description: string;
  46. metric: string;
  47. threshold: number;
  48. reward: string;
  49. isActive: boolean;
  50. }
  51. @Component({
  52. selector: 'app-system-settings',
  53. standalone: true,
  54. imports: [
  55. CommonModule,
  56. RouterModule,
  57. FormsModule,
  58. MatFormFieldModule,
  59. MatSelectModule,
  60. MatSlideToggleModule
  61. ],
  62. templateUrl: './system-settings.html'
  63. })
  64. export class SystemSettings implements OnInit {
  65. // 当前激活的标签页
  66. activeTab: string = 'workflow';
  67. // 搜索关键词
  68. workflowSearchTerm: string = '';
  69. sopSearchTerm: string = '';
  70. pricingSearchTerm: string = '';
  71. performanceSearchTerm: string = '';
  72. // 数据列表
  73. workflowStages: WorkflowStage[] = [];
  74. sopTemplates: SOPTemplate[] = [];
  75. pricingRules: PricingRule[] = [];
  76. performanceRules: PerformanceRule[] = [];
  77. // 过滤后的数据列表
  78. filteredWorkflowStages: WorkflowStage[] = [];
  79. filteredSOPTemplates: SOPTemplate[] = [];
  80. filteredPricingRules: PricingRule[] = [];
  81. filteredPerformanceRules: PerformanceRule[] = [];
  82. // 常用指标
  83. performanceMetrics = ['项目完成率', '客户满意度', '按时交付率', '产值'];
  84. // 图表实例引用
  85. @ViewChild('dataUsageChart') private dataUsageChart!: ElementRef;
  86. @ViewChild('backupHistoryChart') private backupHistoryChart!: ElementRef;
  87. @ViewChild('systemPerformanceChart') private systemPerformanceChart!: ElementRef;
  88. // 数据统计信息
  89. systemStats = {
  90. totalDataSize: 128,
  91. usedDataSize: 76,
  92. backupCount: 12,
  93. activeUsers: 32,
  94. systemUptime: '99.9%',
  95. lastBackup: '2025-09-15 02:00:00'
  96. };
  97. // 系统配置选项
  98. systemOptions = {
  99. enableAuditLog: true,
  100. enableNotification: true,
  101. autoBackupEnabled: true,
  102. backupFrequency: 'daily',
  103. dataRetentionDays: 365,
  104. enableDataExport: true
  105. };
  106. // 备份历史数据
  107. backupHistory = [
  108. { date: '2025-09-15', size: 6.2, status: 'success' },
  109. { date: '2025-09-14', size: 6.1, status: 'success' },
  110. { date: '2025-09-13', size: 6.0, status: 'success' },
  111. { date: '2025-09-12', size: 5.9, status: 'success' },
  112. { date: '2025-09-11', size: 5.8, status: 'success' },
  113. { date: '2025-09-10', size: 5.7, status: 'warning' },
  114. { date: '2025-09-09', size: 5.6, status: 'success' },
  115. { date: '2025-09-08', size: 5.5, status: 'error' },
  116. { date: '2025-09-07', size: 5.4, status: 'success' },
  117. { date: '2025-09-06', size: 5.3, status: 'success' },
  118. { date: '2025-09-05', size: 5.2, status: 'success' },
  119. { date: '2025-09-04', size: 5.1, status: 'success' }
  120. ];
  121. // 系统性能数据
  122. systemPerformance = [
  123. { time: '00:00', cpuUsage: 15, memoryUsage: 30, diskIO: 10 },
  124. { time: '04:00', cpuUsage: 10, memoryUsage: 25, diskIO: 5 },
  125. { time: '08:00', cpuUsage: 25, memoryUsage: 40, diskIO: 25 },
  126. { time: '12:00', cpuUsage: 40, memoryUsage: 55, diskIO: 45 },
  127. { time: '16:00', cpuUsage: 35, memoryUsage: 50, diskIO: 40 },
  128. { time: '20:00', cpuUsage: 20, memoryUsage: 35, diskIO: 20 }
  129. ];
  130. // 数据类型分布
  131. dataDistribution = [
  132. { name: '项目数据', value: 35 },
  133. { name: '客户数据', value: 25 },
  134. { name: '日志数据', value: 20 },
  135. { name: '配置数据', value: 10 },
  136. { name: '其他数据', value: 10 }
  137. ];
  138. constructor(private dialog: MatDialog) {}
  139. ngOnInit(): void {
  140. // 加载各类数据
  141. this.loadWorkflowStages();
  142. this.loadSOPTemplates();
  143. this.loadPricingRules();
  144. this.loadPerformanceRules();
  145. this.loadSystemOptions();
  146. // 初始化图表(延迟初始化,确保DOM已经加载)
  147. setTimeout(() => {
  148. this.initDataUsageChart();
  149. this.initBackupHistoryChart();
  150. this.initSystemPerformanceChart();
  151. }, 100);
  152. }
  153. // 切换标签页
  154. switchTab(tab: string): void {
  155. this.activeTab = tab;
  156. }
  157. // 加载工作流阶段数据
  158. loadWorkflowStages(): void {
  159. this.workflowStages = [
  160. {
  161. id: '1',
  162. name: '需求沟通',
  163. order: 1,
  164. description: '与客户沟通需求,了解项目背景和期望',
  165. isActive: true
  166. },
  167. {
  168. id: '2',
  169. name: '方案设计',
  170. order: 2,
  171. description: '根据需求设计解决方案和技术架构',
  172. isActive: true
  173. },
  174. {
  175. id: '3',
  176. name: '开发实现',
  177. order: 3,
  178. description: '按照方案进行开发和实现',
  179. isActive: true
  180. },
  181. {
  182. id: '4',
  183. name: '测试验证',
  184. order: 4,
  185. description: '对开发结果进行测试和验证',
  186. isActive: true
  187. },
  188. {
  189. id: '5',
  190. name: '部署上线',
  191. order: 5,
  192. description: '将项目部署到生产环境',
  193. isActive: true
  194. },
  195. {
  196. id: '6',
  197. name: '运维维护',
  198. order: 6,
  199. description: '项目上线后的运行维护和优化',
  200. isActive: true
  201. }
  202. ];
  203. this.onWorkflowSearch();
  204. }
  205. // 加载SOP模板数据
  206. loadSOPTemplates(): void {
  207. this.sopTemplates = [
  208. {
  209. id: '1',
  210. name: '新客户接入流程',
  211. description: '规范新客户从接触到签约的全流程',
  212. steps: [
  213. '初步接触与需求了解',
  214. '提供解决方案与报价',
  215. '商务谈判',
  216. '签订合同',
  217. '客户信息录入系统',
  218. '启动项目'
  219. ],
  220. isActive: true
  221. },
  222. {
  223. id: '2',
  224. name: '项目开发流程',
  225. description: '标准项目开发的流程规范',
  226. steps: [
  227. '需求分析与文档编写',
  228. '系统设计',
  229. '编码实现',
  230. '单元测试',
  231. '集成测试',
  232. '系统测试',
  233. '用户验收测试',
  234. '上线部署'
  235. ],
  236. isActive: true
  237. },
  238. {
  239. id: '3',
  240. name: '问题处理流程',
  241. description: '处理客户反馈问题的标准流程',
  242. steps: [
  243. '问题记录与分类',
  244. '问题评估与优先级确定',
  245. '问题分析与解决',
  246. '验证解决方案',
  247. '更新文档',
  248. '反馈给客户'
  249. ],
  250. isActive: true
  251. }
  252. ];
  253. this.onSOPSearch();
  254. }
  255. // 加载报价规则数据
  256. loadPricingRules(): void {
  257. this.pricingRules = [
  258. {
  259. id: '1',
  260. name: '基础开发服务',
  261. description: '标准软件开发服务报价',
  262. condition: '基础功能开发',
  263. price: 12000,
  264. isActive: true
  265. },
  266. {
  267. id: '2',
  268. name: '高级开发服务',
  269. description: '包含复杂功能的开发服务报价',
  270. condition: '高级功能开发',
  271. price: 25000,
  272. isActive: true
  273. },
  274. {
  275. id: '3',
  276. name: '维护服务',
  277. description: '系统上线后的维护服务报价',
  278. condition: '系统维护',
  279. price: 5000,
  280. isActive: true
  281. }
  282. ];
  283. this.onPricingSearch();
  284. }
  285. // 加载绩效规则数据
  286. loadPerformanceRules(): void {
  287. this.performanceRules = [
  288. {
  289. id: '1',
  290. name: '项目按时完成率',
  291. description: '评估项目是否按时完成',
  292. metric: '按时交付率',
  293. threshold: 90,
  294. reward: '绩效加分10分',
  295. isActive: true
  296. },
  297. {
  298. id: '2',
  299. name: '客户满意度',
  300. description: '评估客户对服务的满意程度',
  301. metric: '客户满意度',
  302. threshold: 95,
  303. reward: '绩效加分15分',
  304. isActive: true
  305. },
  306. {
  307. id: '3',
  308. name: '项目完成质量',
  309. description: '评估项目交付质量',
  310. metric: '项目完成率',
  311. threshold: 85,
  312. reward: '绩效加分12分',
  313. isActive: true
  314. }
  315. ];
  316. this.onPerformanceSearch();
  317. }
  318. // 加载系统配置
  319. loadSystemOptions(): void {
  320. // 这里可以添加从后端加载配置的逻辑
  321. // 目前使用的是模拟数据
  322. }
  323. // 打开工作流阶段对话框
  324. openWorkflowDialog(stage?: WorkflowStage): void {
  325. // 打开对话框的逻辑
  326. console.log('打开工作流阶段对话框', stage);
  327. }
  328. // 打开SOP模板对话框
  329. openSOPDialog(template?: SOPTemplate): void {
  330. // 打开对话框的逻辑
  331. console.log('打开SOP模板对话框', template);
  332. }
  333. // 打开报价规则对话框
  334. openPricingDialog(rule?: PricingRule): void {
  335. // 打开对话框的逻辑
  336. console.log('打开报价规则对话框', rule);
  337. }
  338. // 打开绩效规则对话框
  339. openPerformanceDialog(rule?: PerformanceRule): void {
  340. // 打开对话框的逻辑
  341. console.log('打开绩效规则对话框', rule);
  342. }
  343. // 保存设置项
  344. saveSetting(type: string, updatedItem: any): void {
  345. switch (type) {
  346. case 'workflow':
  347. if (updatedItem.id) {
  348. // 更新现有阶段
  349. this.workflowStages = this.workflowStages.map(stage =>
  350. stage.id === updatedItem.id ? updatedItem : stage
  351. );
  352. } else {
  353. // 添加新阶段
  354. updatedItem.id = (this.workflowStages.length + 1).toString();
  355. this.workflowStages.push(updatedItem);
  356. }
  357. this.onWorkflowSearch();
  358. break;
  359. case 'sop':
  360. if (updatedItem.id) {
  361. // 更新现有模板
  362. this.sopTemplates = this.sopTemplates.map(template =>
  363. template.id === updatedItem.id ? updatedItem : template
  364. );
  365. } else {
  366. // 添加新模板
  367. updatedItem.id = (this.sopTemplates.length + 1).toString();
  368. this.sopTemplates.push(updatedItem);
  369. }
  370. this.onSOPSearch();
  371. break;
  372. case 'pricing':
  373. if (updatedItem.id) {
  374. // 更新现有规则
  375. this.pricingRules = this.pricingRules.map(rule =>
  376. rule.id === updatedItem.id ? updatedItem : rule
  377. );
  378. } else {
  379. // 添加新规则
  380. updatedItem.id = (this.pricingRules.length + 1).toString();
  381. this.pricingRules.push(updatedItem);
  382. }
  383. this.onPricingSearch();
  384. break;
  385. case 'performance':
  386. if (updatedItem.id) {
  387. // 更新现有规则
  388. this.performanceRules = this.performanceRules.map(rule =>
  389. rule.id === updatedItem.id ? updatedItem : rule
  390. );
  391. } else {
  392. // 添加新规则
  393. updatedItem.id = (this.performanceRules.length + 1).toString();
  394. this.performanceRules.push(updatedItem);
  395. }
  396. this.onPerformanceSearch();
  397. break;
  398. }
  399. }
  400. // 删除设置项
  401. deleteSetting(type: string, id: string): void {
  402. if (confirm('确定要删除此项设置吗?')) {
  403. switch (type) {
  404. case 'workflow':
  405. this.workflowStages = this.workflowStages.filter(stage => stage.id !== id);
  406. this.onWorkflowSearch();
  407. break;
  408. case 'sop':
  409. this.sopTemplates = this.sopTemplates.filter(template => template.id !== id);
  410. this.onSOPSearch();
  411. break;
  412. case 'pricing':
  413. this.pricingRules = this.pricingRules.filter(rule => rule.id !== id);
  414. this.onPricingSearch();
  415. break;
  416. case 'performance':
  417. this.performanceRules = this.performanceRules.filter(rule => rule.id !== id);
  418. this.onPerformanceSearch();
  419. break;
  420. }
  421. }
  422. }
  423. // 更新设置项的激活状态
  424. toggleActive(type: string, id: string, isActive: boolean): void {
  425. switch (type) {
  426. case 'workflow':
  427. this.workflowStages = this.workflowStages.map(stage =>
  428. stage.id === id ? { ...stage, isActive } : stage
  429. );
  430. this.onWorkflowSearch();
  431. break;
  432. case 'sop':
  433. this.sopTemplates = this.sopTemplates.map(template =>
  434. template.id === id ? { ...template, isActive } : template
  435. );
  436. this.onSOPSearch();
  437. break;
  438. case 'pricing':
  439. this.pricingRules = this.pricingRules.map(rule =>
  440. rule.id === id ? { ...rule, isActive } : rule
  441. );
  442. this.onPricingSearch();
  443. break;
  444. case 'performance':
  445. this.performanceRules = this.performanceRules.map(rule =>
  446. rule.id === id ? { ...rule, isActive } : rule
  447. );
  448. this.onPerformanceSearch();
  449. break;
  450. }
  451. }
  452. // 搜索工作流阶段
  453. onWorkflowSearch(): void {
  454. if (!this.workflowSearchTerm.trim()) {
  455. this.filteredWorkflowStages = this.workflowStages;
  456. } else {
  457. const searchTerm = this.workflowSearchTerm.toLowerCase();
  458. this.filteredWorkflowStages = this.workflowStages.filter(
  459. stage => stage.name.toLowerCase().includes(searchTerm) ||
  460. stage.description.toLowerCase().includes(searchTerm)
  461. );
  462. }
  463. }
  464. // 搜索SOP模板
  465. onSOPSearch(): void {
  466. if (!this.sopSearchTerm.trim()) {
  467. this.filteredSOPTemplates = this.sopTemplates;
  468. } else {
  469. const searchTerm = this.sopSearchTerm.toLowerCase();
  470. this.filteredSOPTemplates = this.sopTemplates.filter(
  471. template => template.name.toLowerCase().includes(searchTerm) ||
  472. template.description.toLowerCase().includes(searchTerm) ||
  473. template.steps.some(step => step.toLowerCase().includes(searchTerm))
  474. );
  475. }
  476. }
  477. // 搜索报价规则
  478. onPricingSearch(): void {
  479. if (!this.pricingSearchTerm.trim()) {
  480. this.filteredPricingRules = this.pricingRules;
  481. } else {
  482. const searchTerm = this.pricingSearchTerm.toLowerCase();
  483. this.filteredPricingRules = this.pricingRules.filter(
  484. rule => rule.name.toLowerCase().includes(searchTerm) ||
  485. rule.description.toLowerCase().includes(searchTerm) ||
  486. rule.condition.toLowerCase().includes(searchTerm)
  487. );
  488. }
  489. }
  490. // 搜索绩效规则
  491. onPerformanceSearch(): void {
  492. if (!this.performanceSearchTerm.trim()) {
  493. this.filteredPerformanceRules = this.performanceRules;
  494. } else {
  495. const searchTerm = this.performanceSearchTerm.toLowerCase();
  496. this.filteredPerformanceRules = this.performanceRules.filter(
  497. rule => rule.name.toLowerCase().includes(searchTerm) ||
  498. rule.description.toLowerCase().includes(searchTerm) ||
  499. rule.metric.toLowerCase().includes(searchTerm)
  500. );
  501. }
  502. }
  503. // 保存系统配置
  504. saveSystemOptions(): void {
  505. console.log('保存系统配置:', this.systemOptions);
  506. // 这里可以添加保存到后端的逻辑
  507. alert('系统配置保存成功!');
  508. }
  509. // 初始化数据使用情况图表
  510. initDataUsageChart(): void {
  511. if (window['echarts'] && this.dataUsageChart) {
  512. const chart = window['echarts'].init(this.dataUsageChart.nativeElement);
  513. const option = {
  514. title: {
  515. text: '数据存储使用情况',
  516. left: 'center',
  517. textStyle: {
  518. fontWeight: 'normal',
  519. fontSize: 16
  520. }
  521. },
  522. tooltip: {
  523. trigger: 'item',
  524. formatter: '{b}: {c}GB ({d}%)'
  525. },
  526. legend: {
  527. orient: 'vertical',
  528. left: 10,
  529. top: 'center'
  530. },
  531. series: [
  532. {
  533. name: '数据存储',
  534. type: 'pie',
  535. radius: ['40%', '70%'],
  536. avoidLabelOverlap: false,
  537. itemStyle: {
  538. borderRadius: 10,
  539. borderColor: '#fff',
  540. borderWidth: 2
  541. },
  542. label: {
  543. show: false,
  544. position: 'center'
  545. },
  546. emphasis: {
  547. label: {
  548. show: true,
  549. fontSize: 18,
  550. fontWeight: 'bold'
  551. }
  552. },
  553. labelLine: {
  554. show: false
  555. },
  556. data: [
  557. {
  558. value: this.systemStats.usedDataSize,
  559. name: '已使用',
  560. itemStyle: { color: '#165DFF' }
  561. },
  562. {
  563. value: this.systemStats.totalDataSize - this.systemStats.usedDataSize,
  564. name: '未使用',
  565. itemStyle: { color: '#E5E6EB' }
  566. }
  567. ]
  568. },
  569. {
  570. name: '数据类型分布',
  571. type: 'pie',
  572. radius: ['15%', '30%'],
  573. center: ['75%', '60%'],
  574. data: this.dataDistribution,
  575. itemStyle: {
  576. borderRadius: 5
  577. },
  578. label: {
  579. show: false
  580. }
  581. }
  582. ]
  583. };
  584. chart.setOption(option);
  585. // 响应式调整
  586. window.addEventListener('resize', () => {
  587. chart.resize();
  588. });
  589. }
  590. }
  591. // 初始化备份历史图表
  592. initBackupHistoryChart(): void {
  593. if (window['echarts'] && this.backupHistoryChart) {
  594. const chart = window['echarts'].init(this.backupHistoryChart.nativeElement);
  595. const dates = this.backupHistory.map(item => item.date);
  596. const sizes = this.backupHistory.map(item => item.size);
  597. const statusColors = this.backupHistory.map(item => {
  598. switch(item.status) {
  599. case 'success': return '#00B42A';
  600. case 'warning': return '#FFAA00';
  601. case 'error': return '#F53F3F';
  602. default: return '#86909C';
  603. }
  604. });
  605. const option = {
  606. title: {
  607. text: '备份历史记录',
  608. left: 'center',
  609. textStyle: {
  610. fontWeight: 'normal',
  611. fontSize: 16
  612. }
  613. },
  614. tooltip: {
  615. trigger: 'axis',
  616. axisPointer: {
  617. type: 'cross',
  618. label: {
  619. backgroundColor: '#6a7985'
  620. }
  621. },
  622. formatter: (params: any) => {
  623. const data = params[0];
  624. const statusItem = this.backupHistory[data.dataIndex];
  625. const statusText: Record<string, string> = {
  626. 'success': '成功',
  627. 'warning': '警告',
  628. 'error': '失败'
  629. };
  630. return `${data.name}<br/>备份大小: ${data.value}GB<br/>状态: ${statusText[statusItem.status]}`;
  631. }
  632. },
  633. grid: {
  634. left: '3%',
  635. right: '4%',
  636. bottom: '3%',
  637. containLabel: true
  638. },
  639. xAxis: {
  640. type: 'category',
  641. boundaryGap: false,
  642. data: dates,
  643. axisLabel: {
  644. rotate: 45
  645. }
  646. },
  647. yAxis: {
  648. type: 'value',
  649. name: '备份大小 (GB)',
  650. min: 0
  651. },
  652. series: [
  653. {
  654. name: '备份大小',
  655. type: 'line',
  656. smooth: true,
  657. data: sizes,
  658. lineStyle: {
  659. width: 3,
  660. color: '#165DFF'
  661. },
  662. areaStyle: {
  663. color: new window['echarts'].graphic.LinearGradient(0, 0, 0, 1, [
  664. {
  665. offset: 0,
  666. color: 'rgba(22, 93, 255, 0.3)'
  667. },
  668. {
  669. offset: 1,
  670. color: 'rgba(22, 93, 255, 0.05)'
  671. }
  672. ])
  673. },
  674. symbol: 'circle',
  675. symbolSize: 8,
  676. itemStyle: {
  677. color: function(params: any) {
  678. return statusColors[params.dataIndex];
  679. }
  680. }
  681. }
  682. ]
  683. };
  684. chart.setOption(option);
  685. // 响应式调整
  686. window.addEventListener('resize', () => {
  687. chart.resize();
  688. });
  689. }
  690. }
  691. // 初始化系统性能图表
  692. initSystemPerformanceChart(): void {
  693. if (window['echarts'] && this.systemPerformanceChart) {
  694. const chart = window['echarts'].init(this.systemPerformanceChart.nativeElement);
  695. const times = this.systemPerformance.map(item => item.time);
  696. const cpuUsage = this.systemPerformance.map(item => item.cpuUsage);
  697. const memoryUsage = this.systemPerformance.map(item => item.memoryUsage);
  698. const diskIO = this.systemPerformance.map(item => item.diskIO);
  699. const option = {
  700. title: {
  701. text: '系统性能监控',
  702. left: 'center',
  703. textStyle: {
  704. fontWeight: 'normal',
  705. fontSize: 16
  706. }
  707. },
  708. tooltip: {
  709. trigger: 'axis'
  710. },
  711. legend: {
  712. data: ['CPU使用率', '内存使用率', '磁盘IO'],
  713. bottom: 0
  714. },
  715. grid: {
  716. left: '3%',
  717. right: '4%',
  718. bottom: '15%',
  719. containLabel: true
  720. },
  721. xAxis: {
  722. type: 'category',
  723. boundaryGap: false,
  724. data: times
  725. },
  726. yAxis: {
  727. type: 'value',
  728. name: '使用率 (%)',
  729. min: 0,
  730. max: 100
  731. },
  732. series: [
  733. {
  734. name: 'CPU使用率',
  735. type: 'line',
  736. stack: 'Total',
  737. data: cpuUsage,
  738. lineStyle: {
  739. color: '#165DFF'
  740. },
  741. areaStyle: {
  742. color: new window['echarts'].graphic.LinearGradient(0, 0, 0, 1, [
  743. {
  744. offset: 0,
  745. color: 'rgba(22, 93, 255, 0.5)'
  746. },
  747. {
  748. offset: 1,
  749. color: 'rgba(22, 93, 255, 0.1)'
  750. }
  751. ])
  752. }
  753. },
  754. {
  755. name: '内存使用率',
  756. type: 'line',
  757. stack: 'Total',
  758. data: memoryUsage,
  759. lineStyle: {
  760. color: '#722ED1'
  761. },
  762. areaStyle: {
  763. color: new window['echarts'].graphic.LinearGradient(0, 0, 0, 1, [
  764. {
  765. offset: 0,
  766. color: 'rgba(114, 46, 209, 0.5)'
  767. },
  768. {
  769. offset: 1,
  770. color: 'rgba(114, 46, 209, 0.1)'
  771. }
  772. ])
  773. }
  774. },
  775. {
  776. name: '磁盘IO',
  777. type: 'line',
  778. stack: 'Total',
  779. data: diskIO,
  780. lineStyle: {
  781. color: '#F7BA1E'
  782. },
  783. areaStyle: {
  784. color: new window['echarts'].graphic.LinearGradient(0, 0, 0, 1, [
  785. {
  786. offset: 0,
  787. color: 'rgba(247, 186, 30, 0.5)'
  788. },
  789. {
  790. offset: 1,
  791. color: 'rgba(247, 186, 30, 0.1)'
  792. }
  793. ])
  794. }
  795. }
  796. ]
  797. };
  798. chart.setOption(option);
  799. // 响应式调整
  800. window.addEventListener('resize', () => {
  801. chart.resize();
  802. });
  803. }
  804. }
  805. }