countdown.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. <template>
  2. <div class="countdown">
  3. <div class="c_changeType" v-if="showType == 0">
  4. <el-button-group>
  5. <el-button
  6. :type="isCountdown ? 'danger' : type == 0 ? 'primary' : ''"
  7. @click.stop="changeType(0)"
  8. :disabled="isCountdown || isKeepTime"
  9. >
  10. 倒计时
  11. </el-button>
  12. <el-button
  13. :type="isKeepTime ? 'danger' : type == 1 ? 'primary' : ''"
  14. @click.stop="changeType(1)"
  15. :disabled="isCountdown || isKeepTime"
  16. >
  17. 计时器
  18. </el-button>
  19. </el-button-group>
  20. </div>
  21. <div class="c_time" v-if="showType == 0">
  22. <div class="c_t_item" v-if="type == 0">
  23. <div>
  24. <span v-if="!isCountdown"
  25. ><el-button class="c_t_i_btn" @click.stop="addTime(600)"
  26. >+</el-button
  27. ></span
  28. >{{ countdownTimeShow.m1
  29. }}<span v-if="!isCountdown"
  30. ><el-button class="c_t_i_btn" @click.stop="reduceTime(600)"
  31. >-</el-button
  32. ></span
  33. >
  34. </div>
  35. <div>
  36. <span v-if="!isCountdown"
  37. ><el-button class="c_t_i_btn" @click.stop="addTime(60)"
  38. >+</el-button
  39. ></span
  40. >{{ countdownTimeShow.m2
  41. }}<span v-if="!isCountdown"
  42. ><el-button class="c_t_i_btn" @click.stop="reduceTime(60)"
  43. >-</el-button
  44. ></span
  45. >
  46. </div>
  47. <span>:</span>
  48. <div>
  49. <span v-if="!isCountdown"
  50. ><el-button class="c_t_i_btn" @click.stop="addTime(10)"
  51. >+</el-button
  52. ></span
  53. >{{ countdownTimeShow.s1
  54. }}<span v-if="!isCountdown"
  55. ><el-button class="c_t_i_btn" @click.stop="reduceTime(10)"
  56. >-</el-button
  57. ></span
  58. >
  59. </div>
  60. <div>
  61. <span v-if="!isCountdown"
  62. ><el-button class="c_t_i_btn" @click.stop="addTime(1)"
  63. >+</el-button
  64. ></span
  65. >{{ countdownTimeShow.s2
  66. }}<span v-if="!isCountdown"
  67. ><el-button class="c_t_i_btn" @click.stop="reduceTime(1)"
  68. >-</el-button
  69. ></span
  70. >
  71. </div>
  72. </div>
  73. <div class="c_t_item" v-if="type == 1">
  74. <div>{{ keepTimeShow.m1 }}</div>
  75. <div>{{ keepTimeShow.m2 }}</div>
  76. <span>:</span>
  77. <div>{{ keepTimeShow.s1 }}</div>
  78. <div>{{ keepTimeShow.s2 }}</div>
  79. </div>
  80. </div>
  81. <div class="c_choiceTime" v-if="type == 0 && showType == 0">
  82. <div class="c_title">
  83. <span>倒计时长</span>
  84. </div>
  85. <div class="c_ct_box">
  86. <span @click.stop="setCountdownTime(30)">30秒</span>
  87. <span @click.stop="setCountdownTime(60)">1分钟</span>
  88. <span @click.stop="setCountdownTime(120)">2分钟</span>
  89. <span @click.stop="setCountdownTime(180)">3分钟</span>
  90. <span @click.stop="setCountdownTime(300)">5分钟</span>
  91. <span @click.stop="setCountdownTime(360)">6分钟</span>
  92. <span @click.stop="setCountdownTime(480)">8分钟</span>
  93. <span @click.stop="setCountdownTime(600)">10分钟</span>
  94. </div>
  95. </div>
  96. <div class="c_behaviorTag" v-if="showType == 0">
  97. <div class="c_title">
  98. <span>行为标签</span>
  99. <div class="c_t_btnArea">
  100. <el-button-group>
  101. <el-button
  102. size="mini"
  103. :disabled="isCountdown || isKeepTime"
  104. :type="behaviorTagType == 0 ? 'primary' : 'info'"
  105. @click.stop="changeBehaviorTagType(0)"
  106. >
  107. 常用
  108. </el-button>
  109. <el-button
  110. size="mini"
  111. :disabled="isCountdown || isKeepTime"
  112. :type="behaviorTagType == 1 ? 'primary' : 'info'"
  113. @click.stop="changeBehaviorTagType(1)"
  114. >
  115. 更多
  116. </el-button>
  117. </el-button-group>
  118. </div>
  119. </div>
  120. <div
  121. class="c_bt_box"
  122. v-loading="behaviorTagMoreLoading && behaviorTagType == 1"
  123. >
  124. <span
  125. v-if="behaviorTagType == 1"
  126. :class="[choiceBehavior.includes(item) ? 'c_bt_b_active' : '']"
  127. v-for="(item, index) in behaviorTagMore"
  128. @click.stop="choiceBehaviorTag(item)"
  129. :key="behaviorTagType + '-' + index"
  130. >{{ item }}</span
  131. >
  132. <span
  133. v-if="behaviorTagType == 0"
  134. :class="[choiceBehavior.includes(item) ? 'c_bt_b_active' : '']"
  135. v-for="(item, index) in behaviorTagCommon"
  136. @click.stop="choiceBehaviorTag(item)"
  137. :key="behaviorTagType + '-' + index"
  138. >{{ item }}</span
  139. >
  140. </div>
  141. </div>
  142. <div class="c_btnArea" v-if="showType == 0">
  143. <span @click.stop="music()" :class="[sourceActive ? 'sourceActive' : '']"
  144. >音乐</span
  145. >
  146. <div class="c_ba_startArea">
  147. <div
  148. :class="[!isCountdown ? 'c_ba_startType' : 'c_ba_startType2']"
  149. v-if="type == 0"
  150. @click.stop="countdownTimeFn()"
  151. >
  152. <svg
  153. v-if="!isCountdown"
  154. t="1721117381559"
  155. viewBox="0 0 1024 1024"
  156. version="1.1"
  157. xmlns="http://www.w3.org/2000/svg"
  158. p-id="12941"
  159. width="64"
  160. height="64"
  161. >
  162. <path
  163. 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"
  164. p-id="12942"
  165. ></path>
  166. </svg>
  167. <svg
  168. v-else
  169. t="1721198913879"
  170. class="icon"
  171. viewBox="0 0 1024 1024"
  172. version="1.1"
  173. xmlns="http://www.w3.org/2000/svg"
  174. p-id="4266"
  175. width="64"
  176. height="64"
  177. >
  178. <path
  179. 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"
  180. p-id="4267"
  181. ></path>
  182. </svg>
  183. <!-- <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> -->
  184. </div>
  185. <div
  186. :class="[!isKeepTime ? 'c_ba_startType' : 'c_ba_startType2']"
  187. v-if="type == 1"
  188. @click.stop="keepTimeFn()"
  189. >
  190. <svg
  191. v-if="!isKeepTime"
  192. t="1721117381559"
  193. viewBox="0 0 1024 1024"
  194. version="1.1"
  195. xmlns="http://www.w3.org/2000/svg"
  196. p-id="12941"
  197. width="64"
  198. height="64"
  199. >
  200. <path
  201. 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"
  202. p-id="12942"
  203. ></path>
  204. </svg>
  205. <svg
  206. v-else
  207. t="1721198913879"
  208. class="icon"
  209. viewBox="0 0 1024 1024"
  210. version="1.1"
  211. xmlns="http://www.w3.org/2000/svg"
  212. p-id="4266"
  213. width="64"
  214. height="64"
  215. >
  216. <path
  217. 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"
  218. p-id="4267"
  219. ></path>
  220. </svg>
  221. <!-- <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> -->
  222. </div>
  223. </div>
  224. <span @click.stop="reset()">重置</span>
  225. </div>
  226. <div
  227. style="margin-bottom:30px;padding:20px;cursor: pointer;"
  228. v-if="showType == 0"
  229. >
  230. <span @click.stop="changeShowType(1)">教学活动备忘>></span>
  231. </div>
  232. <div
  233. v-if="showType == 1"
  234. style="padding-top:20px;height:100%;box-sizing: border-box;"
  235. >
  236. <span style="padding:20px;cursor: pointer;" @click.stop="changeShowType(0)"
  237. ><<返回</span
  238. >
  239. <div class="c_step" ref="stepRef" v-loading="memorandumLoading">
  240. <el-timeline>
  241. <el-timeline-item
  242. v-for="(item, index) in memorandumList"
  243. :key="index"
  244. :timestamp="item.time"
  245. >
  246. <div v-html="item.text"></div>
  247. <!-- <span v-html="activity.content"></span> -->
  248. </el-timeline-item>
  249. </el-timeline>
  250. </div>
  251. </div>
  252. <mini-audio
  253. v-show="false"
  254. ref="audioRef"
  255. :loop="true"
  256. :audio-source="sourceUrl"
  257. ></mini-audio>
  258. <mini-audio
  259. v-show="false"
  260. ref="endSourceUrlRef"
  261. :loop="false"
  262. :audio-source="endSourceUrl"
  263. ></mini-audio>
  264. </div>
  265. </template>
  266. <script>
  267. import { v4 as uuidv4 } from "uuid";
  268. export default {
  269. props: {
  270. courseDetail: {
  271. type: Object,
  272. default: () => {}
  273. },
  274. fileId: {
  275. type: Array,
  276. default: () => []
  277. }
  278. },
  279. data() {
  280. return {
  281. userid: this.$route.query.userid,
  282. courseId: this.$route.query.courseId,
  283. showType: 0,
  284. sourceUrl:
  285. "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",
  286. endSourceUrl:
  287. "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",
  288. sourceActive: false,
  289. type: 0, //0:倒计时 1:计时器
  290. isCountdown: false,
  291. isKeepTime: false,
  292. countdownTime: 0,
  293. countdownTimeDefault: 0,
  294. countdownTimeTimer: null,
  295. keepTime: 0,
  296. keepTimeTimer: null,
  297. startCountdownTime: 0,
  298. behaviorTagType: 0, //0:常用 1:更多
  299. behaviorTagMore: [], //更多
  300. behaviorTagMoreLoading: false,
  301. behaviorTagCommon: [
  302. "小组讨论",
  303. "小组汇报",
  304. "动手实验",
  305. "课堂游戏",
  306. "自主学习",
  307. "作品展示",
  308. "学生演讲",
  309. "学生分享",
  310. "随堂练习",
  311. "快速问答",
  312. "阅读资料",
  313. "观察记录"
  314. ], //常用
  315. choiceBehavior: [],
  316. memorandumList: [],
  317. memorandumLoading:false,
  318. };
  319. },
  320. computed: {
  321. countdownTimeShow() {
  322. let _result = {
  323. m1: 0,
  324. m2: 0,
  325. s1: 0,
  326. s2: 0
  327. };
  328. if (this.countdownTime <= 0) return _result;
  329. let minutes = Math.floor(this.countdownTime / 60);
  330. let seconds = this.countdownTime % 60;
  331. if (minutes > 9) {
  332. _result.m1 = Math.floor(minutes / 10);
  333. _result.m2 = minutes % 10;
  334. } else {
  335. _result.m1 = 0;
  336. _result.m2 = minutes;
  337. }
  338. if (seconds > 9) {
  339. _result.s1 = Math.floor(seconds / 10);
  340. _result.s2 = seconds % 10;
  341. } else {
  342. _result.s1 = 0;
  343. _result.s2 = seconds;
  344. }
  345. return _result;
  346. },
  347. keepTimeShow() {
  348. let _result = {
  349. m1: 0,
  350. m2: 0,
  351. s1: 0,
  352. s2: 0
  353. };
  354. if (this.keepTime <= 0) return _result;
  355. let minutes = Math.floor(this.keepTime / 60);
  356. let seconds = this.keepTime % 60;
  357. if (minutes > 9) {
  358. _result.m1 = Math.floor(minutes / 10);
  359. _result.m2 = minutes % 10;
  360. } else {
  361. _result.m1 = 0;
  362. _result.m2 = minutes;
  363. }
  364. if (seconds > 9) {
  365. _result.s1 = Math.floor(seconds / 10);
  366. _result.s2 = seconds % 10;
  367. } else {
  368. _result.s1 = 0;
  369. _result.s2 = seconds;
  370. }
  371. return _result;
  372. }
  373. },
  374. watch: {
  375. countdownTime(newValue) {
  376. if (this.isCountdown && this.countdownTimeTimer && newValue == 0) {
  377. this.countdownTimeFinish();
  378. } else if (!this.isCountdown && !this.countdownTimeTimer) {
  379. this.countdownTimeDefault = newValue;
  380. }
  381. if (this.$refs.audioRef.playing && this.sourceActive && newValue == 10) {
  382. this.$refs.audioRef.stop();
  383. this.$refs.endSourceUrlRef.play();
  384. // this.$refs.audioRef.setVolume(newValue / 10);
  385. }
  386. }
  387. },
  388. methods: {
  389. insertMemorandum(_html) {
  390. return;
  391. //保存行为操作
  392. //variable
  393. //btn
  394. let params = [
  395. {
  396. uid: this.userid,
  397. courseId: this.courseId,
  398. content: _html
  399. }
  400. ];
  401. this.ajax
  402. .post(
  403. this.$store.state.api + "insert_systemOperation_countdownBehavior",
  404. params
  405. )
  406. .then(res => {
  407. if (res.data == 1) {
  408. console.log("保存操作成功");
  409. } else {
  410. console.log("保存操作失败");
  411. }
  412. })
  413. .catch(e => {
  414. console.log("保存操作失败");
  415. console.log(e);
  416. });
  417. },
  418. changeShowType(newType) {
  419. this.showType = newType;
  420. if (this.showType == 1) {
  421. this.selectMemorandum()
  422. }
  423. },
  424. changeType(newType) {
  425. if (this.isCountdown || this.isKeepTime) return;
  426. this.type = newType;
  427. },
  428. changeBehaviorTagType(newType) {
  429. if (this.isCountdown) return this.$message.error("正在倒计时");
  430. if (this.isKeepTime) return this.$message.error("正在计时");
  431. if (this.behaviorTagType == newType) return;
  432. this.choiceBehavior = [];
  433. this.behaviorTagType = newType;
  434. if (this.behaviorTagType == 1 && this.behaviorTagMore.length <= 0) {
  435. this.getBehaviorTagMore();
  436. }
  437. },
  438. setCountdownTime(newTime = 0) {
  439. if (this.isCountdown) return this.$message.error("正在倒计时");
  440. if (this.isKeepTime) return this.$message.error("正在计时");
  441. this.countdownTime = newTime;
  442. },
  443. addTime(time = 0) {
  444. if (this.isCountdown) return console.log("正在计时");
  445. if (this.countdownTime >= 3600) {
  446. return this.$message.error("倒计时最高一小时");
  447. }
  448. if (this.countdownTime + time > 3600) {
  449. return (this.countdownTime = 3600);
  450. }
  451. this.countdownTime += time;
  452. },
  453. reduceTime(time = 0) {
  454. if (this.isCountdown) return console.log("正在计时");
  455. if (this.countdownTime - time < 0) return (this.countdownTime = 0);
  456. this.countdownTime -= time;
  457. },
  458. choiceBehaviorTag(tag) {
  459. if (this.isCountdown) return this.$message.error("正在倒计时");
  460. if (this.isKeepTime) return this.$message.error("正在计时");
  461. let _index = this.choiceBehavior.findIndex(i => i == tag);
  462. if (_index != -1) {
  463. // 数组删除指定下标数据
  464. this.choiceBehavior.splice(_index, 1);
  465. } else {
  466. this.choiceBehavior.push(tag);
  467. }
  468. },
  469. countdownTimeFn() {
  470. if (this.isCountdown) {
  471. //取消
  472. clearInterval(this.countdownTimeTimer);
  473. this.countdownTimeTimer = null;
  474. this.isCountdown = false;
  475. if (this.$refs.audioRef.playing && this.sourceActive) {
  476. this.$refs.audioRef.pause();
  477. }
  478. this.$message.success("已暂停倒计时");
  479. } else {
  480. //开始
  481. if (this.countdownTime == 0)
  482. return this.$message.error("请设置倒计时时间");
  483. this.isCountdown = true;
  484. this.$message.success("已开始倒计时");
  485. if (this.sourceActive) {
  486. this.$refs.audioRef.setVolume(0);
  487. this.$refs.audioRef.play();
  488. }
  489. if (this.countdownTime >= 20 && this.sourceActive) {
  490. let volume = 0;
  491. let sourceTimer = setInterval(() => {
  492. volume += 1;
  493. if (volume >= 10) {
  494. volume = 10;
  495. clearInterval(sourceTimer);
  496. sourceTimer = null;
  497. }
  498. this.$refs.audioRef.setVolume(volume / 10);
  499. }, 1000);
  500. } else if (
  501. this.countdownTime <= 20 &&
  502. this.countdownTime > 10 &&
  503. this.sourceActive
  504. ) {
  505. this.$refs.audioRef.setVolume(1);
  506. } else if (this.countdownTime <= 10 && this.sourceActive) {
  507. this.$refs.audioRef.stop();
  508. this.$refs.endSourceUrlRef.setProgress(
  509. (10 - this.countdownTime) / 10
  510. );
  511. this.$refs.endSourceUrlRef.play();
  512. }
  513. this.countdownTimeTimer = setInterval(() => {
  514. this.isCountdown = true;
  515. this.countdownTime -= 1;
  516. }, 1000);
  517. let timeShow = `${this.countdownTimeShow.m1}${this.countdownTimeShow.m2}分钟${this.countdownTimeShow.s1}${this.countdownTimeShow.s2}秒`;
  518. this.insertMemorandum(
  519. `设置<span class="variable"></span><span class="btn">倒计时${timeShow}</span>${
  520. this.choiceBehavior.length > 0
  521. ? ",用于" +
  522. '<span class="btn">' +
  523. this.choiceBehavior.join("、") +
  524. "</span>"
  525. : ""
  526. }`
  527. );
  528. }
  529. },
  530. countdownTimeFinish() {
  531. clearInterval(this.countdownTimeTimer);
  532. this.countdownTimeTimer = null;
  533. this.isCountdown = false;
  534. this.$parent.type = 1;
  535. this.$parent.itemType = 3;
  536. if (this.$refs.audioRef.playing && this.sourceActive) {
  537. this.$refs.audioRef.pause();
  538. }
  539. let _data = {
  540. type: "countdown",
  541. time: this.countdownTimeDefault,
  542. tag: this.choiceBehavior
  543. };
  544. this.insertMemorandum(`<span class="btn">倒计时</span>结束`);
  545. this.insertData(_data);
  546. },
  547. keepTimeFn() {
  548. if (this.isKeepTime) {
  549. this.isKeepTime = false;
  550. clearInterval(this.keepTimeTimer);
  551. this.keepTimeTimer = null;
  552. if (this.$refs.audioRef.playing && this.sourceActive) {
  553. this.$refs.audioRef.pause();
  554. }
  555. this.$message.success("已停止计时");
  556. } else {
  557. this.isKeepTime = true;
  558. if (this.sourceActive) {
  559. this.$refs.audioRef.setVolume(1);
  560. this.$refs.audioRef.play();
  561. }
  562. this.keepTimeTimer = setInterval(() => {
  563. this.keepTime += 1;
  564. }, 1000);
  565. this.$message.success("已开始计时");
  566. this.insertMemorandum(
  567. `使用<span class="btn">计时器</span>${
  568. this.choiceBehavior.length > 0
  569. ? ",用于" +
  570. '<span class="btn">' +
  571. this.choiceBehavior.join("、") +
  572. "</span>"
  573. : ""
  574. }`
  575. );
  576. }
  577. },
  578. music() {
  579. this.sourceActive = !this.sourceActive;
  580. if (
  581. (this.$refs.audioRef.playing || this.$refs.endSourceUrlRef.playing) &&
  582. !this.sourceActive
  583. ) {
  584. this.$refs.audioRef.pause();
  585. this.$refs.endSourceUrlRef.stop();
  586. } else if (this.sourceActive) {
  587. if (this.isCountdown) {
  588. if (this.countdownTime > 10) {
  589. this.$refs.audioRef.play();
  590. } else {
  591. this.$refs.audioRef.stop();
  592. this.$refs.endSourceUrlRef.setProgress(
  593. (10 - this.countdownTime) / 10
  594. );
  595. this.$refs.endSourceUrlRef.play();
  596. }
  597. } else if (this.isKeepTime) {
  598. this.$refs.audioRef.play();
  599. }
  600. }
  601. },
  602. reset() {
  603. if (this.type == 0) {
  604. if (this.isCountdown) {
  605. this.$confirm("正在倒计时!确定重置倒计时吗?", "提醒", {
  606. confirmButtonText: "确定",
  607. cancelButtonText: "取消",
  608. type: "warning"
  609. })
  610. .then(_ => {
  611. clearInterval(this.countdownTimeTimer);
  612. this.countdownTimeTimer = null;
  613. // this.countdownTime = this.countdownTimeDefault;
  614. this.countdownTime = 0;
  615. this.isCountdown = false;
  616. this.choiceBehavior = [];
  617. this.$message.success("已重置");
  618. if (this.$refs.audioRef.playing) {
  619. this.$refs.audioRef.pause();
  620. }
  621. })
  622. .catch(_ => {
  623. console.log("取消重置");
  624. });
  625. } else {
  626. this.$confirm("确定重置倒计时吗?", "提醒", {
  627. confirmButtonText: "确定",
  628. cancelButtonText: "取消",
  629. type: "warning"
  630. })
  631. .then(_ => {
  632. if (this.$refs.audioRef.playing) {
  633. this.$refs.audioRef.pause();
  634. }
  635. // this.countdownTime = this.countdownTimeDefault;
  636. this.countdownTime = 0;
  637. this.isCountdown = false;
  638. this.choiceBehavior = [];
  639. this.$message.success("已重置");
  640. })
  641. .catch(_ => {
  642. console.log("取消重置");
  643. });
  644. }
  645. } else if (this.type == 1) {
  646. if (this.isKeepTime) {
  647. this.$confirm("正在计时!确定重置计时吗?", "提醒", {
  648. confirmButtonText: "确定",
  649. cancelButtonText: "取消",
  650. type: "warning"
  651. })
  652. .then(_ => {
  653. if (this.$refs.audioRef.playing) {
  654. this.$refs.audioRef.pause();
  655. }
  656. clearInterval(this.keepTimeTimer);
  657. this.keepTimeTimer = null;
  658. let _data = {
  659. type: "keepTime",
  660. time: this.keepTime,
  661. tag: this.choiceBehavior
  662. };
  663. let timeShow = `${this.keepTimeShow.m1}${this.keepTimeShow.m2}分钟${this.keepTimeShow.s1}${this.keepTimeShow.s2}秒`;
  664. this.insertMemorandum(
  665. `结束计时器,<span class="btn">计时</span><span class="variable">${timeShow}</span>${
  666. this.choiceBehavior.length > 0
  667. ? ",用于" +
  668. '<span class="btn">' +
  669. this.choiceBehavior.join("、") +
  670. "</span>"
  671. : ""
  672. }`
  673. );
  674. this.keepTime = 0;
  675. this.isKeepTime = false;
  676. this.insertData(_data);
  677. })
  678. .catch(_ => {
  679. console.log("取消重置");
  680. });
  681. } else {
  682. let _data = {
  683. type: "keepTime",
  684. time: this.keepTime,
  685. tag: this.choiceBehavior
  686. };
  687. if (this.$refs.audioRef.playing) {
  688. this.$refs.audioRef.pause();
  689. }
  690. this.insertData(_data);
  691. let timeShow = `${this.keepTimeShow.m1}${this.keepTimeShow.m2}分钟${this.keepTimeShow.s1}${this.keepTimeShow.s2}秒`;
  692. this.insertMemorandum(
  693. `结束计时器,<span class="btn">计时</span><span class="variable">${timeShow}</span>${
  694. this.choiceBehavior.length > 0
  695. ? ",用于" +
  696. '<span class="btn">' +
  697. this.choiceBehavior.join("、") +
  698. "</span>"
  699. : ""
  700. }`
  701. );
  702. this.keepTime = 0;
  703. this.isKeepTime = false;
  704. // this.choiceBehavior = [];
  705. this.$message.success("已重置");
  706. }
  707. }
  708. },
  709. getBehaviorTagMore() {
  710. this.behaviorTagMoreLoading = true;
  711. let _textData = `课程名称:${this.courseDetail.title}\n分类:${this.courseDetail.name}\n\n`;
  712. let _chapters = JSON.parse(this.courseDetail.chapters);
  713. _chapters.forEach((i1, index1) => {
  714. if (i1.dyName) {
  715. _textData += `阶段${index1 + 1}:${i1.dyName}\n`;
  716. }
  717. i1.chapterInfo[0].taskJson.forEach((i2, index2) => {
  718. if (i2.task) {
  719. _textData += `任务${index2 + 1}:${i2.task}\n`;
  720. _textData += `${i2.taskDetail}\n`;
  721. }
  722. });
  723. _textData += "\n";
  724. });
  725. 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.
  726. ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
  727. Instruction: Based on the context, follow "Format example", write content
  728. #Context
  729. ##任务
  730. 在以下课堂中,如果老师设置一个倒计时,他可能想开展哪些教学活动?每个教学活动使用4个字,进行简洁精确的描述,请返回所有可能的行为名称,不需要额外的解释。请返回最有可能的12个活动类
  731. ##Format example
  732. ["小组讨论","小组汇报","动手实验","课堂游戏","自主学习","作品展示","学生演讲","学生分享","随堂练习","快速问答","阅读资料","观察记录"]
  733. ##课堂内容
  734. ${_textData}
  735. `;
  736. this.behaviorTagMore = [];
  737. let params = {
  738. assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
  739. userId: this.userid,
  740. message: [{ type: "text", text: _msg }],
  741. session_name: uuidv4(),
  742. file_ids: this.fileId
  743. };
  744. this.ajax
  745. // .post("https://gpt4.cocorobo.cn/chat", params)
  746. // .post("https://claude3.cocorobo.cn/chat", params)
  747. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
  748. .then(res => {
  749. // console.log(res)
  750. let _data = res.data.FunctionResponse.message;
  751. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  752. const match = _data.match(/\[\s*[^]*\s*\]/);
  753. let _result = JSON.parse(match[0]);
  754. this.behaviorTagMore = _result;
  755. this.behaviorTagMoreLoading = false;
  756. })
  757. .catch(e => {
  758. this.behaviorTagMoreLoading = false;
  759. this.$message.error("获取更多行为标签失败");
  760. this.behaviorTagType = 0;
  761. this.behaviorTagMore = [];
  762. console.log(e);
  763. });
  764. },
  765. insertData(data = null) {
  766. if (!data) return;
  767. let params = [
  768. {
  769. uid: this.userid,
  770. courseId: this.courseId,
  771. content: JSON.stringify(data)
  772. }
  773. ];
  774. this.ajax
  775. .post(
  776. this.$store.state.api + "insert_systemOperation_classRoomHelper",
  777. params
  778. )
  779. .then(res => {
  780. if (res.data == 1) {
  781. console.log("保存成功");
  782. } else {
  783. console.log("保存失败");
  784. }
  785. })
  786. .catch(e => {
  787. console.log("保存失败👇");
  788. console.log(e);
  789. });
  790. },
  791. selectMemorandum(){
  792. return;
  793. this.memorandumLoading = false;
  794. let params = {
  795. uid:this.userid,
  796. courseId:this.courseId,
  797. }
  798. this.memorandumList = [];
  799. this.ajax.get(this.$store.state.api+"select_systemOperation_countdownBehavior",params).then(res=>{
  800. let _data = res.data[0];
  801. if(_data.length){
  802. this.memorandumList = _data;
  803. }else{
  804. this.memorandumList = [];
  805. }
  806. this.memorandumLoading = false;
  807. console.log(res);
  808. }).catch(err=>{
  809. console.log(err)
  810. this.memorandumLoading = false;
  811. this.$message.error("获取行为备忘失败")
  812. })
  813. }
  814. }
  815. };
  816. </script>
  817. <style scoped>
  818. .countdown {
  819. width: 100%;
  820. height: 100%;
  821. /* display: flex;
  822. flex-direction: column;
  823. align-items: center; */
  824. /* justify-content: center; */
  825. padding: auto;
  826. overflow: auto;
  827. }
  828. .c_changeType {
  829. width: 100%;
  830. height: 100px;
  831. display: flex;
  832. align-items: center;
  833. justify-content: center;
  834. }
  835. .c_time {
  836. width: 100%;
  837. height: 200px;
  838. display: flex;
  839. align-items: center;
  840. justify-content: center;
  841. }
  842. .c_t_item {
  843. font-size: 6em;
  844. font-weight: bold;
  845. color: black;
  846. display: flex;
  847. align-items: center;
  848. justify-content: center;
  849. }
  850. .c_t_item > div {
  851. display: flex;
  852. flex-direction: column;
  853. align-items: center;
  854. justify-content: space-between;
  855. }
  856. .c_t_item > div > span {
  857. margin: 0;
  858. display: flex;
  859. justify-content: center;
  860. align-items: center;
  861. width: 25px;
  862. height: 25px;
  863. }
  864. .c_t_i_btn {
  865. padding: 5px 10px !important;
  866. }
  867. .c_t_item > span {
  868. margin: 0 10px;
  869. position: relative;
  870. top: -11px;
  871. }
  872. .c_choiceTime {
  873. width: 100%;
  874. height: auto;
  875. box-sizing: border-box;
  876. padding: 20px;
  877. }
  878. .c_title {
  879. display: flex;
  880. align-items: center;
  881. width: 100%;
  882. }
  883. .c_title > span {
  884. font-size: 20px;
  885. font-weight: bold;
  886. }
  887. .c_t_btnArea {
  888. margin-left: 20px;
  889. }
  890. .c_ct_box {
  891. width: 100%;
  892. height: auto;
  893. display: flex;
  894. align-items: center;
  895. justify-content: space-around;
  896. flex-wrap: wrap;
  897. padding-top: 10px;
  898. }
  899. .c_ct_box > span {
  900. width: 20%;
  901. height: 30px;
  902. border-radius: 20px;
  903. box-sizing: border-box;
  904. border: solid 1px #d0d0d0;
  905. margin: 10px 2%;
  906. background-color: #fff;
  907. display: flex;
  908. align-items: center;
  909. justify-content: center;
  910. transition: 0.1s;
  911. cursor: pointer;
  912. }
  913. .c_ct_box > span:hover {
  914. background-color: #409eff;
  915. border: solid 1px #409eff;
  916. color: #fff;
  917. }
  918. .c_behaviorTag {
  919. width: 100%;
  920. height: auto;
  921. box-sizing: border-box;
  922. padding: 20px;
  923. }
  924. .c_bt_box {
  925. width: 100%;
  926. height: auto;
  927. min-height: 100px;
  928. display: flex;
  929. align-items: flex-start;
  930. justify-content: space-around;
  931. flex-wrap: wrap;
  932. overflow: auto;
  933. margin-top: 10px;
  934. }
  935. .c_bt_box > span {
  936. width: auto;
  937. height: auto;
  938. padding: 5px 8px;
  939. border-radius: 8px;
  940. border: solid 1px #d0d0d0;
  941. margin: 10px 0;
  942. background-color: #fff;
  943. display: flex;
  944. align-items: center;
  945. justify-content: center;
  946. transition: 0.1s;
  947. cursor: pointer;
  948. }
  949. .c_bt_b_active {
  950. background-color: #409eff !important;
  951. border: solid 1px #409eff !important;
  952. color: #fff;
  953. }
  954. .c_bt_box > span:hover {
  955. background-color: #409eff !important;
  956. border: solid 1px #409eff !important;
  957. color: #fff !important;
  958. }
  959. .c_btnArea {
  960. width: 100%;
  961. height: 100px;
  962. display: flex;
  963. align-items: center;
  964. justify-content: center;
  965. }
  966. .c_btnArea > span {
  967. width: auto;
  968. height: auto;
  969. padding: 5px 10px;
  970. border: solid 1px #d0d0d0;
  971. background-color: #fff;
  972. border-radius: 20px;
  973. cursor: pointer;
  974. transition: 0.2s;
  975. }
  976. .c_btnArea > span:hover {
  977. border: solid 1px #409eff;
  978. background-color: #409eff;
  979. color: #fff;
  980. }
  981. .c_ba_startArea {
  982. width: 60px;
  983. height: 60px;
  984. margin: 0 40px;
  985. display: flex;
  986. align-items: center;
  987. justify-content: center;
  988. }
  989. .c_ba_startType {
  990. width: 100%;
  991. height: 100%;
  992. display: flex;
  993. align-items: center;
  994. justify-content: center;
  995. border-radius: 50%;
  996. border: solid 2px #707070;
  997. color: #707070;
  998. cursor: pointer;
  999. transition: 0.2s;
  1000. }
  1001. .c_ba_startType > svg {
  1002. fill: #707070;
  1003. width: 70%;
  1004. height: 70%;
  1005. position: relative;
  1006. left: 3px;
  1007. transition: 0.2s;
  1008. }
  1009. .c_ba_startType:hover {
  1010. border: solid 2px #409eff;
  1011. }
  1012. .c_ba_startType:hover > svg {
  1013. fill: #409eff;
  1014. }
  1015. .c_ba_startType2 {
  1016. width: 100%;
  1017. height: 100%;
  1018. display: flex;
  1019. align-items: center;
  1020. justify-content: center;
  1021. border-radius: 50%;
  1022. border: solid 2px #f5222d;
  1023. color: #f5222d;
  1024. cursor: pointer;
  1025. transition: 0.2s;
  1026. }
  1027. .c_ba_startType2 > svg {
  1028. fill: #f5222d;
  1029. width: 70%;
  1030. height: 70%;
  1031. transition: 0.2s;
  1032. }
  1033. .c_ba_startType2:hover {
  1034. border: solid 2px #cf1322;
  1035. }
  1036. .c_ba_startType2:hover > svg {
  1037. fill: #cf1322;
  1038. }
  1039. .sourceActive {
  1040. border: solid 1px #409eff !important;
  1041. background-color: #409eff !important;
  1042. color: #fff;
  1043. }
  1044. .c_step {
  1045. width: 100%;
  1046. height: calc(100% - 80px);
  1047. margin-top: 20px;
  1048. padding: 20px 50px;
  1049. box-sizing: border-box;
  1050. overflow: auto;
  1051. }
  1052. .c_s_item {
  1053. display: flex;
  1054. justify-content: center;
  1055. align-items: center;
  1056. }
  1057. </style>