camera.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const common_assets = require("../../common/assets.js");
  4. const _sfc_main = {
  5. data() {
  6. return {
  7. cameraContext: null,
  8. devicePosition: "front",
  9. interviewStarted: true,
  10. showEndModal: false,
  11. currentQuestionIndex: 0,
  12. currentStep: 1,
  13. stepTexts: ["测试准备", "回答问题", "测试结束"],
  14. progressWidth: 50,
  15. remainingTime: "00:27",
  16. selectedOption: null,
  17. showResult: false,
  18. isAnswerCorrect: false,
  19. questions: [
  20. {
  21. id: 6,
  22. text: "以下不属于中国传统节日的是( )。",
  23. options: [
  24. "A. 春节",
  25. "B. 端午节",
  26. "C. 重阳节",
  27. "D. 元旦"
  28. ],
  29. correctAnswer: 3,
  30. isImportant: true,
  31. explanation: "元旦是公历新年,属于现代节日,而春节、端午节和重阳节都是中国传统节日。"
  32. },
  33. {
  34. id: 7,
  35. text: "下列哪个是中国四大名著之一( )。",
  36. options: [
  37. "A. 聊斋志异",
  38. "B. 西游记",
  39. "C. 世说新语",
  40. "D. 聊斋志异"
  41. ],
  42. correctAnswer: 1,
  43. isImportant: false,
  44. explanation: "中国四大名著是《红楼梦》、《西游记》、《水浒传》和《三国演义》。"
  45. },
  46. {
  47. id: 8,
  48. text: '中国传统文化中"仁义礼智信"五常不包括( )。',
  49. options: [
  50. "A. 忠",
  51. "B. 孝",
  52. "C. 礼",
  53. "D. 信"
  54. ],
  55. correctAnswer: 1,
  56. isImportant: true,
  57. explanation: '儒家的五常是"仁、义、礼、智、信",不包括"孝"。'
  58. }
  59. ],
  60. useVideo: false,
  61. timerInterval: null,
  62. score: 0,
  63. totalQuestions: 0,
  64. interviewCompleted: false,
  65. digitalHumanUrl: ""
  66. // 数字人URL
  67. };
  68. },
  69. computed: {
  70. currentQuestion() {
  71. return this.questions[this.currentQuestionIndex];
  72. }
  73. },
  74. onReady() {
  75. this.cameraContext = common_vendor.index.createCameraContext();
  76. if (this.useVideo) {
  77. this.aiVideoContext = common_vendor.index.createVideoContext("aiInterviewer");
  78. }
  79. this.startTimer();
  80. this.totalQuestions = this.questions.length;
  81. this.initDigitalHuman();
  82. },
  83. methods: {
  84. startTimer() {
  85. let seconds = 30;
  86. this.timerInterval = setInterval(() => {
  87. seconds--;
  88. if (seconds <= 0) {
  89. clearInterval(this.timerInterval);
  90. if (!this.showResult) {
  91. this.checkAnswer();
  92. }
  93. }
  94. const min = Math.floor(seconds / 60).toString().padStart(2, "0");
  95. const sec = (seconds % 60).toString().padStart(2, "0");
  96. this.remainingTime = `${min}:${sec}`;
  97. }, 1e3);
  98. },
  99. resetTimer() {
  100. clearInterval(this.timerInterval);
  101. this.startTimer();
  102. },
  103. selectOption(index) {
  104. if (this.showResult)
  105. return;
  106. this.selectedOption = index;
  107. this.playAiSpeaking();
  108. },
  109. checkAnswer() {
  110. clearInterval(this.timerInterval);
  111. if (!this.currentQuestion) {
  112. console.error("当前问题不存在");
  113. return;
  114. }
  115. this.isAnswerCorrect = this.selectedOption === this.currentQuestion.correctAnswer;
  116. if (this.isAnswerCorrect) {
  117. this.score++;
  118. }
  119. if (this.currentQuestionIndex === this.questions.length - 1) {
  120. this.showEndModal = false;
  121. this.interviewCompleted = true;
  122. return;
  123. }
  124. this.goToNextQuestion();
  125. },
  126. nextQuestion() {
  127. if (this.selectedOption !== null) {
  128. this.checkAnswer();
  129. return;
  130. }
  131. },
  132. // 新增方法,处理进入下一题的逻辑
  133. goToNextQuestion() {
  134. this.showResult = false;
  135. this.selectedOption = null;
  136. this.currentQuestionIndex++;
  137. if (this.currentQuestionIndex >= this.questions.length) {
  138. this.showEndModal = false;
  139. this.interviewCompleted = true;
  140. if (this.timerInterval) {
  141. clearInterval(this.timerInterval);
  142. }
  143. return;
  144. }
  145. this.resetTimer();
  146. this.progressWidth = (this.currentQuestionIndex + 1) / this.questions.length * 100;
  147. this.playAiSpeaking();
  148. setTimeout(() => {
  149. this.pauseAiSpeaking();
  150. }, 2e3);
  151. },
  152. toggleSettings() {
  153. common_vendor.index.showToast({
  154. title: "设置功能开发中",
  155. icon: "none"
  156. });
  157. },
  158. back() {
  159. if (this.timerInterval) {
  160. clearInterval(this.timerInterval);
  161. }
  162. try {
  163. const pages = getCurrentPages();
  164. if (pages.length > 1) {
  165. common_vendor.index.reLaunch({
  166. url: "/pages/index/index"
  167. });
  168. } else {
  169. common_vendor.index.reLaunch({
  170. url: "/pages/index/index"
  171. });
  172. }
  173. } catch (e) {
  174. console.error("导航错误:", e);
  175. common_vendor.index.reLaunch({
  176. url: "/pages/index/index"
  177. });
  178. }
  179. },
  180. error(e) {
  181. console.error(e.detail);
  182. common_vendor.index.showToast({
  183. title: "相机启动失败,请检查权限设置",
  184. icon: "none"
  185. });
  186. },
  187. playAiSpeaking() {
  188. if (this.useVideo && this.aiVideoContext) {
  189. this.aiVideoContext.play();
  190. }
  191. if (this.digitalHumanUrl) {
  192. const speakText = this.currentQuestion ? this.currentQuestion.text : "";
  193. this.interactWithDigitalHuman(speakText);
  194. }
  195. },
  196. pauseAiSpeaking() {
  197. if (this.useVideo && this.aiVideoContext) {
  198. this.aiVideoContext.pause();
  199. }
  200. },
  201. // 重新开始测试
  202. restartTest() {
  203. this.currentQuestionIndex = 0;
  204. this.score = 0;
  205. this.showEndModal = false;
  206. this.showResult = false;
  207. this.selectedOption = null;
  208. this.resetTimer();
  209. },
  210. // 在methods中添加测试方法
  211. testEndScreen() {
  212. this.interviewCompleted = true;
  213. this.showEndModal = false;
  214. },
  215. // 初始化数字人
  216. initDigitalHuman() {
  217. this.digitalHumanUrl = "https://your-digital-human-service.com/avatar?id=123";
  218. },
  219. // 与数字人交互的方法
  220. interactWithDigitalHuman(message) {
  221. const webview = this.$mp.page.$getAppWebview().children()[0];
  222. if (webview) {
  223. webview.evalJS(`receiveMessage('${message}')`);
  224. }
  225. }
  226. },
  227. // 添加生命周期钩子,确保在组件销毁时清除计时器
  228. beforeDestroy() {
  229. if (this.timerInterval) {
  230. clearInterval(this.timerInterval);
  231. }
  232. }
  233. };
  234. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  235. return common_vendor.e({
  236. a: $data.digitalHumanUrl
  237. }, $data.digitalHumanUrl ? {
  238. b: $data.digitalHumanUrl
  239. } : {
  240. c: common_assets._imports_0
  241. }, {
  242. d: common_vendor.t($data.currentQuestionIndex + 1),
  243. e: common_vendor.t($options.currentQuestion.id),
  244. f: common_vendor.t($data.questions.length),
  245. g: $options.currentQuestion.isImportant
  246. }, $options.currentQuestion.isImportant ? {} : {}, {
  247. h: common_vendor.t($options.currentQuestion.text),
  248. i: common_vendor.f($options.currentQuestion.options, (option, index, i0) => {
  249. return {
  250. a: common_vendor.t(option),
  251. b: index,
  252. c: $data.selectedOption === index ? 1 : "",
  253. d: $data.showResult && index === $options.currentQuestion.correctAnswer ? 1 : "",
  254. e: $data.showResult && $data.selectedOption === index && index !== $options.currentQuestion.correctAnswer ? 1 : "",
  255. f: common_vendor.o(($event) => $options.selectOption(index), index)
  256. };
  257. }),
  258. j: common_vendor.t($data.remainingTime),
  259. k: common_vendor.o((...args) => $options.nextQuestion && $options.nextQuestion(...args)),
  260. l: $data.selectedOption === null,
  261. m: $data.showEndModal
  262. }, $data.showEndModal ? {
  263. n: common_vendor.t($data.score),
  264. o: common_vendor.t($data.totalQuestions),
  265. p: common_vendor.t($data.score),
  266. q: common_vendor.t($data.totalQuestions),
  267. r: common_vendor.o((...args) => $options.restartTest && $options.restartTest(...args)),
  268. s: common_vendor.o((...args) => $options.back && $options.back(...args))
  269. } : {}, {
  270. t: $data.interviewCompleted
  271. }, $data.interviewCompleted ? {
  272. v: common_assets._imports_0,
  273. w: common_vendor.o((...args) => $options.back && $options.back(...args))
  274. } : {});
  275. }
  276. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
  277. wx.createPage(MiniProgramPage);