camera.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const api_user = require("../../api/user.js");
  4. const common_config = require("../../common/config.js");
  5. const common_assets = require("../../common/assets.js");
  6. const _sfc_main = {
  7. data() {
  8. return {
  9. cameraContext: null,
  10. devicePosition: "front",
  11. interviewStarted: true,
  12. showEndModal: false,
  13. currentQuestionIndex: 0,
  14. currentStep: 1,
  15. stepTexts: ["测试准备", "回答问题", "测试结束"],
  16. progressWidth: 50,
  17. remainingTime: "00:27",
  18. selectedOption: null,
  19. selectedOptions: [],
  20. showResult: false,
  21. isAnswerCorrect: false,
  22. questions: [],
  23. // 改为空数组,将通过API获取
  24. interviewId: null,
  25. // 存储当前面试ID
  26. useVideo: false,
  27. timerInterval: null,
  28. score: 0,
  29. totalQuestions: 0,
  30. interviewCompleted: false,
  31. digitalHumanUrl: "",
  32. // 数字人URL
  33. loading: true,
  34. // 添加加载状态
  35. loadError: false,
  36. // 添加加载错误状态
  37. errorMessage: "",
  38. // 添加错误消息
  39. answers: [],
  40. // 存储用户的所有答案
  41. currentQuestionDetail: null,
  42. // 当前题目详情
  43. isSubmitting: false,
  44. // 是否正在提交答案
  45. openQuestionAnswer: "",
  46. // 存储开放问题的答案
  47. currentAnswer: null,
  48. // 存储当前答案以便提交
  49. questionStartTime: null,
  50. // 存储问题开始时间
  51. mode: "normal",
  52. // 相机模式
  53. currentScrollId: "question-0"
  54. // 当前滚动到的问题ID
  55. };
  56. },
  57. computed: {
  58. currentQuestion() {
  59. console.log(this.questions[this.currentQuestionIndex]);
  60. return this.questions[this.currentQuestionIndex];
  61. }
  62. },
  63. onLoad(options) {
  64. if (options && options.id) {
  65. this.interviewId = options.id;
  66. this.fetchInterviewData();
  67. } else {
  68. this.fetchInterviewList();
  69. }
  70. },
  71. onReady() {
  72. this.cameraContext = common_vendor.index.createCameraContext();
  73. if (this.useVideo) {
  74. this.aiVideoContext = common_vendor.index.createVideoContext("aiInterviewer");
  75. }
  76. this.initDigitalHuman();
  77. },
  78. methods: {
  79. // 获取面试列表
  80. async fetchInterviewList() {
  81. try {
  82. this.loading = true;
  83. const res2 = await api_user.getQuestions({ position_id: JSON.parse(common_vendor.index.getStorageSync("selectedJob")).id, page: 1, limit: 999, tenant_id: 1 });
  84. console.log(res2.items);
  85. this.interviewId = res2.items;
  86. this.fetchInterviewData(res2.items);
  87. } catch (error) {
  88. console.error("获取面试列表失败:", error);
  89. this.handleLoadError("获取面试列表失败");
  90. }
  91. },
  92. // 获取面试详情数据
  93. async fetchInterviewData(data) {
  94. try {
  95. this.loading = true;
  96. if (data && Array.isArray(data)) {
  97. this.questions = data.filter((q) => q.question_form !== 0).map((q, index) => ({
  98. id: q.id || index + 1,
  99. text: q.question || "未知问题",
  100. options: q.options || [],
  101. correctAnswer: q.correctAnswer || 0,
  102. isImportant: q.is_system || false,
  103. explanation: q.explanation || "",
  104. questionType: q.question_form,
  105. questionTypeName: q.question_form_name || "单选题",
  106. is_required_correct: q.is_required_correct || false,
  107. correctAnswers: q.correct_answers || [],
  108. difficulty: q.difficulty || 1,
  109. difficultyName: q.difficulty_name || "初级",
  110. imageUrl: q.question_image_url || ""
  111. // 添加图片URL字段
  112. }));
  113. } else {
  114. this.processInterviewData(res);
  115. }
  116. console.log(this.questions);
  117. this.totalQuestions = this.questions.length;
  118. } catch (error) {
  119. console.error("获取面试详情失败:", error);
  120. this.handleLoadError("获取面试详情失败");
  121. } finally {
  122. this.loading = false;
  123. }
  124. },
  125. // 处理面试数据
  126. processInterviewData(data) {
  127. this.questions = [];
  128. if (data && data.question_form !== 0) {
  129. const formattedQuestion = {
  130. id: data.id || 1,
  131. text: data.question || "未知问题",
  132. options: data.options || [],
  133. correctAnswer: data.correctAnswer || 0,
  134. isImportant: data.is_system || false,
  135. explanation: data.explanation || "",
  136. questionType: data.question_form,
  137. // 1-单选题,2-多选题,3-看图答题
  138. questionTypeName: data.question_form_name || "单选题",
  139. is_required_correct: data.is_required_correct || false,
  140. correctAnswers: data.correct_answers || [],
  141. difficulty: data.difficulty || 1,
  142. difficultyName: data.difficulty_name || "初级",
  143. imageUrl: data.question_image_url || ""
  144. // 添加图片URL字段
  145. };
  146. this.questions.push(formattedQuestion);
  147. this.totalQuestions = this.questions.length;
  148. } else {
  149. this.handleLoadError("没有可用的选择题");
  150. }
  151. },
  152. // 处理加载错误
  153. handleLoadError(message) {
  154. this.loadError = true;
  155. this.loading = false;
  156. this.errorMessage = message || "加载失败";
  157. common_vendor.index.showToast({
  158. title: message || "加载失败",
  159. icon: "none",
  160. duration: 2e3
  161. });
  162. },
  163. startTimer() {
  164. if (this.questions.length === 0)
  165. return;
  166. this.questionStartTime = /* @__PURE__ */ new Date();
  167. let seconds = 60;
  168. this.remainingTime = `01:00`;
  169. this.timerInterval = setInterval(() => {
  170. seconds--;
  171. if (seconds <= 0) {
  172. clearInterval(this.timerInterval);
  173. if (!this.showResult) {
  174. this.checkAnswer();
  175. setTimeout(() => {
  176. if (this.currentQuestionIndex < this.questions.length - 1) {
  177. this.goToNextQuestion();
  178. } else {
  179. common_vendor.index.navigateTo({
  180. url: "/pages/interview-question/interview-question"
  181. });
  182. }
  183. }, 1500);
  184. }
  185. }
  186. const min = Math.floor(seconds / 60).toString().padStart(2, "0");
  187. const sec = (seconds % 60).toString().padStart(2, "0");
  188. this.remainingTime = `${min}:${sec}`;
  189. }, 1e3);
  190. },
  191. resetTimer() {
  192. clearInterval(this.timerInterval);
  193. },
  194. selectOption(index) {
  195. if (this.showResult)
  196. return;
  197. if (this.currentQuestion.questionType === 2) {
  198. const optionIndex = this.selectedOptions.indexOf(index);
  199. if (optionIndex > -1) {
  200. this.selectedOptions.splice(optionIndex, 1);
  201. } else {
  202. this.selectedOptions.push(index);
  203. }
  204. } else if (this.currentQuestion.questionType === 1 || this.currentQuestion.questionType === 3) {
  205. this.selectedOption = index;
  206. this.playAiSpeaking();
  207. setTimeout(() => {
  208. this.checkAnswer();
  209. this.saveAnswer();
  210. this.submitCurrentAnswer().then(() => {
  211. setTimeout(() => {
  212. if (this.currentQuestionIndex >= this.questions.length - 1) {
  213. common_vendor.index.navigateTo({
  214. url: "/pages/interview-question/interview-question"
  215. });
  216. } else {
  217. this.goToNextQuestion();
  218. }
  219. }, 800);
  220. }).catch((error) => {
  221. console.error("提交答案失败:", error);
  222. setTimeout(() => {
  223. if (this.currentQuestionIndex >= this.questions.length - 1) {
  224. common_vendor.index.navigateTo({
  225. url: "/pages/interview-question/interview-question"
  226. });
  227. } else {
  228. this.goToNextQuestion();
  229. }
  230. }, 1e3);
  231. });
  232. }, 500);
  233. }
  234. },
  235. checkAnswer() {
  236. if (this.showResult)
  237. return;
  238. clearInterval(this.timerInterval);
  239. if (!this.currentQuestion) {
  240. console.error("当前问题不存在");
  241. return;
  242. }
  243. if (this.currentQuestion.questionType === 0) {
  244. this.isAnswerCorrect = true;
  245. } else if (this.currentQuestion.questionType === 2) {
  246. const sortedSelected = [...this.selectedOptions].sort();
  247. const sortedCorrect = [...this.currentQuestion.correctAnswers].sort();
  248. if (sortedSelected.length !== sortedCorrect.length) {
  249. this.isAnswerCorrect = false;
  250. } else {
  251. this.isAnswerCorrect = sortedSelected.every((value, index) => value === sortedCorrect[index]);
  252. }
  253. } else {
  254. this.isAnswerCorrect = this.selectedOption === this.currentQuestion.correctAnswer;
  255. }
  256. this.showResult = true;
  257. this.saveAnswer();
  258. },
  259. // 修改 nextQuestion 方法,只处理多选题
  260. nextQuestion() {
  261. if (this.currentQuestion.questionType !== 2)
  262. return;
  263. this.checkAnswer();
  264. this.saveAnswer();
  265. this.submitCurrentAnswer().then(() => {
  266. setTimeout(() => {
  267. if (this.currentQuestionIndex >= this.questions.length - 1) {
  268. common_vendor.index.navigateTo({
  269. url: "/pages/interview-question/interview-question"
  270. });
  271. } else {
  272. this.goToNextQuestion();
  273. }
  274. }, 500);
  275. }).catch((error) => {
  276. console.error("提交答案失败:", error);
  277. setTimeout(() => {
  278. if (this.currentQuestionIndex >= this.questions.length - 1) {
  279. common_vendor.index.navigateTo({
  280. url: "/pages/interview-question/interview-question"
  281. });
  282. } else {
  283. this.goToNextQuestion();
  284. }
  285. }, 1e3);
  286. });
  287. },
  288. // 保存当前题目的答案
  289. saveAnswer() {
  290. let answer;
  291. if (this.currentQuestion.questionType === 0) {
  292. answer = {
  293. questionId: this.currentQuestion.id,
  294. questionType: this.currentQuestion.questionType,
  295. answer: this.openQuestionAnswer,
  296. answerDuration: this.getAnswerDuration()
  297. // 添加答题时长
  298. };
  299. } else if (this.currentQuestion.questionType === 1 || this.currentQuestion.questionType === 3) {
  300. answer = {
  301. questionId: this.currentQuestion.id,
  302. questionType: this.currentQuestion.questionType,
  303. answer: this.selectedOption,
  304. answerDuration: this.getAnswerDuration()
  305. // 添加答题时长
  306. };
  307. } else {
  308. answer = {
  309. questionId: this.currentQuestion.id,
  310. questionType: this.currentQuestion.questionType,
  311. answer: this.selectedOptions,
  312. answerDuration: this.getAnswerDuration()
  313. // 添加答题时长
  314. };
  315. }
  316. const existingIndex = this.answers.findIndex((a) => a.questionId === answer.questionId);
  317. if (existingIndex > -1) {
  318. this.answers[existingIndex] = answer;
  319. } else {
  320. this.answers.push(answer);
  321. }
  322. this.currentAnswer = answer;
  323. console.log("已保存答案:", this.answers);
  324. },
  325. // 获取答题时长(秒)
  326. getAnswerDuration() {
  327. const remainingTimeArr = this.remainingTime.split(":");
  328. const remainingSeconds = parseInt(remainingTimeArr[0]) * 60 + parseInt(remainingTimeArr[1]);
  329. return 30 - remainingSeconds;
  330. },
  331. // 提交当前答案
  332. async submitCurrentAnswer() {
  333. if (!this.currentAnswer || this.isSubmitting)
  334. return;
  335. try {
  336. this.isSubmitting = true;
  337. common_vendor.index.showLoading({
  338. title: "正在提交答案..."
  339. });
  340. let answerContent = "";
  341. let answerOptions = [];
  342. if (this.currentAnswer.questionType === 0) {
  343. answerContent = this.currentAnswer.answer;
  344. answerOptions = [];
  345. } else if (this.currentAnswer.questionType === 1 || this.currentAnswer.questionType === 3) {
  346. const selectedIndex = this.currentAnswer.answer;
  347. const selectedOption = this.currentQuestion.options[selectedIndex];
  348. console.log("selectedOption", selectedOption);
  349. const optionId = selectedOption.id ? selectedOption.id : selectedIndex;
  350. answerContent = optionId.toString();
  351. answerOptions = [optionId];
  352. } else if (this.currentAnswer.questionType === 2) {
  353. const selectedIndices = this.currentAnswer.answer;
  354. const selectedOptionIds = selectedIndices.map((index) => {
  355. const option = this.currentQuestion.options[index];
  356. return option.id ? option.id : index;
  357. });
  358. answerOptions = selectedOptionIds;
  359. }
  360. const submitData = {
  361. position_id: JSON.parse(common_vendor.index.getStorageSync("selectedJob")).id,
  362. applicant_id: JSON.parse(common_vendor.index.getStorageSync("userInfo")).id,
  363. job_position_question_id: this.currentAnswer.questionId,
  364. // answer_content: answerContent,
  365. answer_options: answerOptions,
  366. answer_duration: this.currentAnswer.answerDuration || 0,
  367. tenant_id: 1
  368. };
  369. console.log("提交数据:", submitData);
  370. const res2 = await this.$http.post(`${common_config.apiBaseUrl}/api/job/submit_answer`, submitData);
  371. console.log("提交答案响应:", res2);
  372. return res2;
  373. } catch (error) {
  374. console.error("提交答案失败:", error);
  375. common_vendor.index.showToast({
  376. title: "提交答案失败,请重试",
  377. icon: "none"
  378. });
  379. throw error;
  380. } finally {
  381. common_vendor.index.hideLoading();
  382. this.isSubmitting = false;
  383. }
  384. },
  385. // 修改 goToNextQuestion 方法,在切换到下一题时重置当前选项状态
  386. async goToNextQuestion() {
  387. this.showResult = false;
  388. this.selectedOption = null;
  389. this.selectedOptions = [];
  390. this.openQuestionAnswer = "";
  391. this.currentQuestionIndex++;
  392. this.currentScrollId = "question-" + this.currentQuestionIndex;
  393. if (this.questions[this.currentQuestionIndex]) {
  394. this.progressWidth = (this.currentQuestionIndex + 1) / this.questions.length * 100;
  395. this.resetTimer();
  396. this.playAiSpeaking();
  397. setTimeout(() => {
  398. this.pauseAiSpeaking();
  399. }, 2e3);
  400. return;
  401. }
  402. try {
  403. this.loading = true;
  404. await new Promise((resolve) => setTimeout(resolve, 1e3));
  405. const res2 = {
  406. /* 模拟的题目数据 */
  407. };
  408. if (res2) {
  409. const formattedQuestion = {
  410. id: res2.id || this.currentQuestionIndex + 1,
  411. text: res2.question || "未知问题",
  412. options: res2.options || [],
  413. correctAnswer: res2.correctAnswer || 0,
  414. isImportant: res2.is_system || false,
  415. explanation: res2.explanation || "",
  416. questionType: res2.question_form || 1,
  417. questionTypeName: res2.question_form_name || "单选题",
  418. is_required_correct: res2.is_required_correct || false,
  419. correctAnswers: res2.correct_answers || [],
  420. difficulty: res2.difficulty || 1,
  421. difficultyName: res2.difficulty_name || "初级"
  422. };
  423. this.questions.push(formattedQuestion);
  424. }
  425. } catch (error) {
  426. console.error("获取题目详情失败:", error);
  427. common_vendor.index.showToast({
  428. title: "获取题目失败,请重试",
  429. icon: "none"
  430. });
  431. this.currentQuestionIndex--;
  432. } finally {
  433. this.loading = false;
  434. this.progressWidth = (this.currentQuestionIndex + 1) / this.questions.length * 100;
  435. this.resetTimer();
  436. }
  437. },
  438. toggleSettings() {
  439. common_vendor.index.showToast({
  440. title: "设置功能开发中",
  441. icon: "none"
  442. });
  443. },
  444. back(target) {
  445. if (this.timerInterval) {
  446. clearInterval(this.timerInterval);
  447. }
  448. if (target) {
  449. common_vendor.index.navigateTo({
  450. url: target
  451. });
  452. return;
  453. }
  454. },
  455. error(e) {
  456. console.error(e.detail);
  457. common_vendor.index.showToast({
  458. title: "相机启动失败,请检查权限设置",
  459. icon: "none"
  460. });
  461. },
  462. playAiSpeaking() {
  463. if (this.useVideo && this.aiVideoContext) {
  464. this.aiVideoContext.play();
  465. }
  466. if (this.digitalHumanUrl) {
  467. const speakText = this.currentQuestion ? this.currentQuestion.text : "";
  468. this.interactWithDigitalHuman(speakText);
  469. }
  470. },
  471. pauseAiSpeaking() {
  472. if (this.useVideo && this.aiVideoContext) {
  473. this.aiVideoContext.pause();
  474. }
  475. },
  476. // 修改 restartTest 方法,添加可选的跳转目标
  477. restartTest(target) {
  478. this.currentQuestionIndex = 0;
  479. this.score = 0;
  480. this.showEndModal = false;
  481. this.showResult = false;
  482. this.selectedOption = null;
  483. this.selectedOptions = [];
  484. this.resetTimer();
  485. if (target) {
  486. common_vendor.index.navigateTo({
  487. url: target
  488. });
  489. }
  490. },
  491. // 在methods中添加测试方法
  492. testEndScreen() {
  493. this.interviewCompleted = true;
  494. this.showEndModal = false;
  495. },
  496. // 初始化数字人
  497. initDigitalHuman() {
  498. this.digitalHumanUrl = "";
  499. },
  500. // 与数字人交互的方法
  501. interactWithDigitalHuman(message) {
  502. const webview = this.$mp.page.$getAppWebview().children()[0];
  503. if (webview) {
  504. webview.evalJS(`receiveMessage('${message}')`);
  505. }
  506. },
  507. // 添加 navigateToInterview 方法
  508. navigateToInterview() {
  509. this.showEndModal = false;
  510. common_vendor.index.navigateTo({
  511. url: "/pages/interview/interview",
  512. success: () => {
  513. console.log("成功跳转到interview页面");
  514. },
  515. fail: (err) => {
  516. console.error("跳转失败:", err);
  517. common_vendor.index.showToast({
  518. title: "跳转失败,请手动返回首页",
  519. icon: "none"
  520. });
  521. }
  522. });
  523. },
  524. // 添加 handleCameraError 方法
  525. handleCameraError(e) {
  526. console.error("相机错误:", e.detail);
  527. common_vendor.index.showToast({
  528. title: "相机启动失败,请检查权限设置",
  529. icon: "none"
  530. });
  531. },
  532. // 修改 isOptionSelected 方法,更精确地判断选项是否被选中
  533. isOptionSelected(question, qIndex, optionIndex) {
  534. const answer = this.answers.find((a) => a.questionId === question.id);
  535. if (qIndex === this.currentQuestionIndex) {
  536. if (question.questionType === 1 || question.questionType === 3) {
  537. return this.selectedOption === optionIndex;
  538. } else if (question.questionType === 2) {
  539. return this.selectedOptions.includes(optionIndex);
  540. }
  541. } else if (answer) {
  542. if (question.questionType === 1 || question.questionType === 3) {
  543. return answer.answer === optionIndex;
  544. } else if (question.questionType === 2 && Array.isArray(answer.answer)) {
  545. return answer.answer.includes(optionIndex);
  546. }
  547. }
  548. return false;
  549. }
  550. },
  551. // 添加生命周期钩子,确保在组件销毁时清除计时器
  552. beforeDestroy() {
  553. if (this.timerInterval) {
  554. clearInterval(this.timerInterval);
  555. }
  556. }
  557. };
  558. if (!Array) {
  559. const _component_uni_load_more = common_vendor.resolveComponent("uni-load-more");
  560. _component_uni_load_more();
  561. }
  562. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  563. return common_vendor.e({
  564. a: !$data.digitalHumanUrl
  565. }, !$data.digitalHumanUrl ? {
  566. b: $data.mode,
  567. c: common_vendor.o((...args) => $options.handleCameraError && $options.handleCameraError(...args))
  568. } : $data.digitalHumanUrl ? {
  569. e: $data.digitalHumanUrl
  570. } : {
  571. f: common_assets._imports_0$1
  572. }, {
  573. d: $data.digitalHumanUrl,
  574. g: common_vendor.f($data.questions, (question, qIndex, i0) => {
  575. return common_vendor.e({
  576. a: common_vendor.t(qIndex + 1),
  577. b: common_vendor.t(question.questionTypeName),
  578. c: common_vendor.t(question.text),
  579. d: question.is_required_correct
  580. }, question.is_required_correct ? {} : {}, {
  581. e: question.questionType === 3 && question.imageUrl
  582. }, question.questionType === 3 && question.imageUrl ? {
  583. f: question.imageUrl
  584. } : {}, {
  585. g: question.questionType !== 0
  586. }, question.questionType !== 0 ? {
  587. h: common_vendor.f(question.options, (option, index, i1) => {
  588. return {
  589. a: common_vendor.t(option.option_text || (typeof option === "string" ? option : JSON.stringify(option))),
  590. b: index,
  591. c: $options.isOptionSelected(question, qIndex, index) ? 1 : "",
  592. d: common_vendor.o(($event) => qIndex === $data.currentQuestionIndex && $options.selectOption(index), index)
  593. };
  594. }),
  595. i: qIndex !== $data.currentQuestionIndex ? 1 : ""
  596. } : {}, {
  597. j: qIndex === $data.currentQuestionIndex && question.questionType === 2
  598. }, qIndex === $data.currentQuestionIndex && question.questionType === 2 ? {
  599. k: common_vendor.t("提交答案"),
  600. l: common_vendor.o(($event) => $options.nextQuestion(), question.id),
  601. m: $data.selectedOptions.length === 0
  602. } : {}, {
  603. n: question.id,
  604. o: "question-" + qIndex
  605. });
  606. }),
  607. h: common_vendor.t($data.questions.length),
  608. i: $data.currentScrollId,
  609. j: $data.showEndModal
  610. }, $data.showEndModal ? {
  611. k: common_vendor.o((...args) => $options.navigateToInterview && $options.navigateToInterview(...args))
  612. } : {}, {
  613. l: $data.interviewCompleted
  614. }, $data.interviewCompleted ? {
  615. m: common_assets._imports_0$1,
  616. n: common_vendor.o((...args) => $options.back && $options.back(...args))
  617. } : {}, {
  618. o: $data.loading
  619. }, $data.loading ? {
  620. p: common_vendor.p({
  621. status: "loading",
  622. contentText: {
  623. contentdown: "加载中..."
  624. }
  625. })
  626. } : {}, {
  627. q: !$data.loading && $data.loadError
  628. }, !$data.loading && $data.loadError ? {
  629. r: common_vendor.o((...args) => $options.fetchInterviewData && $options.fetchInterviewData(...args))
  630. } : {});
  631. }
  632. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
  633. wx.createPage(MiniProgramPage);