countdown.vue 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876
  1. <template>
  2. <div class="countdown">
  3. <div class="c_timeBox" v-if="showType == 0">
  4. <div class="c_tb_top">
  5. <div class="c_time">
  6. <div class="c_t_item" v-if="type == 0">
  7. <div class="c_t_i_card">
  8. <div>
  9. <span class="c_t_i_btnTop" v-if="!isCountdown"
  10. ><el-button class="c_t_i_btn" @click.stop="addTime(600)"
  11. >+</el-button
  12. ></span
  13. >
  14. <div>{{ countdownTimeShow.m1 }}</div>
  15. <span class="c_t_i_btnBottom" v-if="!isCountdown"
  16. ><el-button class="c_t_i_btn" @click.stop="reduceTime(600)"
  17. >-</el-button
  18. ></span
  19. >
  20. </div>
  21. <div>
  22. <span class="c_t_i_btnTop" v-if="!isCountdown"
  23. ><el-button class="c_t_i_btn" @click.stop="addTime(60)"
  24. >+</el-button
  25. ></span
  26. >
  27. <div>{{ countdownTimeShow.m2 }}</div>
  28. <span class="c_t_i_btnBottom" v-if="!isCountdown"
  29. ><el-button class="c_t_i_btn" @click.stop="reduceTime(60)"
  30. >-</el-button
  31. ></span
  32. >
  33. </div>
  34. <span>分</span>
  35. </div>
  36. <div class="c_t_i_card">
  37. <div>
  38. <span class="c_t_i_btnTop" v-if="!isCountdown"
  39. ><el-button class="c_t_i_btn" @click.stop="addTime(10)"
  40. >+</el-button
  41. ></span
  42. >
  43. <div>{{ countdownTimeShow.s1 }}</div>
  44. <span class="c_t_i_btnBottom" v-if="!isCountdown"
  45. ><el-button class="c_t_i_btn" @click.stop="reduceTime(10)"
  46. >-</el-button
  47. ></span
  48. >
  49. </div>
  50. <div>
  51. <span class="c_t_i_btnTop" v-if="!isCountdown"
  52. ><el-button class="c_t_i_btn" @click.stop="addTime(1)"
  53. >+</el-button
  54. ></span
  55. >
  56. <div>{{ countdownTimeShow.s2 }}</div>
  57. <span class="c_t_i_btnBottom" v-if="!isCountdown"
  58. ><el-button class="c_t_i_btn" @click.stop="reduceTime(1)"
  59. >-</el-button
  60. ></span
  61. >
  62. </div>
  63. <span>秒</span>
  64. </div>
  65. </div>
  66. <div class="c_t_item" v-if="type == 1">
  67. <div class="c_t_i_card">
  68. <div>
  69. <div>{{ keepTimeShow.m1 }}</div>
  70. </div>
  71. <div>
  72. <div>{{ keepTimeShow.m2 }}</div>
  73. </div>
  74. <span>分</span>
  75. </div>
  76. <div class="c_t_i_card">
  77. <div>
  78. <div>{{ keepTimeShow.s1 }}</div>
  79. </div>
  80. <div>
  81. <div>{{ keepTimeShow.s2 }}</div>
  82. </div>
  83. <span>秒</span>
  84. </div>
  85. </div>
  86. </div>
  87. <div class="c_choiceTime" v-if="type == 0">
  88. <div class="c_title">
  89. <span>快捷设置</span>
  90. </div>
  91. <div class="c_ct_box">
  92. <span @click.stop="setCountdownTime(30)">30秒</span>
  93. <span @click.stop="setCountdownTime(60)">1分钟</span>
  94. <span @click.stop="setCountdownTime(120)">2分钟</span>
  95. <span @click.stop="setCountdownTime(180)">3分钟</span>
  96. <span @click.stop="setCountdownTime(300)">5分钟</span>
  97. <span @click.stop="setCountdownTime(360)">6分钟</span>
  98. <span @click.stop="setCountdownTime(480)">8分钟</span>
  99. <span @click.stop="setCountdownTime(600)">10分钟</span>
  100. </div>
  101. </div>
  102. <div class="c_behaviorTag">
  103. <div class="c_title">
  104. <span>行为标签</span>
  105. <div class="c_t_btnArea">
  106. <span
  107. @click.stop="changeBehaviorTagType(0)"
  108. :class="[behaviorTagType == 0 ? 'c_t_ba_active' : '']"
  109. >常用</span
  110. >
  111. <span
  112. @click.stop="changeBehaviorTagType(1)"
  113. :class="[behaviorTagType == 1 ? 'c_t_ba_active' : '']"
  114. >更多</span
  115. >
  116. <!-- <el-button-group>
  117. <el-button
  118. size="mini"
  119. :disabled="isCountdown || isKeepTime"
  120. :type="behaviorTagType == 0 ? 'primary' : 'info'"
  121. @click.stop="changeBehaviorTagType(0)"
  122. >
  123. 常用
  124. </el-button>
  125. <el-button
  126. size="mini"
  127. :disabled="isCountdown || isKeepTime"
  128. :type="behaviorTagType == 1 ? 'primary' : 'info'"
  129. @click.stop="changeBehaviorTagType(1)"
  130. >
  131. 更多
  132. </el-button>
  133. </el-button-group> -->
  134. </div>
  135. </div>
  136. <div
  137. class="c_bt_box"
  138. v-loading="behaviorTagMoreLoading && behaviorTagType == 1"
  139. >
  140. <span
  141. v-if="behaviorTagType == 1"
  142. :class="[choiceBehavior.includes(item) ? 'c_bt_b_active' : '']"
  143. v-for="(item, index) in behaviorTagMore"
  144. @click.stop="choiceBehaviorTag(item)"
  145. :key="behaviorTagType + '-' + index"
  146. >{{ item }}</span
  147. >
  148. <span
  149. v-if="behaviorTagType == 0"
  150. :class="[choiceBehavior.includes(item) ? 'c_bt_b_active' : '']"
  151. v-for="(item, index) in behaviorTagCommon"
  152. @click.stop="choiceBehaviorTag(item)"
  153. :key="behaviorTagType + '-' + index"
  154. >{{ item }}</span
  155. >
  156. </div>
  157. </div>
  158. <div class="c_btnArea">
  159. <span @click.stop="music()">
  160. <el-tooltip
  161. class="item"
  162. effect="light"
  163. :content="sourceActive ? '关闭音乐' : '开启音乐'"
  164. placement="top"
  165. >
  166. <svg
  167. width="24"
  168. height="24"
  169. viewBox="0 0 24 24"
  170. fill="none"
  171. xmlns="http://www.w3.org/2000/svg"
  172. >
  173. <path
  174. fill-rule="evenodd"
  175. clip-rule="evenodd"
  176. d="M12.0001 3.18362C7.13095 3.18362 3.18374 7.13083 3.18374 11.9999C3.18374 16.4071 6.41825 20.0602 10.6428 20.7125C11.0848 20.7808 11.5381 20.8163 12.0001 20.8163C12.4058 20.8163 12.7348 21.1452 12.7348 21.551C12.7348 21.9567 12.4058 22.2857 12.0001 22.2857C11.4627 22.2857 10.9345 22.2444 10.4186 22.1647C5.48856 21.4035 1.71436 17.1431 1.71436 11.9999C1.71436 6.3193 6.31943 1.71423 12.0001 1.71423C16.5776 1.71423 20.4549 4.70396 21.7896 8.83532C22.1119 9.83321 22.2858 10.897 22.2858 11.9999C22.2858 12.4057 21.9569 12.7346 21.5511 12.7346C21.1453 12.7346 20.8164 12.4057 20.8164 11.9999C20.8164 11.0522 20.6671 10.1407 20.3913 9.28702C19.2469 5.74447 15.9216 3.18362 12.0001 3.18362Z"
  177. :fill="sourceActive ? '#E11E1E' : 'black'"
  178. fill-opacity="0.9"
  179. />
  180. <path
  181. fill-rule="evenodd"
  182. clip-rule="evenodd"
  183. d="M22.0162 13.8835C22.1871 14.0192 22.2856 14.2186 22.2856 14.4285V20.1428C22.2856 20.3322 22.2053 20.5139 22.0625 20.6479L21.3005 21.3622C21.003 21.6411 20.5206 21.6411 20.2231 21.3622C19.9255 21.0832 19.9255 20.631 20.2231 20.352L20.7618 19.8469V15.2717L17.7142 15.7479V20.8571C17.7142 21.0465 17.6339 21.2282 17.491 21.3622L16.7291 22.0765C16.4316 22.3554 15.9492 22.3554 15.6516 22.0765C15.3541 21.7975 15.3541 21.3452 15.6516 21.0663L16.1904 20.5612V15.1428C16.1904 14.7936 16.4596 14.4956 16.827 14.4382L21.3984 13.724C21.6194 13.6894 21.8453 13.7478 22.0162 13.8835Z"
  184. :fill="sourceActive ? '#E11E1E' : '#3681FC'"
  185. />
  186. <path
  187. d="M14.5713 12C14.5713 13.4202 13.4201 14.5714 11.9999 14.5714C10.5797 14.5714 9.42847 13.4202 9.42847 12C9.42847 10.5799 10.5797 9.42859 11.9999 9.42859C13.4201 9.42859 14.5713 10.5799 14.5713 12Z"
  188. :fill="sourceActive ? '#E11E1E' : 'black'"
  189. fill-opacity="0.9"
  190. />
  191. </svg>
  192. </el-tooltip>
  193. </span>
  194. <div class="c_ba_startArea">
  195. <div
  196. :class="[
  197. !canStartCountdownTime
  198. ? 'c_ba_startType0'
  199. : !isCountdown
  200. ? 'c_ba_startType'
  201. : 'c_ba_startType2',
  202. ]"
  203. v-if="type == 0"
  204. style=""
  205. @click.stop="countdownTimeFn()"
  206. >
  207. <svg
  208. v-if="!isCountdown"
  209. t="1721117381559"
  210. viewBox="0 0 1024 1024"
  211. version="1.1"
  212. xmlns="http://www.w3.org/2000/svg"
  213. p-id="12941"
  214. width="64"
  215. height="64"
  216. >
  217. <path
  218. d="M161.2 839.9v-654c0-56.1 60.7-91.1 109.3-63.1l566.3 327c48.6 28 48.6 98.1 0 126.2L270.4 903c-48.5 28-109.2-7.1-109.2-63.1z"
  219. p-id="12942"
  220. ></path>
  221. </svg>
  222. <svg
  223. v-else
  224. t="1721198913879"
  225. class="icon"
  226. viewBox="0 0 1024 1024"
  227. version="1.1"
  228. xmlns="http://www.w3.org/2000/svg"
  229. p-id="4266"
  230. width="64"
  231. height="64"
  232. >
  233. <path
  234. d="M426.666667 138.666667v746.666666a53.393333 53.393333 0 0 1-53.333334 53.333334H266.666667a53.393333 53.393333 0 0 1-53.333334-53.333334V138.666667a53.393333 53.393333 0 0 1 53.333334-53.333334h106.666666a53.393333 53.393333 0 0 1 53.333334 53.333334z m330.666666-53.333334H650.666667a53.393333 53.393333 0 0 0-53.333334 53.333334v746.666666a53.393333 53.393333 0 0 0 53.333334 53.333334h106.666666a53.393333 53.393333 0 0 0 53.333334-53.333334V138.666667a53.393333 53.393333 0 0 0-53.333334-53.333334z"
  235. p-id="4267"
  236. ></path>
  237. </svg>
  238. <!-- <svg v-else t="1721117616634" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13970" width="64" height="64"><path d="M128 128m53.333333 0l661.333334 0q53.333333 0 53.333333 53.333333l0 661.333334q0 53.333333-53.333333 53.333333l-661.333334 0q-53.333333 0-53.333333-53.333333l0-661.333334q0-53.333333 53.333333-53.333333Z" p-id="13971"></path></svg> -->
  239. </div>
  240. <div
  241. :class="[!isKeepTime ? 'c_ba_startType' : 'c_ba_startType2']"
  242. v-if="type == 1"
  243. @click.stop="keepTimeFn()"
  244. >
  245. <svg
  246. v-if="!isKeepTime"
  247. t="1721117381559"
  248. viewBox="0 0 1024 1024"
  249. version="1.1"
  250. xmlns="http://www.w3.org/2000/svg"
  251. p-id="12941"
  252. width="64"
  253. height="64"
  254. >
  255. <path
  256. d="M161.2 839.9v-654c0-56.1 60.7-91.1 109.3-63.1l566.3 327c48.6 28 48.6 98.1 0 126.2L270.4 903c-48.5 28-109.2-7.1-109.2-63.1z"
  257. p-id="12942"
  258. ></path>
  259. </svg>
  260. <svg
  261. v-else
  262. t="1721198913879"
  263. class="icon"
  264. viewBox="0 0 1024 1024"
  265. version="1.1"
  266. xmlns="http://www.w3.org/2000/svg"
  267. p-id="4266"
  268. width="64"
  269. height="64"
  270. >
  271. <path
  272. d="M426.666667 138.666667v746.666666a53.393333 53.393333 0 0 1-53.333334 53.333334H266.666667a53.393333 53.393333 0 0 1-53.333334-53.333334V138.666667a53.393333 53.393333 0 0 1 53.333334-53.333334h106.666666a53.393333 53.393333 0 0 1 53.333334 53.333334z m330.666666-53.333334H650.666667a53.393333 53.393333 0 0 0-53.333334 53.333334v746.666666a53.393333 53.393333 0 0 0 53.333334 53.333334h106.666666a53.393333 53.393333 0 0 0 53.333334-53.333334V138.666667a53.393333 53.393333 0 0 0-53.333334-53.333334z"
  273. p-id="4267"
  274. ></path>
  275. </svg>
  276. <!-- <svg v-else t="1721117616634" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13970" width="64" height="64"><path d="M128 128m53.333333 0l661.333334 0q53.333333 0 53.333333 53.333333l0 661.333334q0 53.333333-53.333333 53.333333l-661.333334 0q-53.333333 0-53.333333-53.333333l0-661.333334q0-53.333333 53.333333-53.333333Z" p-id="13971"></path></svg> -->
  277. </div>
  278. </div>
  279. <span @click.stop="reset()">
  280. <el-tooltip
  281. class="item"
  282. effect="light"
  283. content="重置"
  284. placement="top"
  285. >
  286. <svg
  287. width="24"
  288. height="24"
  289. viewBox="0 0 24 24"
  290. fill="none"
  291. xmlns="http://www.w3.org/2000/svg"
  292. >
  293. <path
  294. fill-rule="evenodd"
  295. clip-rule="evenodd"
  296. d="M2.25 19.5C2.25 19.0858 2.58579 18.75 3 18.75H22.5C22.9142 18.75 23.25 19.0858 23.25 19.5C23.25 19.9142 22.9142 20.25 22.5 20.25H3C2.58579 20.25 2.25 19.9142 2.25 19.5Z"
  297. fill="black"
  298. />
  299. <path d="M3 8.25L3.75 14.25L8.25 10.5L3 8.25Z" fill="black" />
  300. <path
  301. fill-rule="evenodd"
  302. clip-rule="evenodd"
  303. d="M6.88061 9.09714C8.37158 7.62191 10.4445 6.75 12.75 6.75C17.3064 6.75 21 10.4437 21 15C21 15.4142 21.3358 15.75 21.75 15.75C22.1643 15.75 22.5 15.4142 22.5 15C22.5 9.61522 18.1348 5.25 12.75 5.25C9.83406 5.25 7.20333 6.45088 5.41113 8.46737L3.29545 7.56065C3.04847 7.4548 2.76374 7.48917 2.54904 7.65074C2.33433 7.81231 2.22247 8.0764 2.2558 8.34303L3.0058 14.343C3.03982 14.6151 3.21963 14.847 3.47471 14.9477C3.7298 15.0483 4.01948 15.0017 4.23015 14.8262L8.73015 11.0762C8.93061 10.9091 9.02983 10.6499 8.99215 10.3917C8.95447 10.1335 8.78529 9.91343 8.54545 9.81065L6.88061 9.09714ZM4.48437 9.70214L3.9064 9.45443L4.03677 10.4974C4.17389 10.2236 4.32334 9.95829 4.48437 9.70214ZM4.91452 12.3033C5.14843 11.5796 5.47638 10.9088 5.884 10.302L6.82973 10.7073L4.91452 12.3033Z"
  304. fill="black"
  305. />
  306. </svg>
  307. </el-tooltip>
  308. </span>
  309. </div>
  310. <div class="ActivityMemo">
  311. <span @click.stop="changeShowType(1)">
  312. 教学活动备忘
  313. <svg
  314. width="16"
  315. height="16"
  316. viewBox="0 0 16 16"
  317. fill="none"
  318. xmlns="http://www.w3.org/2000/svg"
  319. >
  320. <path
  321. fill-rule="evenodd"
  322. clip-rule="evenodd"
  323. d="M3.66782 3.1263C3.87421 2.94284 4.19025 2.96143 4.37371 3.16782L8.37371 7.66782C8.5421 7.85727 8.5421 8.14274 8.37371 8.33219L4.37371 12.8322C4.19025 13.0386 3.87421 13.0572 3.66782 12.8737C3.46143 12.6903 3.44284 12.3742 3.6263 12.1678L7.33103 8.00001L3.6263 3.83219C3.44284 3.6258 3.46143 3.30976 3.66782 3.1263Z"
  324. fill="black"
  325. />
  326. <path
  327. fill-rule="evenodd"
  328. clip-rule="evenodd"
  329. d="M7.66782 3.1263C7.87421 2.94284 8.19025 2.96143 8.37371 3.16782L12.3737 7.66782C12.5421 7.85727 12.5421 8.14274 12.3737 8.33219L8.37371 12.8322C8.19025 13.0386 7.87421 13.0572 7.66782 12.8737C7.46143 12.6903 7.44284 12.3742 7.6263 12.1678L11.331 8.00001L7.6263 3.83219C7.44284 3.6258 7.46143 3.30976 7.66782 3.1263Z"
  330. fill="black"
  331. />
  332. </svg>
  333. </span>
  334. </div>
  335. </div>
  336. <div class="c_changeType">
  337. <div class="c_ct_btn" @click.stop="changeType(0)">
  338. <div>倒计时</div>
  339. <span v-if="type == 0"></span>
  340. <svg
  341. width="21"
  342. height="6"
  343. viewBox="0 0 21 6"
  344. fill="none"
  345. xmlns="http://www.w3.org/2000/svg"
  346. v-if="type == 0"
  347. >
  348. <path
  349. fill-rule="evenodd"
  350. clip-rule="evenodd"
  351. d="M1.05713 0.470583C1.80179 -0.155333 3.01121 -0.157081 3.75845 0.466679C5.4879 1.91035 7.86809 2.8 10.5 2.8C13.1319 2.8 15.5121 1.91035 17.2416 0.466679C17.9888 -0.157081 19.1982 -0.155333 19.9429 0.470583C20.6875 1.0965 20.6854 2.10956 19.9382 2.73332C17.5219 4.75032 14.1834 6 10.5 6C6.81664 6 3.47806 4.75032 1.06179 2.73332C0.314559 2.10956 0.312473 1.0965 1.05713 0.470583Z"
  352. fill="url(#paint0_linear_269_7318)"
  353. />
  354. <defs>
  355. <linearGradient
  356. id="paint0_linear_269_7318"
  357. x1="0.5"
  358. y1="6"
  359. x2="20.5"
  360. y2="6"
  361. gradientUnits="userSpaceOnUse"
  362. >
  363. <stop stop-color="#3673E8" />
  364. <stop offset="1" stop-color="#AD88FD" />
  365. </linearGradient>
  366. </defs>
  367. </svg>
  368. </div>
  369. <span></span>
  370. <div class="c_ct_btn" @click.stop="changeType(1)">
  371. <div>计时器</div>
  372. <span v-if="type == 1"></span>
  373. <svg
  374. width="21"
  375. height="6"
  376. viewBox="0 0 21 6"
  377. fill="none"
  378. xmlns="http://www.w3.org/2000/svg"
  379. v-if="type == 1"
  380. >
  381. <path
  382. fill-rule="evenodd"
  383. clip-rule="evenodd"
  384. d="M1.05713 0.470583C1.80179 -0.155333 3.01121 -0.157081 3.75845 0.466679C5.4879 1.91035 7.86809 2.8 10.5 2.8C13.1319 2.8 15.5121 1.91035 17.2416 0.466679C17.9888 -0.157081 19.1982 -0.155333 19.9429 0.470583C20.6875 1.0965 20.6854 2.10956 19.9382 2.73332C17.5219 4.75032 14.1834 6 10.5 6C6.81664 6 3.47806 4.75032 1.06179 2.73332C0.314559 2.10956 0.312473 1.0965 1.05713 0.470583Z"
  385. fill="url(#paint0_linear_269_7318)"
  386. />
  387. <defs>
  388. <linearGradient
  389. id="paint0_linear_269_7318"
  390. x1="0.5"
  391. y1="6"
  392. x2="20.5"
  393. y2="6"
  394. gradientUnits="userSpaceOnUse"
  395. >
  396. <stop stop-color="#3673E8" />
  397. <stop offset="1" stop-color="#AD88FD" />
  398. </linearGradient>
  399. </defs>
  400. </svg>
  401. </div>
  402. <!-- <el-button-group>
  403. <el-button
  404. :type="isCountdown ? 'danger' : type == 0 ? 'primary' : ''"
  405. @click.stop="changeType(0)"
  406. :disabled="isCountdown || isKeepTime"
  407. >
  408. 倒计时
  409. </el-button>
  410. <el-button
  411. :type="isKeepTime ? 'danger' : type == 1 ? 'primary' : ''"
  412. @click.stop="changeType(1)"
  413. :disabled="isCountdown || isKeepTime"
  414. >
  415. 计时器
  416. </el-button>
  417. </el-button-group> -->
  418. </div>
  419. </div>
  420. <div class="c_behavior" v-if="showType == 1">
  421. <div class="behaviorBack">
  422. <span @click.stop="changeShowType(0)">
  423. <svg
  424. width="16"
  425. height="16"
  426. viewBox="0 0 16 16"
  427. fill="none"
  428. xmlns="http://www.w3.org/2000/svg"
  429. >
  430. <path
  431. fill-rule="evenodd"
  432. clip-rule="evenodd"
  433. d="M3.66782 3.1263C3.87421 2.94284 4.19025 2.96143 4.37371 3.16782L8.37371 7.66782C8.5421 7.85727 8.5421 8.14274 8.37371 8.33219L4.37371 12.8322C4.19025 13.0386 3.87421 13.0572 3.66782 12.8737C3.46143 12.6903 3.44284 12.3742 3.6263 12.1678L7.33103 8.00001L3.6263 3.83219C3.44284 3.6258 3.46143 3.30976 3.66782 3.1263Z"
  434. fill="black"
  435. />
  436. <path
  437. fill-rule="evenodd"
  438. clip-rule="evenodd"
  439. d="M7.66782 3.1263C7.87421 2.94284 8.19025 2.96143 8.37371 3.16782L12.3737 7.66782C12.5421 7.85727 12.5421 8.14274 12.3737 8.33219L8.37371 12.8322C8.19025 13.0386 7.87421 13.0572 7.66782 12.8737C7.46143 12.6903 7.44284 12.3742 7.6263 12.1678L11.331 8.00001L7.6263 3.83219C7.44284 3.6258 7.46143 3.30976 7.66782 3.1263Z"
  440. fill="black"
  441. /></svg
  442. >返回</span
  443. >
  444. </div>
  445. <div class="c_step" ref="stepRef" v-loading="memorandumLoading">
  446. <el-timeline>
  447. <el-timeline-item
  448. v-for="(item, index) in showMemorandumList"
  449. :class="item.color"
  450. :key="index"
  451. :timestamp="item.time"
  452. size="large"
  453. >
  454. <span v-html="item.textList.join(',')"></span>
  455. </el-timeline-item>
  456. </el-timeline>
  457. </div>
  458. </div>
  459. <mini-audio
  460. v-show="false"
  461. ref="audioRef"
  462. :loop="true"
  463. :audio-source="sourceUrl"
  464. ></mini-audio>
  465. <mini-audio
  466. v-show="false"
  467. ref="endSourceUrlRef"
  468. :loop="false"
  469. :audio-source="endSourceUrl"
  470. ></mini-audio>
  471. </div>
  472. </template>
  473. <script>
  474. import { v4 as uuidv4 } from "uuid";
  475. export default {
  476. props: {
  477. courseDetail: {
  478. type: Object,
  479. default: () => {},
  480. },
  481. fileId: {
  482. type: Array,
  483. default: () => [],
  484. },
  485. },
  486. data() {
  487. return {
  488. userid: this.$route.query.userid,
  489. courseId: this.$route.query.courseId,
  490. tcid2: this.$route.query.tcid,
  491. showType: 0,
  492. sourceUrl:
  493. "https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E5%80%92%E8%AE%A1%E6%97%B6%E9%9F%B3%E4%B9%901721355956636.mp3",
  494. endSourceUrl:
  495. "https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E5%80%92%E6%95%B010%E7%A7%92%E5%8F%A0%E5%8A%A0%E9%9F%B3%E6%95%881721638403882.MP3",
  496. sourceActive: false,
  497. type: 0, //0:倒计时 1:计时器
  498. isCountdown: false,
  499. isKeepTime: false,
  500. countdownTime: 0,
  501. countdownTimeDefault: 0,
  502. countdownTimeTimer: null,
  503. keepTime: 0,
  504. keepTimeTimer: null,
  505. startCountdownTime: 0,
  506. behaviorTagType: 0, //0:常用 1:更多
  507. behaviorTagMore: [], //更多
  508. behaviorTagMoreLoading: false,
  509. behaviorTagCommon: [
  510. "小组讨论",
  511. "小组汇报",
  512. "动手实验",
  513. "课堂游戏",
  514. "自主学习",
  515. "作品展示",
  516. "学生演讲",
  517. "学生分享",
  518. "随堂练习",
  519. "快速问答",
  520. "阅读资料",
  521. "观察记录",
  522. ], //常用
  523. choiceBehavior: [],
  524. memorandumList: [],
  525. memorandumLoading: false,
  526. };
  527. },
  528. computed: {
  529. canStartCountdownTime() {
  530. let _result = false;
  531. if (this.countdownTime > 0) {
  532. _result = true;
  533. }
  534. return _result;
  535. },
  536. countdownTimeShow() {
  537. let _result = {
  538. m1: 0,
  539. m2: 0,
  540. s1: 0,
  541. s2: 0,
  542. };
  543. if (this.countdownTime <= 0) return _result;
  544. let minutes = Math.floor(this.countdownTime / 60);
  545. let seconds = this.countdownTime % 60;
  546. if (minutes > 9) {
  547. _result.m1 = Math.floor(minutes / 10);
  548. _result.m2 = minutes % 10;
  549. } else {
  550. _result.m1 = 0;
  551. _result.m2 = minutes;
  552. }
  553. if (seconds > 9) {
  554. _result.s1 = Math.floor(seconds / 10);
  555. _result.s2 = seconds % 10;
  556. } else {
  557. _result.s1 = 0;
  558. _result.s2 = seconds;
  559. }
  560. return _result;
  561. },
  562. keepTimeShow() {
  563. let _result = {
  564. m1: 0,
  565. m2: 0,
  566. s1: 0,
  567. s2: 0,
  568. };
  569. if (this.keepTime <= 0) return _result;
  570. let minutes = Math.floor(this.keepTime / 60);
  571. let seconds = this.keepTime % 60;
  572. if (minutes > 9) {
  573. _result.m1 = Math.floor(minutes / 10);
  574. _result.m2 = minutes % 10;
  575. } else {
  576. _result.m1 = 0;
  577. _result.m2 = minutes;
  578. }
  579. if (seconds > 9) {
  580. _result.s1 = Math.floor(seconds / 10);
  581. _result.s2 = seconds % 10;
  582. } else {
  583. _result.s1 = 0;
  584. _result.s2 = seconds;
  585. }
  586. return _result;
  587. },
  588. showMemorandumList() {
  589. let _result = [];
  590. let _time1 = ""; //_interval1之内的时间
  591. let _time2 = ""; //_interval2之内的时间
  592. let _type = "blue"; //要展示的颜色
  593. let _interval1 = 300; //行为间隔 s
  594. let _interval2 = 10; //行为间隔 s
  595. let _previousBehavior = "";
  596. let _resultTemplate = [];
  597. let _topic = "";
  598. this.memorandumList.forEach((item, index) => {
  599. if (index == 0) {
  600. _time1 = item.time
  601. _time2 = item.time
  602. _type = "blue";
  603. return _result.push({
  604. textList: [item.text],
  605. time: item.time,
  606. color: _type,
  607. });
  608. }
  609. if (this.isMoreThanSeconds(item.time,_time1,_interval1)) {
  610. //切换颜色
  611. _type = _type == "blue" ? "green" : "blue";
  612. _time1 = item.time;
  613. }
  614. //针对查看学生的作业情况
  615. if (_result[_result.length - 1].textList.length) {
  616. if (
  617. _result[_result.length - 1].textList[
  618. _result[_result.length - 1].textList.length - 1
  619. ].indexOf("的作业") === -1 &&
  620. item.text.indexOf("的作业") !== -1
  621. ) {
  622. return _result.push({
  623. textList: [item.text],
  624. time: item.time,
  625. color: _type,
  626. });
  627. } else if (
  628. _result[_result.length - 1].textList[
  629. _result[_result.length - 1].textList.length - 1
  630. ].indexOf("的作业") !== -1 &&
  631. item.text.indexOf("的作业") !== -1
  632. ) {
  633. return _result[_result.length - 1].textList.push(item.text);
  634. }else if(_result[_result.length - 1].textList[
  635. _result[_result.length - 1].textList.length - 1
  636. ].indexOf("的作业") !== -1 && item.text.indexOf("的作业") == -1){
  637. return _result.push({
  638. textList: [item.text],
  639. time: item.time,
  640. color: _type,
  641. });
  642. }
  643. }
  644. //针对任务面板做题的操作情况
  645. if (
  646. item.text.match(/<span class=['"]variable['"]>第(.*?)题<\/span>/g) !=
  647. null
  648. ) {
  649. let _match = item.text.match(
  650. /<span class=['"]variable['"]>(.*?)<\/span>/
  651. );
  652. let _matchTopic = _match[1];
  653. if (
  654. _result[_result.length - 1].textList[
  655. _result[_result.length - 1].textList.length - 1
  656. ].match(/<span class=['"]variable['"]>第(.*?)题<\/span>/g) == null
  657. ) {
  658. _topic = _matchTopic;
  659. return _result.push({
  660. textList: [item.text],
  661. time: item.time,
  662. color: _type,
  663. });
  664. } else {
  665. if (_topic == _matchTopic) {
  666. //同一题
  667. return _result[_result.length - 1].textList.push(item.text);
  668. } else {
  669. _topic = _matchTopic;
  670. return _result.push({
  671. textList: [item.text],
  672. time: item.time,
  673. color: _type,
  674. });
  675. }
  676. }
  677. } else if (
  678. _result[_result.length - 1].textList[
  679. _result[_result.length - 1].textList.length - 1
  680. ].match(/<span class=['"]variable['"]>第(.*?)题<\/span>/g)
  681. ) {
  682. return _result.push({
  683. textList: [item.text],
  684. time: item.time,
  685. color: _type,
  686. });
  687. }
  688. if (this.isMoreThanSeconds(item.time,_time2,_interval2)) {
  689. _time2 = item.time
  690. //十秒过了
  691. _result.push({
  692. textList: [item.text],
  693. time: item.time,
  694. color: _type,
  695. });
  696. } else {
  697. _result[_result.length - 1].textList.push(`${item.text}`);
  698. }
  699. });
  700. _result.forEach((i) => {
  701. if (i.textList.every((ei) => ei.indexOf("的作业") !== -1)) {
  702. let _useSet = new Set();
  703. i.textList.forEach((i2) => {
  704. let _userMatch = i2.match(
  705. /<span class=['"]variable['"]>(.*?)<\/span>的作业/
  706. );
  707. if (_userMatch) {
  708. _useSet.add(_userMatch[1]);
  709. }
  710. });
  711. if (Array.from(_useSet).length > 1) {
  712. i.textList = this.lookWork(i.textList);
  713. } else {
  714. i.textList = this.lookWork2(i.textList);
  715. }
  716. } else if (
  717. i.textList.every((ei) =>
  718. ei.match(/<span class=['"]variable['"]>第(.*?)题<\/span>/g)
  719. )
  720. ) {
  721. i.textList = this.lookTask(i.textList);
  722. }
  723. });
  724. return _result;
  725. },
  726. },
  727. watch: {
  728. countdownTime(newValue) {
  729. if (this.isCountdown && this.countdownTimeTimer && newValue == 0) {
  730. this.countdownTimeFinish();
  731. } else if (!this.isCountdown && !this.countdownTimeTimer) {
  732. this.countdownTimeDefault = newValue;
  733. }
  734. if (this.$refs.audioRef.playing && this.sourceActive && newValue == 10) {
  735. this.$refs.audioRef.stop();
  736. this.$refs.endSourceUrlRef.play();
  737. // this.$refs.audioRef.setVolume(newValue / 10);
  738. }
  739. },
  740. },
  741. methods: {
  742. lookWork(data) {
  743. const taskTypes = {
  744. 查看作业: new Set(),
  745. 进行点赞: new Set(),
  746. 进行评论: new Set(),
  747. 进行评分: new Set(),
  748. };
  749. let _result = [];
  750. const viewRegex = /查看<span class=['"]variable['"]>(.*?)<\/span>的作业/g;
  751. const likeRegex =
  752. /对<span class=['"]variable['"]>(.*?)<\/span>的作业进行<span class=['"]btn['"]>点赞<\/span>/g;
  753. const commentRegex =
  754. /对<span class=['"]variable['"]>(.*?)<\/span>的作业进行<span class=['"]btn['"]>评论<\/span>/g;
  755. const markRegex =
  756. /对<span class=['"]variable['"]>(.*?)<\/span>的作业进行<span class=['"]btn['"]>评分<\/span>/g;
  757. data.forEach((str) => {
  758. if (viewRegex.test(str)) {
  759. this.extractText(str, viewRegex).forEach((item) =>
  760. taskTypes["查看作业"].add(item)
  761. );
  762. } else if (likeRegex.test(str)) {
  763. this.extractText(str, likeRegex).forEach((item) =>
  764. taskTypes["进行点赞"].add(item)
  765. );
  766. } else if (commentRegex.test(str)) {
  767. this.extractText(str, commentRegex).forEach((item) =>
  768. taskTypes["进行评论"].add(item)
  769. );
  770. } else if (markRegex.test(str)) {
  771. this.extractText(str, markRegex).forEach((item) =>
  772. taskTypes["进行评分"].add(item)
  773. );
  774. }
  775. });
  776. if (Array.from(taskTypes["查看作业"]).length > 0) {
  777. _result.push(
  778. `查看<span class='variable'>${Array.from(taskTypes["查看作业"]).join(
  779. ","
  780. )}</span>的作业`
  781. );
  782. }
  783. if (Array.from(taskTypes["进行点赞"]).length > 0) {
  784. _result.push(
  785. `对<span class='variable'>${Array.from(taskTypes["进行点赞"]).join(
  786. ","
  787. )}</span>的作业进行<span class="btn">点赞</span>`
  788. );
  789. }
  790. if (Array.from(taskTypes["进行评论"]).length > 0) {
  791. _result.push(
  792. `对<span class='variable'>${Array.from(taskTypes["进行评论"]).join(
  793. ","
  794. )}</span>的作业进行<span class="btn">评论</span>`
  795. );
  796. }
  797. if (Array.from(taskTypes["进行评分"]).length > 0) {
  798. _result.push(
  799. `对<span class='variable'>${Array.from(taskTypes["进行评分"]).join(
  800. ","
  801. )}</span>的作业进行<span class="btn">评分</span>`
  802. );
  803. }
  804. return _result;
  805. },
  806. lookWork2(data) {
  807. // 用于存储结果
  808. let result = [];
  809. // 用于跟踪 variable 和对应的 btn 操作
  810. let map = new Map();
  811. data.forEach((item) => {
  812. // 提取 variable
  813. let variableMatch = item.match(
  814. /<span class=["']variable["']>(.*?)<\/span>/
  815. );
  816. // 提取 btn
  817. let btnMatch = item.match(/<span class=["']btn["']>(.*?)<\/span>/);
  818. if (variableMatch) {
  819. let variable = variableMatch[1];
  820. if (btnMatch) {
  821. let btn = btnMatch[1];
  822. if (!map.has(variable)) {
  823. map.set(variable, []);
  824. }
  825. // 存储 btn 操作
  826. map.get(variable).push(btn);
  827. } else {
  828. // 如果没有 btn 操作,直接推入结果
  829. result.push(item);
  830. }
  831. }
  832. });
  833. // 构建结果数组
  834. map.forEach((btns, variable) => {
  835. // 构建新的字符串
  836. let newString = `对<span class="variable">${variable}</span>的作业<span class="btn">${btns.join(
  837. ","
  838. )}</span>`;
  839. result.push(newString);
  840. });
  841. return Array.from(new Set(result));
  842. },
  843. lookTask(data) {
  844. // 创建一个对象来存储 variable 和对应的操作
  845. let map = {};
  846. let arr = Array.from(new Set(data));
  847. arr.forEach((item) => {
  848. // 提取 variable 和操作部分
  849. let variableMatch = item.match(
  850. /<span class=["']variable["']>(.*?)<\/span>/
  851. );
  852. let operationMatch = item.match(/<\/span>(.*?)$/);
  853. if (variableMatch && operationMatch) {
  854. let variable = variableMatch[1];
  855. let operation = operationMatch[1];
  856. if (!map[variable]) {
  857. map[variable] = [];
  858. }
  859. // 将操作部分去掉前面的 "的" 字符串,并添加到 map 中
  860. map[variable].push(operation.replace(/^的/, ""));
  861. }
  862. });
  863. // 构建结果数组
  864. let result = [];
  865. for (let variable in map) {
  866. // 将操作部分合并成一个字符串
  867. let combinedOperations = map[variable].join("、");
  868. result.push(
  869. `查看<span class="variable">${variable}</span>的<span class="btn">${combinedOperations}</span>`
  870. );
  871. }
  872. return result;
  873. },
  874. extractText(htmlString, regex) {
  875. const matches = htmlString.match(regex);
  876. return matches ? matches.map((match) => match.replace(regex, "$1")) : [];
  877. },
  878. isMoreThanSeconds(time1, time2,exceed) {
  879. // 将时间字符串转换为 Date 对象
  880. let date1 = new Date(time1);
  881. let date2 = new Date(time2);
  882. // 获取时间戳(毫秒)
  883. let timestamp1 = date1.getTime();
  884. let timestamp2 = date2.getTime();
  885. // 计算两个时间戳的差异(秒)
  886. let diffInSeconds = Math.abs(timestamp2 - timestamp1) / 1000;
  887. // 判断差异是否超过 10 秒
  888. return diffInSeconds > exceed;
  889. },
  890. insertMemorandum(_html) {
  891. // return;
  892. //保存行为操作
  893. //variable
  894. //btn
  895. let params = [
  896. {
  897. uid: this.userid,
  898. courseId: this.courseId+(this.tcid2?this.tcid2:""),
  899. content: _html,
  900. },
  901. ];
  902. this.ajax
  903. .post(
  904. this.$store.state.api + "insert_systemOperation_countdownBehavior",
  905. params
  906. )
  907. .then((res) => {
  908. if (res.data == 1) {
  909. console.log("保存操作成功");
  910. } else {
  911. console.log("保存操作失败");
  912. }
  913. })
  914. .catch((e) => {
  915. console.log("保存操作失败");
  916. console.log(e);
  917. });
  918. },
  919. changeShowType(newType) {
  920. this.showType = newType;
  921. if (this.showType == 1) {
  922. this.selectMemorandum();
  923. }
  924. },
  925. changeType(newType) {
  926. if (this.isCountdown || this.isKeepTime) return;
  927. this.type = newType;
  928. },
  929. changeBehaviorTagType(newType) {
  930. if (this.isCountdown) return this.$message.error("正在倒计时");
  931. if (this.isKeepTime) return this.$message.error("正在计时");
  932. if (this.behaviorTagType == newType) return;
  933. this.choiceBehavior = [];
  934. this.behaviorTagType = newType;
  935. if (this.behaviorTagType == 1 && this.behaviorTagMore.length <= 0) {
  936. this.getBehaviorTagMore();
  937. }
  938. },
  939. setCountdownTime(newTime = 0) {
  940. if (this.isCountdown) return this.$message.error("正在倒计时");
  941. if (this.isKeepTime) return this.$message.error("正在计时");
  942. this.countdownTime = newTime;
  943. },
  944. addTime(time = 0) {
  945. if (this.isCountdown) return console.log("正在计时");
  946. if (this.countdownTime >= 3600) {
  947. return this.$message.error("倒计时最高一小时");
  948. }
  949. if (this.countdownTime + time > 3600) {
  950. return (this.countdownTime = 3600);
  951. }
  952. this.countdownTime += time;
  953. },
  954. reduceTime(time = 0) {
  955. if (this.isCountdown) return console.log("正在计时");
  956. if (this.countdownTime - time < 0) return (this.countdownTime = 0);
  957. this.countdownTime -= time;
  958. },
  959. choiceBehaviorTag(tag) {
  960. if (this.isCountdown) return this.$message.error("正在倒计时");
  961. if (this.isKeepTime) return this.$message.error("正在计时");
  962. let _index = this.choiceBehavior.findIndex((i) => i == tag);
  963. if (_index != -1) {
  964. // 数组删除指定下标数据
  965. this.choiceBehavior.splice(_index, 1);
  966. } else {
  967. this.choiceBehavior.push(tag);
  968. }
  969. },
  970. countdownTimeFn() {
  971. if (this.isCountdown) {
  972. //取消
  973. clearInterval(this.countdownTimeTimer);
  974. this.countdownTimeTimer = null;
  975. this.isCountdown = false;
  976. if (this.$refs.audioRef.playing && this.sourceActive) {
  977. this.$refs.audioRef.pause();
  978. }
  979. this.$message.success("已暂停倒计时");
  980. } else {
  981. //开始
  982. if (this.countdownTime == 0)
  983. return this.$message.error("请设置倒计时时间");
  984. this.isCountdown = true;
  985. this.$message.success("已开始倒计时");
  986. if (this.sourceActive) {
  987. this.$refs.audioRef.setVolume(0);
  988. this.$refs.audioRef.play();
  989. }
  990. if (this.countdownTime >= 20 && this.sourceActive) {
  991. let volume = 0;
  992. let sourceTimer = setInterval(() => {
  993. volume += 1;
  994. if (volume >= 10) {
  995. volume = 10;
  996. clearInterval(sourceTimer);
  997. sourceTimer = null;
  998. }
  999. this.$refs.audioRef.setVolume(volume / 10);
  1000. }, 1000);
  1001. } else if (
  1002. this.countdownTime <= 20 &&
  1003. this.countdownTime > 10 &&
  1004. this.sourceActive
  1005. ) {
  1006. this.$refs.audioRef.setVolume(1);
  1007. } else if (this.countdownTime <= 10 && this.sourceActive) {
  1008. this.$refs.audioRef.stop();
  1009. this.$refs.endSourceUrlRef.setProgress(
  1010. (10 - this.countdownTime) / 10
  1011. );
  1012. this.$refs.endSourceUrlRef.play();
  1013. }
  1014. this.countdownTimeTimer = setInterval(() => {
  1015. this.isCountdown = true;
  1016. this.countdownTime -= 1;
  1017. }, 1000);
  1018. let timeShow = `${this.countdownTimeShow.m1}${this.countdownTimeShow.m2}分钟${this.countdownTimeShow.s1}${this.countdownTimeShow.s2}秒`;
  1019. this.insertMemorandum(
  1020. `设置<span class="variable">${timeShow}</span><span class="btn">倒计时</span>${
  1021. this.choiceBehavior.length > 0
  1022. ? ",用于" +
  1023. '<span class="btn">' +
  1024. this.choiceBehavior.join("、") +
  1025. "</span>"
  1026. : ""
  1027. }`
  1028. );
  1029. }
  1030. },
  1031. countdownTimeFinish() {
  1032. clearInterval(this.countdownTimeTimer);
  1033. this.countdownTimeTimer = null;
  1034. this.isCountdown = false;
  1035. this.$parent.type = 1;
  1036. this.$parent.itemType = 3;
  1037. this.changeShowType(0);
  1038. if (this.$refs.audioRef.playing && this.sourceActive) {
  1039. this.$refs.audioRef.pause();
  1040. }
  1041. let _data = {
  1042. type: "countdown",
  1043. time: this.countdownTimeDefault,
  1044. tag: this.choiceBehavior,
  1045. };
  1046. this.insertMemorandum(`<span class="btn">倒计时</span>结束`);
  1047. this.insertData(_data);
  1048. },
  1049. keepTimeFn() {
  1050. if (this.isKeepTime) {
  1051. this.isKeepTime = false;
  1052. clearInterval(this.keepTimeTimer);
  1053. this.keepTimeTimer = null;
  1054. if (this.$refs.audioRef.playing && this.sourceActive) {
  1055. this.$refs.audioRef.pause();
  1056. }
  1057. this.$message.success("已停止计时");
  1058. } else {
  1059. this.isKeepTime = true;
  1060. if (this.sourceActive) {
  1061. this.$refs.audioRef.setVolume(1);
  1062. this.$refs.audioRef.play();
  1063. }
  1064. this.keepTimeTimer = setInterval(() => {
  1065. this.keepTime += 1;
  1066. }, 1000);
  1067. this.$message.success("已开始计时");
  1068. this.insertMemorandum(
  1069. `使用<span class="btn">计时器</span>${
  1070. this.choiceBehavior.length > 0
  1071. ? ",用于" +
  1072. '<span class="btn">' +
  1073. this.choiceBehavior.join("、") +
  1074. "</span>"
  1075. : ""
  1076. }`
  1077. );
  1078. }
  1079. },
  1080. music() {
  1081. this.sourceActive = !this.sourceActive;
  1082. if (
  1083. (this.$refs.audioRef.playing || this.$refs.endSourceUrlRef.playing) &&
  1084. !this.sourceActive
  1085. ) {
  1086. this.$refs.audioRef.pause();
  1087. this.$refs.endSourceUrlRef.stop();
  1088. } else if (this.sourceActive) {
  1089. if (this.isCountdown) {
  1090. if (this.countdownTime > 10) {
  1091. this.$refs.audioRef.play();
  1092. } else {
  1093. this.$refs.audioRef.stop();
  1094. this.$refs.endSourceUrlRef.setProgress(
  1095. (10 - this.countdownTime) / 10
  1096. );
  1097. this.$refs.endSourceUrlRef.play();
  1098. }
  1099. } else if (this.isKeepTime) {
  1100. this.$refs.audioRef.play();
  1101. }
  1102. }
  1103. },
  1104. reset() {
  1105. if (this.type == 0) {
  1106. if (this.isCountdown) {
  1107. this.$confirm("正在倒计时!确定重置倒计时吗?", "提醒", {
  1108. confirmButtonText: "确定",
  1109. cancelButtonText: "取消",
  1110. type: "warning",
  1111. })
  1112. .then((_) => {
  1113. clearInterval(this.countdownTimeTimer);
  1114. this.countdownTimeTimer = null;
  1115. // this.countdownTime = this.countdownTimeDefault;
  1116. this.countdownTime = 0;
  1117. this.isCountdown = false;
  1118. this.choiceBehavior = [];
  1119. this.$message.success("已重置");
  1120. if (this.$refs.audioRef.playing) {
  1121. this.$refs.audioRef.pause();
  1122. }
  1123. })
  1124. .catch((_) => {
  1125. console.log("取消重置");
  1126. });
  1127. } else {
  1128. this.$confirm("确定重置倒计时吗?", "提醒", {
  1129. confirmButtonText: "确定",
  1130. cancelButtonText: "取消",
  1131. type: "warning",
  1132. })
  1133. .then((_) => {
  1134. if (this.$refs.audioRef.playing) {
  1135. this.$refs.audioRef.pause();
  1136. }
  1137. // this.countdownTime = this.countdownTimeDefault;
  1138. this.countdownTime = 0;
  1139. this.isCountdown = false;
  1140. this.choiceBehavior = [];
  1141. this.$message.success("已重置");
  1142. })
  1143. .catch((_) => {
  1144. console.log("取消重置");
  1145. });
  1146. }
  1147. } else if (this.type == 1) {
  1148. if (this.isKeepTime) {
  1149. this.$confirm("正在计时!确定重置计时吗?", "提醒", {
  1150. confirmButtonText: "确定",
  1151. cancelButtonText: "取消",
  1152. type: "warning",
  1153. })
  1154. .then((_) => {
  1155. if (this.$refs.audioRef.playing) {
  1156. this.$refs.audioRef.pause();
  1157. }
  1158. clearInterval(this.keepTimeTimer);
  1159. this.keepTimeTimer = null;
  1160. let _data = {
  1161. type: "keepTime",
  1162. time: this.keepTime,
  1163. tag: this.choiceBehavior,
  1164. };
  1165. let timeShow = `${this.keepTimeShow.m1}${this.keepTimeShow.m2}分钟${this.keepTimeShow.s1}${this.keepTimeShow.s2}秒`;
  1166. this.insertMemorandum(
  1167. `结束计时器,<span class="btn">计时</span><span class="variable">${timeShow}</span>${
  1168. this.choiceBehavior.length > 0
  1169. ? ",用于" +
  1170. '<span class="btn">' +
  1171. this.choiceBehavior.join("、") +
  1172. "</span>"
  1173. : ""
  1174. }`
  1175. );
  1176. this.keepTime = 0;
  1177. this.isKeepTime = false;
  1178. this.insertData(_data);
  1179. })
  1180. .catch((_) => {
  1181. console.log("取消重置");
  1182. });
  1183. } else {
  1184. let _data = {
  1185. type: "keepTime",
  1186. time: this.keepTime,
  1187. tag: this.choiceBehavior,
  1188. };
  1189. if (this.$refs.audioRef.playing) {
  1190. this.$refs.audioRef.pause();
  1191. }
  1192. this.insertData(_data);
  1193. let timeShow = `${this.keepTimeShow.m1}${this.keepTimeShow.m2}分钟${this.keepTimeShow.s1}${this.keepTimeShow.s2}秒`;
  1194. this.insertMemorandum(
  1195. `结束计时器,<span class="btn">计时</span><span class="variable">${timeShow}</span>${
  1196. this.choiceBehavior.length > 0
  1197. ? ",用于" +
  1198. '<span class="btn">' +
  1199. this.choiceBehavior.join("、") +
  1200. "</span>"
  1201. : ""
  1202. }`
  1203. );
  1204. this.keepTime = 0;
  1205. this.isKeepTime = false;
  1206. // this.choiceBehavior = [];
  1207. this.$message.success("已重置");
  1208. }
  1209. }
  1210. },
  1211. getBehaviorTagMore() {
  1212. this.behaviorTagMoreLoading = true;
  1213. let _textData = `课程名称:${this.courseDetail.title}\n分类:${this.courseDetail.name}\n\n`;
  1214. let _chapters = JSON.parse(this.courseDetail.chapters);
  1215. _chapters.forEach((i1, index1) => {
  1216. if (i1.dyName) {
  1217. _textData += `阶段${index1 + 1}:${i1.dyName}\n`;
  1218. }
  1219. i1.chapterInfo[0].taskJson.forEach((i2, index2) => {
  1220. if (i2.task) {
  1221. _textData += `任务${index2 + 1}:${i2.task}\n`;
  1222. _textData += `${i2.taskDetail}\n`;
  1223. }
  1224. });
  1225. _textData += "\n";
  1226. });
  1227. let _msg = `Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
  1228. ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
  1229. Instruction: Based on the context, follow "Format example", write content
  1230. #Context
  1231. ##任务
  1232. 在以下课堂中,如果老师设置一个倒计时,他可能想开展哪些教学活动?每个教学活动使用4个字,进行简洁精确的描述,请返回所有可能的行为名称,不需要额外的解释。请返回最有可能的12个活动类
  1233. ##Format example
  1234. ["小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报","小组汇报"]
  1235. ##课堂内容
  1236. ${_textData}
  1237. `;
  1238. this.behaviorTagMore = [];
  1239. let params = {
  1240. assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
  1241. userId: this.userid,
  1242. message: [{ type: "text", text: _msg }],
  1243. session_name: uuidv4(),
  1244. file_ids: this.fileId,
  1245. model: "gpt-4o-2024-08-06",
  1246. };
  1247. this.ajax
  1248. // .post("https://gpt4.cocorobo.cn/chat", params)
  1249. // .post("https://claude3.cocorobo.cn/chat", params)
  1250. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
  1251. .then((res) => {
  1252. // console.log(res)
  1253. let _data = res.data.FunctionResponse.message;
  1254. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  1255. const match = _data.match(/\[\s*[^]*\s*\]/);
  1256. let _result = JSON.parse(match[0]);
  1257. this.behaviorTagMore = _result;
  1258. this.behaviorTagMoreLoading = false;
  1259. })
  1260. .catch((e) => {
  1261. this.behaviorTagMoreLoading = false;
  1262. this.$message.error("获取更多行为标签失败");
  1263. this.behaviorTagType = 0;
  1264. this.behaviorTagMore = [];
  1265. console.log(e);
  1266. });
  1267. },
  1268. insertData(data = null) {
  1269. if (!data) return;
  1270. let params = [
  1271. {
  1272. uid: this.userid,
  1273. courseId: this.courseId,
  1274. content: JSON.stringify(data),
  1275. },
  1276. ];
  1277. this.ajax
  1278. .post(
  1279. this.$store.state.api + "insert_systemOperation_classRoomHelper",
  1280. params
  1281. )
  1282. .then((res) => {
  1283. if (res.data == 1) {
  1284. console.log("保存成功");
  1285. } else {
  1286. console.log("保存失败");
  1287. }
  1288. })
  1289. .catch((e) => {
  1290. console.log("保存失败👇");
  1291. console.log(e);
  1292. });
  1293. },
  1294. selectMemorandum() {
  1295. this.memorandumLoading = true;
  1296. let params = {
  1297. uid: this.userid,
  1298. courseId: this.courseId+(this.tcid2?this.tcid2:""),
  1299. };
  1300. this.memorandumList = [];
  1301. this.ajax
  1302. .get(
  1303. this.$store.state.api + "select_systemOperation_countdownBehavior",
  1304. params
  1305. )
  1306. .then((res) => {
  1307. let _data = res.data[0];
  1308. if (_data.length) {
  1309. // let _result = _data;
  1310. // console.log(_result)
  1311. this.memorandumList = _data;
  1312. } else {
  1313. this.memorandumList = [];
  1314. }
  1315. this.$nextTick(() => {
  1316. this.$refs.stepRef.scrollTop = this.$refs.stepRef.scrollHeight;
  1317. });
  1318. this.memorandumLoading = false;
  1319. })
  1320. .catch((err) => {
  1321. console.log(err);
  1322. this.memorandumLoading = false;
  1323. this.$message.error("获取行为备忘失败");
  1324. });
  1325. },
  1326. },
  1327. };
  1328. </script>
  1329. <style scoped>
  1330. .countdown {
  1331. width: 100%;
  1332. height: 100%;
  1333. /* display: flex;
  1334. flex-direction: column;
  1335. align-items: center; */
  1336. /* justify-content: center; */
  1337. /* padding: auto;
  1338. overflow: auto; */
  1339. }
  1340. .c_timeBox {
  1341. width: 100%;
  1342. height: 100%;
  1343. position: relative;
  1344. display: flex;
  1345. flex-direction: column;
  1346. justify-content: flex-end;
  1347. }
  1348. .c_tb_top {
  1349. width: 100%;
  1350. max-height: calc(100% - 60px);
  1351. margin-top: auto;
  1352. overflow-x: hidden;
  1353. padding-bottom: 30px;
  1354. }
  1355. .c_behavior {
  1356. width: 100%;
  1357. height: 100%;
  1358. }
  1359. .c_changeType {
  1360. width: 100%;
  1361. height: 60px;
  1362. display: flex;
  1363. align-items: center;
  1364. justify-content: space-evenly;
  1365. border-top: solid 1px #e7e7e7;
  1366. box-sizing: border-box;
  1367. }
  1368. .c_changeType > span {
  1369. width: 2px;
  1370. height: 30px;
  1371. background-color: #e7e7e7;
  1372. }
  1373. .c_ct_btn {
  1374. width: 100px;
  1375. height: 90%;
  1376. display: flex;
  1377. justify-content: center;
  1378. align-items: center;
  1379. cursor: pointer;
  1380. position: relative;
  1381. }
  1382. .c_ct_btn > div {
  1383. font-size: 18px;
  1384. font-weight: bold;
  1385. }
  1386. .c_ct_btn > span {
  1387. position: absolute;
  1388. width: 60%;
  1389. height: 60%;
  1390. background: #6c8cff67;
  1391. filter: blur(20px);
  1392. border-radius: 50%;
  1393. }
  1394. .c_ct_btn > svg {
  1395. width: 30px;
  1396. height: 30px;
  1397. position: absolute;
  1398. margin-top: 30px;
  1399. }
  1400. .c_time {
  1401. width: 100%;
  1402. height: 200px;
  1403. display: flex;
  1404. align-items: center;
  1405. justify-content: center;
  1406. }
  1407. .c_t_item {
  1408. color: black;
  1409. display: flex;
  1410. align-items: center;
  1411. justify-content: center;
  1412. }
  1413. .c_t_i_card {
  1414. display: flex;
  1415. align-items: center;
  1416. justify-content: center;
  1417. position: relative;
  1418. padding: 0px 30px;
  1419. background-color: #fff;
  1420. margin: 0 10px;
  1421. box-shadow: 0px 0px 5px 2px #1d398314;
  1422. /* box-shadow: 1px 1px 20px 4px #1d39830d; */
  1423. border-radius: 8px;
  1424. }
  1425. .c_t_i_card > span {
  1426. position: absolute;
  1427. bottom: 25px;
  1428. right: 10px;
  1429. font-size: 16px;
  1430. }
  1431. .c_t_i_card > div {
  1432. display: flex;
  1433. flex-direction: column;
  1434. align-items: center;
  1435. justify-content: space-between;
  1436. }
  1437. .c_t_i_card > div > div {
  1438. font-size: 5em;
  1439. font-weight: bold;
  1440. margin: 0 5px;
  1441. }
  1442. .c_t_i_card > div > span {
  1443. margin: 0;
  1444. display: flex;
  1445. justify-content: center;
  1446. align-items: center;
  1447. width: 25px;
  1448. height: 25px;
  1449. position: absolute;
  1450. }
  1451. .c_t_i_btnTop {
  1452. top: -30px;
  1453. }
  1454. .c_t_i_btnBottom {
  1455. bottom: -30px;
  1456. }
  1457. .c_t_i_btn {
  1458. font-size: 1.3em;
  1459. width: 25px;
  1460. height: 25px;
  1461. display: flex;
  1462. justify-content: center;
  1463. align-items: center;
  1464. padding: 0 !important;
  1465. background-color: #f0f2f5;
  1466. }
  1467. .c_choiceTime {
  1468. width: 100%;
  1469. height: auto;
  1470. box-sizing: border-box;
  1471. padding: 20px;
  1472. }
  1473. .c_title {
  1474. display: flex;
  1475. align-items: center;
  1476. justify-content: space-between;
  1477. width: 100%;
  1478. }
  1479. .c_title > span {
  1480. font-size: 20px;
  1481. font-weight: bold;
  1482. }
  1483. .c_t_btnArea {
  1484. margin-left: 20px;
  1485. display: flex;
  1486. justify-content: center;
  1487. align-items: center;
  1488. }
  1489. .c_t_btnArea > span {
  1490. width: 40px;
  1491. display: flex;
  1492. justify-content: center;
  1493. align-items: center;
  1494. margin-left: 10px;
  1495. cursor: pointer;
  1496. color: #999999;
  1497. position: relative;
  1498. font-size: 14px;
  1499. }
  1500. .c_t_ba_active {
  1501. color: black !important;
  1502. }
  1503. .c_t_ba_active::after {
  1504. content: "";
  1505. width: 100%;
  1506. height: 3px;
  1507. background-color: #3681fc;
  1508. position: absolute;
  1509. bottom: -7px;
  1510. left: 1px;
  1511. }
  1512. .c_ct_box {
  1513. width: 100%;
  1514. height: auto;
  1515. display: flex;
  1516. align-items: center;
  1517. justify-content: space-around;
  1518. flex-wrap: wrap;
  1519. padding-top: 10px;
  1520. }
  1521. .c_ct_box > span {
  1522. width: 20%;
  1523. height: 30px;
  1524. border-radius: 20px;
  1525. box-sizing: border-box;
  1526. border: 0.5px solid #E0EAFB;
  1527. margin: 10px 2%;
  1528. background-color: #fff;
  1529. display: flex;
  1530. align-items: center;
  1531. justify-content: center;
  1532. transition: 0.1s;
  1533. cursor: pointer;
  1534. box-shadow: 0px 2px 5px 0px #1D398314;
  1535. box-shadow: 0.5px 0.5px 10px 2px #1D39830D;
  1536. }
  1537. .c_ct_box > span:hover {
  1538. background-color: #409eff;
  1539. border: solid 1px #409eff;
  1540. color: #fff;
  1541. }
  1542. .c_behaviorTag {
  1543. width: 100%;
  1544. height: auto;
  1545. box-sizing: border-box;
  1546. padding: 20px;
  1547. }
  1548. .c_bt_box {
  1549. width: 100%;
  1550. height: auto;
  1551. min-height: 100px;
  1552. display: flex;
  1553. align-items: flex-start;
  1554. justify-content: space-around;
  1555. flex-wrap: wrap;
  1556. overflow: auto;
  1557. margin-top: 10px;
  1558. }
  1559. .c_bt_box > span {
  1560. width: auto;
  1561. height: auto;
  1562. padding: 6px 10px;
  1563. border-radius: 50px;
  1564. border: 0.5px solid #e0eafb;
  1565. box-shadow: 0px 2px 5px 0px #1d398314;
  1566. box-shadow: 0.5px 0.5px 10px 2px #1d39830d;
  1567. margin: 10px 0;
  1568. background-color: #fff;
  1569. display: flex;
  1570. align-items: center;
  1571. justify-content: center;
  1572. transition: 0.1s;
  1573. cursor: pointer;
  1574. font-size: 15px;
  1575. }
  1576. .c_bt_b_active {
  1577. background-color: #409eff !important;
  1578. border: solid 1px #409eff !important;
  1579. color: #fff;
  1580. }
  1581. .c_bt_box > span:hover {
  1582. background-color: #409eff !important;
  1583. border: solid 1px #409eff !important;
  1584. color: #fff !important;
  1585. }
  1586. .c_btnArea {
  1587. width: 100%;
  1588. height: 100px;
  1589. display: flex;
  1590. align-items: center;
  1591. justify-content: center;
  1592. }
  1593. .c_btnArea > span {
  1594. width: auto;
  1595. height: auto;
  1596. padding: 5px 10px;
  1597. /* border: solid 1px #d0d0d0;
  1598. background-color: #fff; */
  1599. /* border-radius: 20px; */
  1600. cursor: pointer;
  1601. transition: 0.2s;
  1602. }
  1603. .c_btnArea > span > svg {
  1604. width: 30px;
  1605. height: 30px;
  1606. }
  1607. /* .c_btnArea > span:hover {
  1608. border: solid 1px #409eff;
  1609. background-color: #409eff;
  1610. color: #fff;
  1611. } */
  1612. .c_ba_startArea {
  1613. width: 60px;
  1614. height: 60px;
  1615. margin: 0 40px;
  1616. display: flex;
  1617. align-items: center;
  1618. justify-content: center;
  1619. }
  1620. .c_ba_startType0 {
  1621. width: 60px;
  1622. height: 60px;
  1623. display: flex;
  1624. align-items: center;
  1625. justify-content: center;
  1626. border-radius: 50%;
  1627. border: solid 8px #e0eafb;
  1628. color: #e0eafb;
  1629. cursor: pointer;
  1630. transition: 0.2s;
  1631. }
  1632. .c_ba_startType0 > svg {
  1633. fill: #afbff7;
  1634. height: 60%;
  1635. position: relative;
  1636. left: 3px;
  1637. transition: 0.2s;
  1638. }
  1639. .c_ba_startType {
  1640. width: 60px;
  1641. height: 60px;
  1642. display: flex;
  1643. align-items: center;
  1644. justify-content: center;
  1645. border-radius: 50%;
  1646. border: solid 8px #3681fc;
  1647. color: #3681fc;
  1648. cursor: pointer;
  1649. transition: 0.2s;
  1650. }
  1651. .c_ba_startType > svg {
  1652. fill: #677bf0;
  1653. height: 60%;
  1654. position: relative;
  1655. left: 3px;
  1656. transition: 0.2s;
  1657. }
  1658. .c_ba_startType2 {
  1659. width: 60px;
  1660. height: 60px;
  1661. display: flex;
  1662. align-items: center;
  1663. justify-content: center;
  1664. border-radius: 50%;
  1665. border: solid 8px #f5222d;
  1666. color: #f5222d;
  1667. cursor: pointer;
  1668. transition: 0.2s;
  1669. }
  1670. .c_ba_startType2 > svg {
  1671. fill: #f5222d;
  1672. height: 60%;
  1673. transition: 0.2s;
  1674. }
  1675. .sourceActive {
  1676. border: solid 1px #409eff !important;
  1677. background-color: #409eff !important;
  1678. color: #fff;
  1679. }
  1680. .c_step {
  1681. width: 100%;
  1682. height: calc(100% - 80px);
  1683. margin-top: 20px;
  1684. padding: 20px 50px;
  1685. box-sizing: border-box;
  1686. overflow: auto;
  1687. }
  1688. .c_step >>> .el-timeline .btn {
  1689. color: #2972f4;
  1690. }
  1691. .c_step >>> .el-timeline .variable {
  1692. color: #319b62;
  1693. }
  1694. .c_step >>> .blue .el-timeline-item__tail{
  1695. border-left: 6px solid #B3CCFA !important;
  1696. }
  1697. .c_step >>> .green .el-timeline-item__tail{
  1698. border-left: 6px solid #B7EACB !important;
  1699. }
  1700. .c_step >>> .el-timeline-item__node{
  1701. background-color: #FFFFFF;
  1702. box-sizing:border-box;
  1703. border:2px solid #B3CCFA;
  1704. position: relative;
  1705. left: -0.5px;
  1706. }
  1707. .c_s_item {
  1708. display: flex;
  1709. justify-content: center;
  1710. align-items: center;
  1711. }
  1712. .ActivityMemo {
  1713. width: 100%;
  1714. height: 30px;
  1715. display: flex;
  1716. align-items: center;
  1717. margin-top: 20px;
  1718. box-sizing: border-box;
  1719. padding-left: 20px;
  1720. }
  1721. .ActivityMemo > span {
  1722. display: flex;
  1723. align-items: center;
  1724. cursor: pointer;
  1725. }
  1726. .ActivityMemo > span > svg {
  1727. margin-left: 5px;
  1728. position: relative;
  1729. top: 1px;
  1730. width: 20px;
  1731. height: 20px;
  1732. }
  1733. .behaviorBack {
  1734. width: 100%;
  1735. height: 30px;
  1736. display: flex;
  1737. align-items: center;
  1738. margin-top: 20px;
  1739. box-sizing: border-box;
  1740. padding-left: 20px;
  1741. }
  1742. .behaviorBack > span {
  1743. display: flex;
  1744. align-items: center;
  1745. cursor: pointer;
  1746. width: 80px;
  1747. }
  1748. .behaviorBack > span > svg {
  1749. margin-right: 5px;
  1750. position: relative;
  1751. top: 1px;
  1752. width: 20px;
  1753. height: 20px;
  1754. transform: rotate(180deg);
  1755. }
  1756. </style>