page-interview.html 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <div class="interview-container">
  2. <!-- 头部区域 -->
  3. <div class="interview-header">
  4. <div class="logo">AI面试官</div>
  5. <div class="timer">
  6. <i class="fas fa-clock"></i>
  7. 剩余时间: {{ remainingTime }}
  8. <span *ngIf="remainingMinutes === 0 && remainingSeconds <= 30" class="time-warning">
  9. (即将结束)
  10. </span>
  11. </div>
  12. </div>
  13. <!-- 数字人区域 -->
  14. <div class="avatar-section">
  15. <div class="avatar-container">
  16. <img [src]="avatarImage" alt="AI头像" class="avatar-img"
  17. (error)="avatarImage = 'assets/default-avatar.svg'">
  18. <div class="voice-wave" [style.animation]="isListening ? 'wave 2s infinite' : 'none'"></div>
  19. </div>
  20. <div class="avatar-expression">
  21. <span class="expression-dot"></span>
  22. <span>{{ expressionText }}</span>
  23. </div>
  24. </div>
  25. <!-- 对话区域 -->
  26. <div class="dialog-container" #dialogContainer>
  27. @for (message of messages; track message) {
  28. <div class="message" [ngClass]="{'message-ai': message.sender === 'ai', 'message-user': message.sender === 'user'}">
  29. <div class="message-bubble" [ngClass]="{'ai-bubble': message.sender === 'ai', 'user-bubble': message.sender === 'user'}">
  30. {{ message.text }}
  31. </div>
  32. <div class="message-meta" [ngClass]="{'ai-meta': message.sender === 'ai', 'user-meta': message.sender === 'user'}">
  33. <i [class]="message.sender === 'ai' ? 'fas fa-robot' : 'fas fa-user'"></i>
  34. {{ message.sender === 'ai' ? 'AI面试官' : '您' }}
  35. </div>
  36. </div>}
  37. </div>
  38. <!-- 问题卡片 -->
  39. @if (showQuestionCard) {
  40. <div class="question-card">
  41. <div class="question-text">
  42. {{ currentQuestion }}
  43. </div>
  44. <div class="question-progress">
  45. <span>问题 {{ currentQuestionIndex + 1 }}/{{ questions.length }}</span>
  46. <div class="progress-bar">
  47. <div class="progress-fill" [style.width]="progress + '%'"></div>
  48. </div>
  49. <span>{{ progress }}%</span>
  50. </div>
  51. </div>}
  52. <!-- 语音输入区域 -->
  53. <div class="voice-input-section">
  54. <div class="voice-controls">
  55. <button class="voice-btn"
  56. (mousedown)="startVoiceInput()"
  57. (mouseup)="stopVoiceInput()"
  58. [class.active]="isListening">
  59. <i class="fas fa-microphone"></i>
  60. <div class="voice-wave"></div>
  61. </button>
  62. <button class="voice-btn"
  63. (click)="playQuestion()"
  64. style="background: linear-gradient(135deg, #48BB78, #38A169);">
  65. <i class="fas fa-play"></i>
  66. </button>
  67. </div>
  68. @if (showSubmitButton) {
  69. <button class="submit-btn" (click)="submitAnswer()" [disabled]="isAnalyzing">
  70. <svg class="check-icon" viewBox="0 0 24 24" width="16" height="16">
  71. <path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z" style="color: burlywood;"/>
  72. </svg>
  73. <div style="color: black;">确认上传并分析</div>
  74. </button>
  75. }
  76. <div class="voice-hint">
  77. 点击播放按钮可重复听取问题<br>
  78. 按住麦克风按钮开始回答
  79. </div>
  80. </div>
  81. <!-- 分析仪表盘 -->
  82. <div class="dashboard-section">
  83. <div class="dashboard-title">
  84. <h3>实时分析面板</h3>
  85. <button class="toggle-btn" (click)="toggleRadarChart()">
  86. <i [class]="showRadarChart ? 'fas fa-chart-bar' : 'fas fa-chart-radar'"></i>
  87. {{ showRadarChart ? '隐藏雷达图' : '显示雷达图' }}
  88. </button>
  89. </div>
  90. <div class="dashboard-content">
  91. <div class="metric-item expressiveness">
  92. <div class="metric-header">
  93. <span class="metric-name">表达能力</span>
  94. <span class="metric-value">{{ metrics.expressiveness }}/100</span>
  95. </div>
  96. <div class="metric-bar">
  97. <div class="metric-fill" [style.width]="metrics.expressiveness + '%'"></div>
  98. </div>
  99. </div>
  100. <div class="metric-item professionalism">
  101. <div class="metric-header">
  102. <span class="metric-name">专业度</span>
  103. <span class="metric-value">{{ metrics.professionalism }}/100</span>
  104. </div>
  105. <div class="metric-bar">
  106. <div class="metric-fill" [style.width]="metrics.professionalism + '%'"></div>
  107. </div>
  108. </div>
  109. <div class="metric-item relevance">
  110. <div class="metric-header">
  111. <span class="metric-name">岗位匹配度</span>
  112. <span class="metric-value">{{ metrics.relevance }}/100</span>
  113. </div>
  114. <div class="metric-bar">
  115. <div class="metric-fill" [style.width]="metrics.relevance + '%'"></div>
  116. </div>
  117. </div>
  118. </div>
  119. @if (showRadarChart){
  120. <div id="radarChart" class="radar-chart"></div>
  121. }
  122. </div>
  123. </div>