shapeIntuition2.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <template>
  2. <div class="content-container">
  3. <div class="content-outline" v-if="!testResultStr">
  4. <div class="left_part">
  5. <div id="left_top" class="flex-row">
  6. <el-image class="setting" :src="require('@/assets/9551.png')" fit="cover" />
  7. <div class="text"> 操作提示:</div>
  8. </div>
  9. <div class="left-desc-80" v-html="subjectInfo.testDescription"></div>
  10. </div>
  11. <div
  12. class="right_part"
  13. :style="{
  14. background:
  15. 'url(' + require('./../../assets/page' + taskId + '.png') + ')',
  16. 'background-size': '100% 100%',
  17. }"
  18. >
  19. <div id="title">
  20. <span>{{ subjectInfo.name }}</span>
  21. </div>
  22. <div
  23. style="
  24. position: absolute;
  25. bottom: 0.156rem;
  26. left: 50%;
  27. transform: translateX(-50%);
  28. "
  29. >
  30. <el-button type="primary" class="start" v-if="button0Show" @click="startTest(0)">练习测试</el-button>
  31. <el-button type="primary" class="start" v-if="button1Show" @click="startTest(1)">正式测试</el-button>
  32. </div>
  33. </div>
  34. </div>
  35. <!-- LOGO -->
  36. <div v-show="testResultStrShow" style="width: 650px; margin: 20px auto; line-height: 2">
  37. <p style="margin-top: 20%; font-size: 30px">
  38. {{ testResultStr }}
  39. </p>
  40. </div>
  41. <div v-if="testFlag" :class="{ testMainDiv: !testState, activeTask: testState }" @contextmenu.prevent=""
  42. @click.left="userClick('L')" @click.right="userClick('R')">
  43. <MainProgress v-if="testTypeCode == 1" :cur-percentage="(imgIndex / 120)" />
  44. <div class="taskHead">
  45. <div class="scale" @click.stop="screen">
  46. <img src="@/assets/small-big.png" alt="" />
  47. </div>
  48. </div>
  49. <div class="taskHead">
  50. <div class="scale" @click.stop="screen">
  51. <img src="../../assets/small-big.png" alt="" />
  52. </div>
  53. </div>
  54. <div class="glass">
  55. <p v-show="countDownShow" class="countdownStr">
  56. {{ countDownStr }}
  57. </p>
  58. <img v-show="showDuckEgg" :src="examImgUrl" alt="" class="shapeImg" />
  59. </div>
  60. <!-- <img v-show="showWhiteFlag" src='../../assets/congnitiveAblitity/whiteFlag.png' alt="" style="width: 50px; height: 50px; margin-top: 20%"> -->
  61. <!-- 演示使用 -->
  62. <!-- <div class="steering">
  63. <el-button type="primary" icon="el-icon-arrow-left" @click="userClick('L')"></el-button>
  64. <el-button type="primary" @click="userClick('R')"><i class="el-icon-arrow-right el-icon--right"></i></el-button>
  65. </div> -->
  66. </div>
  67. <go-back />
  68. </div>
  69. </template>
  70. <script>
  71. import { oSessionStorage } from "../../utils/utils";
  72. import { preloader } from "@/utils/utils";
  73. import screenfull from "screenfull";
  74. import MainProgress from "@/components/MainProgress/index.vue";
  75. import GoBack from "@/components/goBack/index.vue";
  76. export default {
  77. components: {GoBack, MainProgress},
  78. data() {
  79. return {
  80. userId: "",
  81. userTestResult: {},
  82. imgUrl: "",
  83. examImgUrl: "",
  84. taskId: "", // 认知任务id
  85. testFlag: false,
  86. testState: false,
  87. saveFlag: false, //结果保存按钮显示标志
  88. subjectInfo: "", //认知任务详情
  89. button0Show: true, // 控制按钮显示隐藏
  90. button1Show: false, // 控制按钮显示隐藏
  91. buttonName: "开始测试", // 正式测试 // 重新练习
  92. testTypeCode: 0, // 0-练习测试 1-正式测试 2-重新测试
  93. imgIndex: 0,
  94. userTestPicList: [], //用户点击图片列表
  95. showImage: true,
  96. difficultList: [0], // [0,10,30,45,60,90,120,180,360]
  97. testPicCount: 10, //测试数目
  98. userRightClickDirection: "", //测试者应该点击的方向
  99. userRightResponseCount: 0, //测试者反应正确的次数
  100. showDuckEgg: false,
  101. countDownTime: 6, //开始前的倒计时
  102. countDownStr: "练习马上开始!",
  103. countDownShow: true,
  104. testTunrnCount: 0, //正式测试轮数
  105. testEndFlag: false, //测试结束标志
  106. testResultStrShow: false, //测试结果展示
  107. testResultStr: "", //测试成绩
  108. userCanClick: true, //用户标识用户单次刺激只能点击一次
  109. myInterval: "",
  110. timeOne: "",
  111. timeTwo: "",
  112. startMilliSeconds: 0, //反应时
  113. userResponseRecords: [], //用户测试反应记录
  114. saveFalg: true,
  115. };
  116. },
  117. // 页面初始化函数
  118. created() {
  119. this.taskId = this.$route.query.taskId;
  120. this.init(this.taskId);
  121. },
  122. mounted() {
  123. document.onkeydown = (e) => {
  124. let key = window.event.keyCode
  125. if (key === 37) {
  126. this.userClick('L');
  127. }
  128. if (key === 39) {
  129. this.userClick('R');
  130. }
  131. }
  132. },
  133. destroyed() {
  134. clearInterval(this.myInterval);
  135. clearTimeout(this.timeOne);
  136. clearTimeout(this.timeTwo);
  137. },
  138. methods: {
  139. init(taskId) {
  140. //this.subjectInfo = cognitiveAbilityTaskList[taskId];
  141. this.subjectInfo = JSON.parse(oSessionStorage.getItem("subjectInfo"));
  142. },
  143. userClick(clickFlag) {
  144. if (this.countDownShow || !this.userCanClick) {
  145. return;
  146. }
  147. this.userCanClick = false;
  148. let milliSecondsCount = new Date().getTime() - this.startMilliSeconds;
  149. let userResponseStr = "Wrong";
  150. clearTimeout(this.timeOne);
  151. //用户反应正确性判断
  152. if (this.userRightClickDirection == clickFlag) {
  153. this.userRightResponseCount++;
  154. userResponseStr = "Right";
  155. }
  156. //判断是否测试结束
  157. if (this.imgIndex == this.userTestPicList.length) {
  158. this.testEndFlag = true;
  159. }
  160. //记录用户反应
  161. if (this.testTypeCode == 1) {
  162. this.userResponseRecords.push({
  163. index: this.imgIndex,
  164. rightOrWrong: userResponseStr,
  165. responseTime: milliSecondsCount,
  166. diff: this.userTestPicList[this.imgIndex - 1].diff,
  167. });
  168. }
  169. this.showDuckEgg = false;
  170. this.timeTwo = setTimeout(() => {
  171. this.showTargetNow();
  172. }, 500);
  173. },
  174. format(percentage) {
  175. return percentage === 100 ? "测试已完成" : "任务进度";
  176. },
  177. screen() {
  178. screenfull.toggle();
  179. },
  180. startTest(testType) {
  181. if (
  182. sessionStorage.getItem("b80bb7740288fda1f201890375a60c8f") == "" ||
  183. sessionStorage.getItem("b80bb7740288fda1f201890375a60c8f") == null
  184. ) {
  185. this.$message.error("请先登录!");
  186. return;
  187. }
  188. this.screen();
  189. if (testType == 0) {
  190. this.testTypeCode = 0;
  191. } else {
  192. this.saveFalg = true;
  193. this.testTypeCode = 1;
  194. }
  195. this.userId = sessionStorage.getItem("b80bb7740288fda1f201890375a60c8f");
  196. if (this.testTypeCode == 1) {
  197. this.difficultList = [360, 180, 90, 60, 30, 0]; // [360,180,90,60,30,0]
  198. this.imgIndex = 0;
  199. this.countDownStr = "马上开始!";
  200. this.countDownTime = 6;
  201. this.testEndFlag = false;
  202. this.showDuckEgg = false;
  203. this.userTestPicList = [];
  204. }
  205. this.countDownShow = true;
  206. this.userTestPicListCreate();
  207. // 预加载图片后开始测试
  208. preloader(this.userTestPicList, () => {
  209. this.testFlag = true;
  210. this.testState = true;
  211. this.countDown();
  212. });
  213. },
  214. showTargetNow() {
  215. // 练习间隔2~4,正式测试2~12;
  216. this.showDuckEgg = false;
  217. if (this.testEndFlag) {
  218. this.computeScore();
  219. } else {
  220. this.userRightClickDirection = this.userTestPicList[this.imgIndex].imgDirection;
  221. this.examImgUrl = this.userTestPicList[this.imgIndex].imgUrl;
  222. this.showDuckEgg = true;
  223. this.imgIndex++;
  224. this.startMilliSeconds = new Date().getTime();
  225. this.userCanClick = true;
  226. if (this.imgIndex == this.userTestPicList.length) {
  227. this.testEndFlag = true;
  228. }
  229. this.timeOne = setTimeout(this.ifShowNextOne, 10 * 1000, this.imgIndex);
  230. }
  231. },
  232. ifShowNextOne(needClickIndex) {
  233. if (needClickIndex == this.imgIndex) {
  234. this.userClick("NULL");
  235. }
  236. },
  237. computeScore() {
  238. screenfull.exit();
  239. if (this.testTypeCode == 0) {
  240. this.testFlag = false;
  241. this.testState = false;
  242. //this.testTypeCode =1
  243. this.countDownStr = "练习马上开始!";
  244. this.userRightResponseCount = 0;
  245. this.imgIndex = 0;
  246. this.countDownTime = 6;
  247. this.testEndFlag = false;
  248. this.showDuckEgg = false;
  249. this.userTestPicList = [];
  250. this.button1Show = true;
  251. this.$message({
  252. message: "测试结束!",
  253. type: "success",
  254. });
  255. } else {
  256. let userScore = (
  257. (this.userRightResponseCount / this.userResponseRecords.length) *
  258. 100
  259. ).toFixed(2);
  260. this.testFlag = false;
  261. this.testState = false;
  262. this.button0Show = false;
  263. this.button1Show = false;
  264. //console.log(this.userResponseRecords)
  265. if (this.saveFalg) {
  266. this.$http.post(
  267. `/cognize/SHAPE2`,
  268. {
  269. userId: this.userId,
  270. userScore: userScore + "%",
  271. userResponseRecords: this.userResponseRecords,
  272. testPlanId: this.$route.query.testPlanId || "",
  273. },
  274. (response) => {
  275. this.goTestResult(response.data)
  276. this.$message({
  277. message: "测试结束!",
  278. type: "success",
  279. });
  280. // this.$router.push({
  281. // name: "TestResult",
  282. // params: {
  283. // result: [
  284. // {
  285. // name: "测试准确率",
  286. // value: userScore + "%",
  287. // }
  288. // ],
  289. // },
  290. // });
  291. }
  292. );
  293. this.saveFalg = false;
  294. }
  295. }
  296. },
  297. userTestPicListCreate() {
  298. let imgObj = {
  299. // imgUrl:'',
  300. // imgDirection:'',
  301. // userClickDirection:''
  302. };
  303. if (this.testTypeCode == 0) {
  304. //随机呈现最简单的10张图片
  305. let imgIndexList = this.getRandomNumber(10, 20);
  306. for (let j = 0; j < this.difficultList.length; j++) {
  307. for (let i = 0; i < imgIndexList.length; i++) {
  308. imgObj = {};
  309. if (i % 2 == 0) {
  310. imgObj.imgUrl = require("../../assets/congnitiveAblitity/shapeIntuition/R_ELP_test_jitter" +
  311. this.difficultList[j] +
  312. "_s" +
  313. imgIndexList[i] +
  314. ".jpg");
  315. imgObj.imgDirection = "R";
  316. imgObj.userClickDirection = "";
  317. } else {
  318. imgObj.imgUrl = require("../../assets/congnitiveAblitity/shapeIntuition/ELP_test_jitter" +
  319. this.difficultList[j] +
  320. "_s" +
  321. imgIndexList[i] +
  322. ".jpg");
  323. imgObj.imgDirection = "L";
  324. imgObj.userClickDirection = "";
  325. }
  326. this.userTestPicList.push(imgObj);
  327. }
  328. }
  329. this.shuffle(this.userTestPicList);
  330. } else {
  331. //展示所有图片
  332. for (let j = 0; j < this.difficultList.length; j++) {
  333. var tempList = [];
  334. for (let i = 1; i < 11; i++) {
  335. imgObj = {};
  336. imgObj.imgUrl = require("../../assets/congnitiveAblitity/shapeIntuition/R_ELP_test_jitter" +
  337. this.difficultList[j] +
  338. "_s" +
  339. i +
  340. ".jpg");
  341. imgObj.imgDirection = "R";
  342. imgObj.userClickDirection = "";
  343. imgObj.diff = this.difficultList[j];
  344. tempList.push(imgObj);
  345. imgObj = {};
  346. imgObj.imgUrl = require("../../assets/congnitiveAblitity/shapeIntuition/ELP_test_jitter" +
  347. this.difficultList[j] +
  348. "_s" +
  349. i +
  350. ".jpg");
  351. imgObj.imgDirection = "L";
  352. imgObj.userClickDirection = "";
  353. imgObj.diff = this.difficultList[j];
  354. tempList.push(imgObj);
  355. //console.log(tempList)
  356. }
  357. this.shuffle(tempList);
  358. this.userTestPicList = this.userTestPicList.concat(tempList);
  359. console.log(this.userTestPicList);
  360. this.testPicCount = this.userTestPicList.length;
  361. }
  362. }
  363. },
  364. getRandomNumber(size, maxNumber) {
  365. let numberList = [];
  366. for (var i = 0; i < size; i++) {
  367. numberList.push(Math.floor(Math.random() * maxNumber) + 1);
  368. }
  369. return numberList;
  370. },
  371. countDown() {
  372. // 测试时间倒计时
  373. this.myInterval = setInterval(() => {
  374. this.countDownTime--;
  375. this.countDownStr = this.countDownTime;
  376. if (this.countDownTime == 0) {
  377. this.countDownShow = false;
  378. //显示鸭蛋
  379. this.showTargetNow();
  380. // 清除定时器
  381. clearInterval(this.myInterval);
  382. //this.countDownTime = 5;
  383. }
  384. }, 1000);
  385. },
  386. shuffle(arr) {
  387. var i = arr.length,
  388. t,
  389. j;
  390. while (i) {
  391. j = Math.floor(Math.random() * i--);
  392. t = arr[i];
  393. arr[i] = arr[j];
  394. arr[j] = t;
  395. }
  396. },
  397. },
  398. };
  399. </script>
  400. <style scoped>
  401. .testMainDiv {
  402. margin: 0 auto;
  403. margin-top: 10px;
  404. background: gray;
  405. background-size: cover;
  406. /* text-align:center; */
  407. width: 500px;
  408. height: 300px;
  409. /* object-fit:fill; */
  410. }
  411. .activeTask {
  412. background: url(../../assets/congnitiveAblitity/shapeIntuition.png) no-repeat center;
  413. background-size: cover;
  414. position: fixed;
  415. top: 0;
  416. left: 0;
  417. right: 0;
  418. bottom: 0;
  419. }
  420. .scaleName {
  421. margin-top: 70px;
  422. background-size: cover;
  423. }
  424. .scaleButton {
  425. margin-top: 20px;
  426. margin-bottom: 20px;
  427. background-size: cover;
  428. }
  429. .steering {
  430. width: 50%;
  431. position: absolute;
  432. bottom: 20%;
  433. left: 50%;
  434. transform: translateX(-50%);
  435. display: flex;
  436. justify-content: space-between;
  437. }
  438. .steering .left {
  439. width: 60px;
  440. height: 60px;
  441. background: url(../../assets/left.png) no-repeat center;
  442. }
  443. .steering .right {
  444. width: 60px;
  445. height: 60px;
  446. background: url(../../assets/right.png) no-repeat center;
  447. margin-left: 15px;
  448. }
  449. .imgBox {
  450. font-size: 50px;
  451. color: black;
  452. position: absolute;
  453. top: 50%;
  454. left: 50%;
  455. transform: translate(-50%, -50%);
  456. }
  457. .shapeImg {
  458. width: 50%;
  459. position: absolute;
  460. top: 50%;
  461. left: 50%;
  462. transform: translate(-50%, -50%);
  463. }
  464. .addImg {
  465. width: 71px;
  466. width: 71px;
  467. position: absolute;
  468. top: 50%;
  469. left: 50%;
  470. transform: translate(-50%, -50%);
  471. }
  472. </style>