Plan.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. <script setup lang="ts">
  2. import CpmdHeader from '@/components/CpmdHeader.vue';
  3. import CpmdQuestionnaire from '@/components/CpmdQuestionnaire.vue'
  4. import { onMounted, onUnmounted, ref } from 'vue'
  5. import { useRouter } from 'vue-router'
  6. const router = useRouter()
  7. //调用子组件的ref
  8. const question = ref<any>()
  9. //持久化设置 菜单状态
  10. import { menuStatusStore, userInfoStore } from '@/stores'
  11. import { isHaveManage } from '@/utils/test';
  12. import { queryIsQuestionApi, userPlanApi, userPlanDetailApi } from '@/api/home';
  13. import { ElMessage } from 'element-plus';
  14. const userInfo = userInfoStore();
  15. const menuStatus = menuStatusStore();
  16. menuStatus.saveActiveIndex('4')
  17. //标志 设置--方法是否结束的标志
  18. const isFinshed = ref<boolean>(false)
  19. //定义计划列表数据
  20. const planList = ref<any>([
  21. ])
  22. //临时存储数组的
  23. const tempPlanList = ref<any>({})
  24. //时间格式化 1000 60 60
  25. // const formatterTi = (val: number) => {
  26. // let mill = Math.floor(val / 1000)
  27. // let ss = Math.floor(mill / 60)
  28. // //先判断是多少个小时
  29. // let hour = Math.floor(val / 1000 / 60 / 60)
  30. // return hour + ':时'
  31. // }
  32. //调用--接口
  33. //紧接着开始
  34. const continueFun = () => {
  35. startPlan(tempPlanList.value);
  36. }
  37. //点击了开始测试--跳转到测试页面
  38. const startPlan = async (val: any) => {
  39. tempPlanList.value = val
  40. //先判断
  41. //是否做了问卷
  42. //如果未做问卷需要弹出问卷的弹出框
  43. //做完以后开始测试
  44. let res: any = await queryIsQuestionApi()
  45. if (res.data != null) {
  46. //此时是问卷未做
  47. //调用问卷组件打开
  48. question.value.open(res.data, '1')
  49. return
  50. }
  51. let nextFlag = '';
  52. let type = '';
  53. if (val.scaleList.length > 0) {
  54. //循环判断是否都完成了
  55. for (let i = 0; i < val.scaleList.length; i++) {
  56. if (val.scaleList[i].isCompleted != '1') {
  57. nextFlag = val.scaleList[i].flag;
  58. type = val.scaleList[i].contentType;
  59. break;
  60. }
  61. }
  62. }
  63. //当标志是空的时候证明所有量表的问答测试都已经完成了
  64. //接下就需要判断认知任务的完成情况了
  65. if (nextFlag == '') {
  66. //那就需要判断是否是 认知任务是否做完了
  67. for (let i = 0; i < val.taskList.length; i++) {
  68. if (val.taskList[i].isCompleted !== '1') {
  69. nextFlag = val.taskList[i].flag;
  70. type = val.taskList[i].contentType;
  71. }
  72. }
  73. } else {
  74. //那就需要
  75. //假如没做完的---判断是flag 是否是scl90
  76. if (nextFlag == "20210617140713") {
  77. //设置---
  78. //判断scl 90 的完成状态是0还是2
  79. for (let i = 0; i < val.scaleList.length; i++) {
  80. if (val.scaleList[i].flag == '20210617140713') {
  81. if (val.scaleList[i].isCompleted == '0') {
  82. }
  83. if (val.scaleList[i].isCompleted == '2') {
  84. //如果是2的话
  85. //几个量表
  86. //拿到
  87. //需要--找到下一个需要做的不展示但是需要必测的
  88. }
  89. }
  90. }
  91. }
  92. }
  93. //如果是量表就开始跳转到量表页面
  94. //判断是type 0还是1
  95. //如果是0的话,需要跳转到量表中间页面
  96. if (type == '0') {
  97. //跳转量表中间页
  98. //传输
  99. router.push({
  100. name: 'scaleDetail', params: {
  101. planId: val.id,
  102. planName: val.planName,
  103. flag: nextFlag,
  104. type: type
  105. }
  106. })
  107. } else if (type == '1') {
  108. //跳转到认知任务中间页
  109. router.push({
  110. name: 'cognize', params: {
  111. planId: val.id,
  112. planName: val.planName,
  113. flag: nextFlag,
  114. type: type
  115. }
  116. })
  117. }
  118. //如果是1的话,需要跳转到认知任务中间页面
  119. //先判断量表接口中是否都完成了
  120. //如果量表接口都完成了
  121. //则开始循环认知任务接口
  122. }
  123. const planNumGet = async () => {
  124. isFinshed.value = false
  125. //如果在就是登录了
  126. if (userInfo.token) {
  127. let userNo = ''
  128. //登录的话
  129. //判断当前是否有后台管理
  130. userNo = userInfo.userInfo.userNo
  131. //调用根据用户查询计划的API
  132. let res: any = await userPlanApi(userNo)
  133. userInfo.savePlanCurrentNum(res.data.length)
  134. planList.value = res.data
  135. //循环list 给她赋值
  136. for (let i = 0; i < planList.value.length; i++) {
  137. let params = {
  138. planId: planList.value[i].id,
  139. userNo: userInfo.userInfo.userNo
  140. }
  141. let temp: any = await userPlanDetailApi(params)
  142. planList.value[i].list = temp.data
  143. }
  144. //-------------处理SCL90的完成状态----------------
  145. for (let i = 0; i < planList.value.length; i++) {
  146. //
  147. if (planList.value[i].list.length > 0) {
  148. planList.value[i].scaleList = []
  149. planList.value[i].taskList = []
  150. //判断是否有----不显示必做但是必做未完成的
  151. let flag = false
  152. for (let j = 0; j < planList.value[i].list.length; j++) {
  153. //
  154. //不需要展示--但是必做--且含有未完成的
  155. if (planList.value[i].list[j].isDisplayed == '0'
  156. && planList.value[i].list[j].isAvailable == '1'
  157. && planList.value[i].list[j].isCompleted == '0') {
  158. flag = true
  159. }
  160. //判断是否是SCL90的flag
  161. //如果是SCL的Flag则判断其完成状态
  162. //如果完成状态是0则正常开始
  163. //如果完成状态为1,则判断后边的到底有没有必做不显示但是其中有未完成的
  164. //如果完成状态为1,则判断后边的到底有没有必做不显示但是其中有未完成的
  165. }
  166. for (let j = 0; j < planList.value[i].list.length; j++) {
  167. //不需要展示--但是必做--且含有未完成的
  168. if (flag) {
  169. if (planList.value[i].list[j].flag == "20210617140713" && planList.value[i].list[j].isCompleted == "1") {
  170. //如果满足以上条件则scl90的状态切换为2 --也是未完成--但是预示着后边还有需要做的
  171. planList.value[i].list[j].isCompleted = '2'
  172. }
  173. }
  174. if (planList.value[i].list[j].contentType == '0' && planList.value[i].list[j].isAvailable == '1' && planList.value[i].list[j].isDisplayed == '1') {
  175. planList.value[i].scaleList.push(planList.value[i].list[j])
  176. }
  177. if (planList.value[i].list[j].contentType == '1' && planList.value[i].list[j].isAvailable == '1' && planList.value[i].list[j].isDisplayed == '1') {
  178. planList.value[i].taskList.push(planList.value[i].list[j])
  179. }
  180. //判断是否是SCL90的flag
  181. //如果是SCL的Flag则判断其完成状态
  182. //如果完成状态是0则正常开始
  183. //如果完成状态为1,则判断后边的到底有没有必做不显示但是其中有未完成的
  184. //如果完成状态为1,则判断后边的到底有没有必做不显示但是其中有未完成的
  185. }
  186. //判断是显示开始测试还是继续测试
  187. let isContinue = []
  188. isContinue = planList.value[i].list.filter((item: any) => {
  189. return item.isCompleted != '0'
  190. })
  191. if (isContinue.length == 0) {
  192. planList.value[i].isCompleted = '0'
  193. } else {
  194. planList.value[i].isCompleted = '2'
  195. }
  196. }
  197. }
  198. //判断是开始测试还好继续测试
  199. console.log("planList.value")
  200. console.log(planList.value)
  201. //数据格式改变抽出需要展示的量表、、放入数组
  202. //抽出需要展示的认知任务--放入数组
  203. }
  204. isFinshed.value = true
  205. }
  206. //刚进入页面就将高度设置为页面需要的
  207. onMounted(() => {
  208. //查询计划内容
  209. planNumGet()
  210. //进到界面开始轮询
  211. })
  212. //界面销毁函数
  213. //退出页面销毁 方法
  214. onUnmounted(() => {
  215. })
  216. </script>
  217. <template>
  218. <div class="home_header_out">
  219. <div class=" home_header_inner">
  220. <CpmdHeader />
  221. <div style="text-align: center;">
  222. <!-- <img class="xlts_img" style="margin-top:40px" src="../assets/home/other_text.png" /> -->
  223. </div>
  224. </div>
  225. <div class="kply">
  226. <div class="kply_inner">
  227. <div>
  228. <div style="padding: 20px 40px;" v-show="planList.length == 0 && isFinshed">
  229. <div style="padding:10% 20% ;" v-show="planList.length == 0 && isFinshed">
  230. <!-- <img width="100%" src="../assets/planNo.png"> -->
  231. <img width="60%" style="margin-left: 20%;" src="../assets/planNo.png">
  232. </div>
  233. </div>
  234. <div class="test_record_out" v-for="item in planList">
  235. <div class="record_tip">
  236. <span class="record_tip_out"><span class="record_tip_inner">创建时间:</span>{{ item.createTime
  237. }}</span>
  238. <span><span class="record_tip_inner">结束时间:</span>{{ item.planEndTime }}</span>
  239. </div>
  240. <div class="test_record">
  241. <img src="../assets/kepu/task_1.png" />
  242. <span>{{ item.planName }}</span>
  243. </div>
  244. <!-- <div class="test_time">
  245. <span>请根据您最近一个月的实际情况,选择最符合自己的选项。所有陈述都无正确和错误之分。所以请您不要再三思考,要根据第一反应诚实作答。</span>
  246. </div> -->
  247. <div class="content_out">
  248. <div class="content_inner">
  249. <div class="task_out">
  250. <div class="content_title">1.问答测试</div>
  251. <div class="task_inner">
  252. <div class="task_inner_single" v-for="subItem in item.scaleList"
  253. :key="subItem.id">
  254. <div class="task_inner_one">
  255. <img style="width: 80px;height: 80px"
  256. src="../assets/kepu/xlwht_active.png" alt="">
  257. <div class="task_content">
  258. <div class="title">{{ subItem.name }}</div>
  259. <div class="des" v-show="subItem.isCompleted != '1'">预计用时:{{
  260. subItem.expectTime }}</div>
  261. <div class="des" v-show="subItem.isCompleted == '1'">实际用时:{{
  262. subItem.useTime }}</div>
  263. <div class="noCompleted" v-show="subItem.isCompleted != '1'">
  264. <div class='noCompleted_status'> 未完成</div>
  265. </div>
  266. <div class="isCompleted" v-show="subItem.isCompleted == '1'">
  267. <div class='isCompleted_status'> 已完成</div>
  268. </div>
  269. </div>
  270. </div>
  271. </div>
  272. </div>
  273. </div>
  274. <div class="task_out">
  275. <div class="content_title">2.认知评估</div>
  276. <div class="task_inner">
  277. <div class="task_inner_single" v-for="subItem in item.taskList">
  278. <div class="task_inner_one">
  279. <img style="width: 80px;height: 80px"
  280. src="../assets/kepu/task_active.png" alt="">
  281. <div class="task_content">
  282. <div class="title">{{ subItem.name }}</div>
  283. <div class="des" v-show="subItem.isCompleted != '1'">预计用时:{{
  284. subItem.expectTime }}</div>
  285. <div class="des" v-show="subItem.isCompleted == '1'">实际用时:{{
  286. subItem.useTime }}</div>
  287. <div class="noCompleted" v-show="subItem.isCompleted != '1'">
  288. <div class='noCompleted_status'> 未完成</div>
  289. </div>
  290. <div class="isCompleted" v-show="subItem.isCompleted == '1'">
  291. <div class='isCompleted_status'> 已完成</div>
  292. </div>
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. </div>
  298. </div>
  299. <div></div>
  300. </div>
  301. <div class="start_button_out">
  302. <div class="start_button_self" @click="startPlan(item)"><span
  303. v-if="item.isCompleted == '0'">开始测试</span><span
  304. v-if="item.isCompleted == '2'">继续测试</span></div>
  305. </div>
  306. </div>
  307. <!-- 测试记录列表 -->
  308. </div>
  309. </div>
  310. </div>
  311. <CpmdQuestionnaire ref="question" @continueFun="continueFun" />
  312. </div>
  313. </template>
  314. <style lang="scss" scoped>
  315. .home_header_out {
  316. // position: relative;
  317. padding-bottom: 60px;
  318. width: 100%;
  319. min-width: 1200px;
  320. background-image: url('../assets/home/bg_ty.png');
  321. background-repeat: no-repeat;
  322. background-size: contain;
  323. background-color: #B3F1DA;
  324. //获取屏幕宽度home_header_out 这个div的宽度--然后宽度*1000再除1920即为当前div的宽度
  325. .home_header_inner {
  326. min-height: 1;
  327. left: 0;
  328. right: 0;
  329. margin: auto;
  330. // height: 100px;
  331. width: 1200px;
  332. .xlts_img {
  333. height: 60px;
  334. }
  335. }
  336. .kply {
  337. width: 100%;
  338. margin-top: 40px;
  339. // background-color: #FAFAFA;
  340. .kply_inner {
  341. // padding: 20px 20px;
  342. left: 0;
  343. right: 0;
  344. margin: auto;
  345. width: 1200px;
  346. min-height: 600px;
  347. background-color: #FAFAFA;
  348. border-radius: 40px;
  349. // height: 1000px;
  350. // margin-bottom: 60px;
  351. .kepu_title {
  352. display: flex;
  353. flex-direction: row;
  354. justify-content: space-between;
  355. align-items: center;
  356. .kepu_title_des {
  357. font-family: Alibaba PuHuiTi 2.0;
  358. font-weight: 600;
  359. font-size: 30px;
  360. color: #000000;
  361. }
  362. .home_mid_plan_button {
  363. width: 100%;
  364. display: flex;
  365. flex-direction: row;
  366. justify-content: end;
  367. // text-align: right;
  368. .pub_button {
  369. cursor: pointer;
  370. // width: 100px;
  371. border-radius: 12px;
  372. border: 3px solid #48D68E;
  373. color: #ffffff;
  374. background-color: #000000;
  375. padding: 8px 30px;
  376. cursor: pointer;
  377. display: flex;
  378. align-items: center;
  379. }
  380. }
  381. }
  382. .com_out {
  383. min-height: 500px;
  384. padding: 20px 20px;
  385. }
  386. .test_record {
  387. margin-top: 20px;
  388. display: flex;
  389. align-items: center;
  390. img {
  391. width: 50px;
  392. }
  393. span {
  394. margin-left: 20px;
  395. font-size: 22px;
  396. font-weight: 700;
  397. letter-spacing: 3px;
  398. }
  399. }
  400. .test_time {
  401. display: flex;
  402. flex-direction: row;
  403. justify-content: space-between;
  404. align-items: center;
  405. letter-spacing: 3px;
  406. line-height: 30px;
  407. span {
  408. color: #000000;
  409. opacity: 0.4;
  410. font-size: 18px;
  411. }
  412. div {
  413. cursor: pointer;
  414. // width: 100px;
  415. border-radius: 12px;
  416. border: 3px solid #48D68E;
  417. color: #ffffff;
  418. background-color: #000000;
  419. margin-right: 20px;
  420. padding: 8px 30px;
  421. cursor: pointer;
  422. display: flex;
  423. align-items: center;
  424. }
  425. }
  426. .record_out {
  427. margin-top: 30px;
  428. background-color: #F7F7F7;
  429. padding: 30px 40px;
  430. border-radius: 40px;
  431. display: flex;
  432. justify-content: center;
  433. align-items: center;
  434. .record_img_out {
  435. position: relative;
  436. .record_img_inner_name {
  437. position: absolute;
  438. margin-top: -150px;
  439. height: 100%;
  440. width: 100%;
  441. text-align: center;
  442. .test_des_name {
  443. font-weight: 700;
  444. color: #000000;
  445. font-size: 20px;
  446. letter-spacing: 3px;
  447. line-height: 15px;
  448. }
  449. }
  450. .record_img_inner {
  451. bottom: 0;
  452. margin-bottom: 10px;
  453. padding-left: 20px;
  454. width: 100%;
  455. position: absolute;
  456. display: flex;
  457. flex-direction: column;
  458. // background-color: #000000;
  459. justify-content: center;
  460. .test_des {
  461. color: #FEFFFE;
  462. font-size: 10px;
  463. line-height: 15px;
  464. .test_time1 {
  465. color: #ffffff;
  466. font-size: 10px;
  467. // line-height: 30px;
  468. line-height: 15px;
  469. }
  470. }
  471. .test_time1 {
  472. color: #ffffff;
  473. font-size: 10px;
  474. line-height: 15px;
  475. }
  476. }
  477. }
  478. .record_diceng {
  479. width: 80px;
  480. margin-left: 10px;
  481. margin-right: 10px;
  482. }
  483. .record_img {
  484. cursor: pointer;
  485. width: 180px;
  486. }
  487. }
  488. .start_button_out {
  489. margin-top: 40px;
  490. margin-bottom: 40px;
  491. display: flex;
  492. flex-direction: row;
  493. justify-content: end;
  494. .start_button_self {
  495. cursor: pointer;
  496. // width: 100px;
  497. border-radius: 12px;
  498. border: 3px solid #48D68E;
  499. color: #ffffff;
  500. background-color: #000000;
  501. margin-right: 20px;
  502. padding: 8px 60px;
  503. cursor: pointer;
  504. display: flex;
  505. align-items: center;
  506. }
  507. }
  508. .test_record_out {
  509. margin-top: 40px;
  510. padding: 20px 40px;
  511. background-color: #ffffff;
  512. border-radius: 40px;
  513. position: relative;
  514. .record_tip {
  515. background-color: #FFF6DF;
  516. position: absolute;
  517. right: 0;
  518. display: flex;
  519. flex-direction: column;
  520. top: 0;
  521. border-top-right-radius: 40px;
  522. border-bottom-left-radius: 40px;
  523. padding: 10px 40px;
  524. color: #FFB700;
  525. font-size: 14px;
  526. font-weight: 700;
  527. letter-spacing: 2px;
  528. .record_tip_inner {
  529. font-size: 13px;
  530. letter-spacing: 3px;
  531. }
  532. .record_tip_out {
  533. margin-bottom: 4px;
  534. .record_tip_inner {
  535. font-size: 13px;
  536. letter-spacing: 3px;
  537. }
  538. }
  539. }
  540. .content_out {
  541. display: flex;
  542. flex-direction: column;
  543. width: 100%;
  544. // height: 200px;
  545. background-color: #F7F7F7;
  546. border-radius: 40px;
  547. .content_inner {
  548. padding: 20px 40px;
  549. .content_title {
  550. margin-bottom: 0px;
  551. font-weight: 700;
  552. font-size: 20px;
  553. }
  554. .content_one {
  555. border-radius: 20px;
  556. // padding: 10px 20px;
  557. display: flex;
  558. background-color: #ffffff;
  559. width: 45%;
  560. align-items: center;
  561. .content_single {
  562. border-radius: 20px;
  563. padding: 10px 20px;
  564. display: flex;
  565. background-color: #ffffff;
  566. width: 45%;
  567. align-items: center;
  568. .content_detail {
  569. display: flex;
  570. margin-left: 15px;
  571. justify-content: start;
  572. height: 80px;
  573. flex-direction: column;
  574. .title {
  575. font-weight: 700;
  576. font-size: 18px;
  577. }
  578. .des {
  579. color: #999999;
  580. font-size: 14px;
  581. }
  582. }
  583. }
  584. }
  585. .task_out {
  586. margin-top: 20px;
  587. display: flex;
  588. flex-direction: column;
  589. .task_inner {
  590. display: flex;
  591. flex-direction: row;
  592. justify-content: space-between;
  593. flex-wrap: wrap;
  594. .task_inner_single {
  595. margin-top: 20px;
  596. height: 100px;
  597. border-radius: 20px;
  598. width: 45%;
  599. display: flex;
  600. flex-direction: row;
  601. background-color: #ffffff;
  602. align-items: center;
  603. .task_inner_one {
  604. padding: 10px 20px;
  605. border-radius: 20px;
  606. width: 100%;
  607. display: flex;
  608. flex-direction: row;
  609. background-color: #ffffff;
  610. align-items: center;
  611. .task_content {
  612. height: 80px;
  613. margin-left: 10px;
  614. display: flex;
  615. flex-direction: column;
  616. width: 100%;
  617. .title {
  618. font-weight: 700;
  619. font-size: 18px;
  620. width: 100%;
  621. letter-spacing: 2px;
  622. }
  623. .des {
  624. color: #999999;
  625. font-size: 14px;
  626. line-height: 24px;
  627. letter-spacing: 2px;
  628. }
  629. .noCompleted {
  630. width: 100%;
  631. color: #ffffff;
  632. display: flex;
  633. justify-content: end;
  634. .noCompleted_status {
  635. // font-weight: 600;
  636. color: #222222;
  637. line-height: 24px;
  638. font-size: 14px;
  639. border-radius: 20px;
  640. text-align: center;
  641. right: 0px;
  642. width: 70px;
  643. background-color: #EDEDED;
  644. }
  645. }
  646. .isCompleted {
  647. width: 100%;
  648. color: #ffffff;
  649. display: flex;
  650. justify-content: end;
  651. .isCompleted_status {
  652. line-height: 24px;
  653. font-size: 14px;
  654. border-radius: 20px;
  655. text-align: center;
  656. right: 0px;
  657. width: 70px;
  658. background-color: #48D68E;
  659. }
  660. }
  661. }
  662. }
  663. }
  664. }
  665. }
  666. }
  667. }
  668. }
  669. }
  670. }
  671. }
  672. </style>