index.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { defineComponent, onMounted, reactive, watch } from "vue";
  2. import styles from "./index.module.less";
  3. // import { verifyMembershipServices } from "../vip-verify";
  4. import { api_lessonTrainingSubmitTraining, api_lessonTrainingTrainingStudentDetail, api_submitTrainingTime } from "../../api";
  5. import state, { handleSetSpeed, hanldeDirectSelection, setSection, togglePlay } from "/src/state";
  6. import { getSecondRPM } from "/src/utils";
  7. import { headImg } from "/src/page-instrument/header-top/image";
  8. export default defineComponent({
  9. name: "HomeWork",
  10. props: {
  11. workeData: {
  12. type: Object,
  13. default: () => ({}),
  14. }
  15. },
  16. emits: ["change"],
  17. setup(props, {expose}) {
  18. const training = reactive({
  19. trainingTimes: "", // 已经练习的时长,单位分钟
  20. trainingSpeed: 0, // 作业规定的速度
  21. times: 0, // 作业规定的练习时长,单位分钟
  22. trainingTimeSecond: 0, // 实时更新的练习时长,单位秒
  23. workRecord: "",
  24. isAddOk: 0,
  25. starTime: 0,
  26. start: "" as any,
  27. end: "" as any,
  28. timer: null as any, // 定时器
  29. realThisTimeTotal: 0, // 达标的本次练习时长
  30. trainingStatus: "UNSUBMITTED" as any, // 作业状态
  31. });
  32. /** 隐藏评测功能 */
  33. const handleHide = () => {
  34. const ids = ["studnetT-0", "studnetT-2", "studnetT-4"];
  35. for (let i = 0; i < ids.length; i++) {
  36. const speedBtn = document.getElementById(ids[i]);
  37. if (speedBtn) {
  38. speedBtn.style.pointerEvents = "none";
  39. speedBtn.style.opacity = ".5";
  40. }
  41. }
  42. };
  43. /** 获取作业详情 */
  44. const getWorkData = async (resourceType?: string) => {
  45. const workeData = props.workeData;
  46. if (workeData.id) {
  47. let trainingContent: any = {};
  48. try {
  49. trainingContent = JSON.parse(workeData.trainingContent);
  50. } catch (error) {
  51. console.log("🚀 ~ error:", error);
  52. }
  53. training.trainingStatus = workeData.trainingStatus || "UNSUBMITTED";
  54. training.times = trainingContent.trainingTimes || 0;
  55. training.trainingTimes = (workeData.trainingTimes / 60).toFixed(1) || "0";
  56. if (!resourceType) {
  57. training.trainingTimeSecond = workeData.trainingTimes || 0;
  58. }
  59. training.trainingSpeed = trainingContent.practiceSpeed;
  60. training.start = Number(trainingContent.practiceChapterBegin);
  61. training.end = Number(trainingContent.practiceChapterEnd);
  62. state.userChooseEndIndex = training.end
  63. state.isWorkDone = Number(training.trainingTimes) >= Number(training.times);
  64. if (training.isAddOk === 0) {
  65. // 设置小节
  66. setSection(training.start, training.end, training.trainingSpeed);
  67. }
  68. // 来自刷新谱面
  69. if (resourceType === 'refresh') {
  70. getWorkDetail()
  71. }
  72. }
  73. };
  74. const getWorkDetail = async () => {
  75. const res = await api_lessonTrainingTrainingStudentDetail(props.workeData.id);
  76. if (res?.code === 200) {
  77. training.trainingTimes = (res.data.trainingTimes / 60).toFixed(1) || "0";
  78. training.trainingTimeSecond = res.data.trainingTimes || 0;
  79. training.trainingStatus = res.data.trainingStatus;
  80. state.isWorkDone = Number(training.trainingTimes) >= Number(training.times) && res.data.trainingStatus === 'TARGET';
  81. }
  82. };
  83. /** 添加作业记录 */
  84. const addHomeworkRecored = async (extraType?: string) => {
  85. let total = extraType === 'save' ? training.realThisTimeTotal : Math.floor((Date.now() - training.starTime) / 1000);
  86. try {
  87. let params: any = {
  88. id: props.workeData.id,
  89. trainingTimes: total,
  90. }
  91. // 如果已达标,手动保存作业时,需要添加submitFlag参数
  92. if (extraType === 'save') {
  93. params = {
  94. id: props.workeData.id,
  95. submitFlag: true
  96. }
  97. }
  98. const res = extraType === 'save' ? await api_lessonTrainingSubmitTraining(params) : await api_submitTrainingTime(params);
  99. if (res?.code == 200) {
  100. getWorkDetail();
  101. training.starTime = Date.now();
  102. }
  103. } catch (error) {}
  104. };
  105. const handleStart = () => {
  106. training.timer = setInterval(() => {
  107. training.trainingTimeSecond += 1;
  108. // console.log('练习时长',training.trainingTimeSecond)
  109. }, 1000);
  110. };
  111. const handleStop = () => {
  112. clearInterval(training.timer)
  113. }
  114. watch(
  115. () => state.playState,
  116. () => {
  117. if (state.playState === "play") {
  118. training.starTime = Date.now();
  119. handleStart();
  120. } else {
  121. // 没有达标停止播放时,需要自动提交练习时长
  122. // if (!state.showWorkDonePop) {
  123. // addHomeworkRecored();
  124. // }
  125. addHomeworkRecored();
  126. handleStop();
  127. }
  128. }
  129. );
  130. watch(
  131. () => state.showWorkDonePop,
  132. () => {
  133. if (state.showWorkDonePop && state.playState === "play") {
  134. togglePlay("paused")
  135. }
  136. }
  137. );
  138. watch(
  139. () => training.trainingTimeSecond,
  140. () => {
  141. // console.log('累积时间',111,state.isWorkDone,training.trainingTimeSecond,training.times * 60)
  142. // 如果播放中,作业从未达标到达标状态,需要暂停播放,并且弹窗提示作业已达标
  143. if (training.trainingStatus !== 'TARGET' && (!state.isWorkDone && training.trainingTimeSecond >= training.times * 60 || (state.isWorkDone && training.trainingTimeSecond === training.times * 60)) ) {
  144. // training.realThisTimeTotal = state.isWorkDone && training.trainingTimeSecond === training.times * 60 ? 0 : Math.ceil((Date.now() - training.starTime) / 1000);
  145. training.realThisTimeTotal = Math.floor((Date.now() - training.starTime) / 1000);
  146. state.isWorkDone = true
  147. togglePlay("paused")
  148. if (training.starTime === 0) {
  149. setTimeout(() => {
  150. state.showWorkDonePop = true
  151. }, 1500);
  152. } else {
  153. state.showWorkDonePop = true
  154. }
  155. }
  156. }
  157. );
  158. const handleAdd = () => {
  159. if (state.playState === "play") {
  160. console.log("退出");
  161. addHomeworkRecored();
  162. }
  163. }
  164. onMounted(() => {
  165. handleHide();
  166. getWorkData();
  167. // verifyMembershipServices();
  168. });
  169. expose({
  170. handleAdd,
  171. getWorkData
  172. })
  173. return () => (
  174. <>
  175. <div class={styles.homework}>
  176. <i class={state.playState === "play" ? styles.blinkDot : styles.grayDot}></i>
  177. <span>{getSecondRPM(training.trainingTimeSecond)} / {getSecondRPM(training.times*60)}</span>
  178. </div>
  179. {
  180. state.showWorkDonePop &&
  181. <div class={styles.workDonePop}>
  182. <img class={styles.doneBg} src={headImg("workDonePop.png")} />
  183. <img class={styles.doneBtn} src={headImg("workDoneBtn.png")} onClick={() => {
  184. state.showWorkDonePop = false
  185. addHomeworkRecored('save');
  186. }} />
  187. </div>
  188. }
  189. </>
  190. );
  191. },
  192. });