index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. <template>
  2. <div class="play-record">
  3. <div class="play-record__header clearfix">
  4. 播放记录
  5. <!-- <a class="clear-btn">清空记录</a> -->
  6. </div>
  7. <div class="play-record__body">
  8. <div class="date-item" v-for="(v, k) in recordList" :key="k">
  9. <div class="date-item__header">{{ k }}</div>
  10. <div class="date-item__body">
  11. <div class="list">
  12. <div
  13. class="course-item"
  14. v-for="(sectionItem, sectionIndex) in v.list"
  15. :key="'section' + sectionIndex"
  16. >
  17. <div class="course-item__header">{{ sectionItem.goodsName }}</div>
  18. <div class="course-item__body">
  19. <div class="img" @click="goCourse(sectionItem)">
  20. <img
  21. :src="$tools.splitImgHost(sectionItem.coverUrl, true)"
  22. alt=""
  23. />
  24. </div>
  25. <div class="text">
  26. <div class="title">
  27. {{ sectionItem.sectionName }}
  28. <!-- <div class="note">60学时</div> -->
  29. </div>
  30. <div class="progress">
  31. 学习进度
  32. <el-progress
  33. class="progress-line"
  34. :text-inside="true"
  35. :stroke-width="16"
  36. :percentage="
  37. toFixed(
  38. (sectionItem.videoCurrentTime /
  39. sectionItem.durationTime) *
  40. 100
  41. )
  42. "
  43. ></el-progress>
  44. </div>
  45. </div>
  46. <!-- <div class="btns-wrap">
  47. <div class="btns">
  48. <div class="btn btn--warm">删除记录</div>
  49. </div>
  50. </div> -->
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. </div>
  56. </div>
  57. <div class="play-record__footer">
  58. <div class="pagination">
  59. <el-pagination
  60. @current-change="currentChange"
  61. background
  62. layout="prev, pager, next"
  63. :total="total"
  64. :pager-count="5"
  65. :page-size="params.pageSize"
  66. >
  67. </el-pagination>
  68. </div>
  69. </div>
  70. <el-dialog
  71. width="800px"
  72. class="rebuild"
  73. :visible.sync="showRebuildDetailModal"
  74. :close-on-click-modal="false"
  75. :close-on-press-escape="false"
  76. :show-close="false"
  77. >
  78. <div class="rebuild__content">
  79. <div class="rebuild__close" @click="showRebuildDetailModal = false">
  80. X
  81. </div>
  82. <div class="rebuild__header">审核详情</div>
  83. <div class="rebuild__body">
  84. <div class="content">
  85. <div class="content__header">
  86. <div class="title">重要提示:</div>
  87. <div class="desc">
  88. 您的学时审核不通过,不通过原因如下,请查阅,并重学不通过的课程内容。
  89. </div>
  90. </div>
  91. <div class="content__body">
  92. <div class="list">
  93. <div
  94. class="list__item"
  95. v-for="(item, index) in rebuildItems"
  96. :key="index"
  97. >
  98. <div class="title">
  99. <span class="note" v-if="item.type == 0"> 测试 </span>
  100. <span class="note note--yellow" v-if="item.type == 1"
  101. >录播</span
  102. >
  103. <span class="note note--yellow" v-if="item.type == 2"
  104. >直播</span
  105. >
  106. <span class="note note--yellow" v-if="item.type == 3"
  107. >回放</span
  108. >
  109. {{ index + 1 }}、{{ item.name }}
  110. </div>
  111. <div class="desc">
  112. <!-- <div class="imgs">
  113. <div
  114. class="img"
  115. v-for="(items, indexs) in item.userStudyRecordPhoto"
  116. :key="indexs"
  117. >
  118. <img :src="$tools.splitImgHost(items.photo)" />
  119. <div class="note">
  120. {{ $tools.timestampToTime(items.createTime, false) }}
  121. </div>
  122. </div>
  123. </div> -->
  124. </div>
  125. <div class="desc">
  126. 原因:
  127. <span class="note">{{ item.auditReason }}</span>
  128. </div>
  129. </div>
  130. </div>
  131. </div>
  132. </div>
  133. </div>
  134. <div class="rebuild__footer">
  135. <el-button class="confirm" @click="rebuildSubmit" type="primary"
  136. >确认已阅读</el-button
  137. >
  138. </div>
  139. </div>
  140. </el-dialog>
  141. </div>
  142. </template>
  143. <script>
  144. export default {
  145. name: "MyCourse",
  146. data() {
  147. return {
  148. activeName: "1",
  149. recordList: {},
  150. total: 0,
  151. rebuildItems: [],
  152. rebuildItem: {},
  153. params: {
  154. pageNum: 1,
  155. pageSize: 10,
  156. },
  157. sysTime: 0,
  158. showRebuildDetailModal: false,
  159. };
  160. },
  161. mounted() {
  162. this.studRrecordListUserRecord();
  163. },
  164. methods: {
  165. toFixed(num) {
  166. console.log(num);
  167. if (num) {
  168. let str = String(num).indexOf(".");
  169. if (str != -1) {
  170. return +num.toFixed(2);
  171. } else {
  172. return num;
  173. }
  174. } else {
  175. return 0;
  176. }
  177. },
  178. rebuildSubmit() {
  179. this.$confirm(
  180. "如对审核结果有异议,请勿点击确认重学。致电020-87085982咨询",
  181. "注意",
  182. {
  183. confirmButtonText: "确认重学",
  184. cancelButtonText: "取消",
  185. closeOnClickModal: false,
  186. closeOnPressEscape: false,
  187. distinguishCancelAndClose: false,
  188. showClose: false,
  189. }
  190. )
  191. .then((_) => {
  192. this.$request
  193. .courseperiodrebuild({
  194. goodsId: this.rebuildItem.goodsId,
  195. gradeId: this.rebuildItem.gradeId,
  196. })
  197. .then((res) => {
  198. this.showRebuildDetailModal = false;
  199. this.$router.push({
  200. path: `/my-course-detail/${this.rebuildItem.goodsId}`,
  201. query: {
  202. gradeId: this.rebuildItem.gradeId,
  203. orderGoodsId: this.rebuildItem.orderGoodsId,
  204. rebuild: 1,
  205. },
  206. });
  207. });
  208. })
  209. .catch((_) => {});
  210. },
  211. currentChange(e) {
  212. this.params.pageNum = e;
  213. this.studRrecordListUserRecord();
  214. },
  215. studRrecordListUserRecord() {
  216. this.$request.studRrecordListUserRecord(this.params).then((res) => {
  217. let dateObj = {};
  218. res.rows.forEach((row) => {
  219. if (!dateObj[row.date]) {
  220. dateObj[row.date] = { title: row.goodsName, list: [] };
  221. dateObj[row.date].list.push(row);
  222. } else {
  223. dateObj[row.date].list.push(row);
  224. }
  225. });
  226. // for (let k in dateObj) {
  227. // dateObj[k].list.sort((a, b) => {
  228. // return a.createTime - b.createTime;
  229. // });
  230. // }
  231. console.log(dateObj, "dateObj");
  232. this.recordList = dateObj;
  233. this.total = res.total;
  234. });
  235. },
  236. async goCourse(sectionItem) {
  237. this.sysTime = this.$tools.timest();
  238. this.$request
  239. .orderInfo({
  240. orderGoodsId: sectionItem.orderGoodsId,
  241. })
  242. .then(async (res) => {
  243. let item = res.data;
  244. if (item.interfacePushId > 0 && item.officialStatus != 1) {
  245. this.$message({
  246. type: "warning",
  247. message:
  248. "机构正在为您报名中,请耐心等待,有疑问请联系020-87085982!",
  249. });
  250. return;
  251. }
  252. if (
  253. this.sysTime <= item.serviceStartTime ||
  254. this.sysTime >= item.serviceEndTime
  255. ) {
  256. this.$message({
  257. type: "warning",
  258. message: "不在学习服务期,不能进入学习",
  259. });
  260. return;
  261. }
  262. if (
  263. (item.classStartTime && this.sysTime <= item.classStartTime) ||
  264. (item.classEndTime && this.sysTime >= item.classEndTime)
  265. ) {
  266. this.$message({
  267. type: "warning",
  268. message: "不在班级有效期,不能进入学习",
  269. });
  270. return;
  271. }
  272. if (item.learningStatus == 2) {
  273. this.$message({
  274. type: "warning",
  275. message: "开放学习时间待定,不能进入学习",
  276. });
  277. return;
  278. }
  279. if (item.classStatus == 0) {
  280. this.$message({
  281. type: "warning",
  282. message: "尚未开班,不能进入学习",
  283. });
  284. return;
  285. }
  286. if (
  287. item.learningStatus == 3 &&
  288. this.sysTime < item.learningTimeStart
  289. ) {
  290. this.$message({
  291. type: "warning",
  292. message: "不在开放学习时间,不能进入学习",
  293. });
  294. return;
  295. }
  296. let rebuildStatus = await this.courseGoodsRebuildStatus(
  297. item.goodsId,
  298. item.gradeId
  299. );
  300. if (rebuildStatus == 0) {
  301. this.rebuildItem = item;
  302. this.$request
  303. .getcourseperiodcheat({
  304. goodsId: item.goodsId,
  305. gradeId: item.gradeId,
  306. })
  307. .then((res) => {
  308. this.rebuildItems = res.rows;
  309. });
  310. this.showRebuildDetailModal = true;
  311. return;
  312. }
  313. if (item.educationName == "继续教育") {
  314. this.$request
  315. .lockLockStatus({
  316. action: "jxjy",
  317. })
  318. .then((res) => {
  319. //有其他端在操作,不能学习
  320. this.$message({
  321. type: "warning",
  322. message: res.msg,
  323. });
  324. })
  325. .catch((err) => {
  326. //可以学习
  327. this.$request
  328. .courseCourseList({
  329. pageNum: 1,
  330. pageSize: 1,
  331. goodsId: item.goodsId,
  332. gradeId: item.gradeId,
  333. })
  334. .then((res) => {
  335. if (res.rows.length) {
  336. this.go("/my-course-detail/" + sectionItem.goodsId, {
  337. gradeId: sectionItem.gradeId,
  338. orderGoodsId: sectionItem.orderGoodsId,
  339. courseId: sectionItem.courseId,
  340. });
  341. } else {
  342. this.$message({
  343. type: "warning",
  344. message: "课程内暂无可以学习的科目",
  345. });
  346. }
  347. });
  348. });
  349. } else {
  350. this.$request
  351. .courseCourseList({
  352. pageNum: 1,
  353. pageSize: 1,
  354. goodsId: item.goodsId,
  355. gradeId: item.gradeId,
  356. })
  357. .then((res) => {
  358. if (res.rows.length) {
  359. this.go("/my-course-detail/" + sectionItem.goodsId, {
  360. gradeId: sectionItem.gradeId,
  361. orderGoodsId: sectionItem.orderGoodsId,
  362. courseId: sectionItem.courseId,
  363. });
  364. } else {
  365. this.$message({
  366. type: "warning",
  367. message: "课程内暂无可以学习的科目",
  368. });
  369. }
  370. });
  371. }
  372. });
  373. },
  374. go(path, query) {
  375. this.$router.push({
  376. path,
  377. query,
  378. });
  379. },
  380. /**
  381. * @param {Object} goodsId 商品id
  382. * 查询商品重修状态
  383. */
  384. courseGoodsRebuildStatus(goodsId, gradeId) {
  385. return new Promise((resolve) => {
  386. this.$request
  387. .courseGoodsRebuildStatus({
  388. goodsId: goodsId,
  389. gradeId: gradeId,
  390. })
  391. .then((res) => {
  392. resolve(res.data);
  393. });
  394. });
  395. },
  396. },
  397. };
  398. </script>
  399. <!-- Add "scoped" attribute to limit CSS to this component only -->
  400. <style scoped lang="scss">
  401. .play-record {
  402. &__header {
  403. height: 56px;
  404. line-height: 56px;
  405. .clear-btn {
  406. margin-top: 12px;
  407. float: right;
  408. display: block;
  409. width: 122px;
  410. height: 32px;
  411. background: #eeeeee;
  412. border-radius: 16px;
  413. text-align: center;
  414. line-height: 32px;
  415. color: #3f8dfd;
  416. }
  417. }
  418. &__body {
  419. .date-item {
  420. margin-top: 24px;
  421. border-top: 1px solid #eee;
  422. &:nth-of-type(1) {
  423. margin: 0;
  424. }
  425. &__header {
  426. padding-left: 15px;
  427. height: 40px;
  428. line-height: 40px;
  429. }
  430. &__body {
  431. .list {
  432. .course-item {
  433. margin-top: 20px;
  434. background: #fafbfc;
  435. border-radius: 8px;
  436. overflow: hidden;
  437. &:nth-of-type(1) {
  438. margin: 0;
  439. }
  440. &__header {
  441. height: 40px;
  442. border-bottom: 1px solid #eee;
  443. padding: 0 18px;
  444. line-height: 40px;
  445. font-size: 16px;
  446. font-family: Microsoft YaHei;
  447. font-weight: bold;
  448. color: #333333;
  449. }
  450. &__body {
  451. .img {
  452. cursor: pointer;
  453. float: left;
  454. width: 160px;
  455. height: 90px;
  456. img {
  457. max-width: 100%;
  458. max-height: 100%;
  459. }
  460. }
  461. .text {
  462. float: left;
  463. margin-left: 12px;
  464. .title {
  465. margin-top: 10px;
  466. font-size: 16px;
  467. font-family: Microsoft YaHei;
  468. font-weight: 400;
  469. color: #333333;
  470. .note {
  471. display: inline-block;
  472. vertical-align: middle;
  473. border: 1px solid #333333;
  474. border-radius: 4px;
  475. font-size: 12px;
  476. font-family: Microsoft YaHei;
  477. font-weight: 400;
  478. color: #333333;
  479. padding: 2px 5px;
  480. margin-left: 12px;
  481. }
  482. }
  483. .progress {
  484. margin-top: 30px;
  485. font-size: 14px;
  486. font-family: Microsoft YaHei;
  487. font-weight: 400;
  488. color: #333333;
  489. &-line {
  490. width: 200px;
  491. display: inline-block;
  492. }
  493. }
  494. }
  495. .btns-wrap {
  496. display: table;
  497. float: right;
  498. height: 90px;
  499. width: 130px;
  500. .btns {
  501. display: table-cell;
  502. vertical-align: middle;
  503. text-align: center;
  504. .btn {
  505. cursor: pointer;
  506. margin: 2px 0;
  507. width: 122px;
  508. height: 32px;
  509. background: #3f8dfd;
  510. border-radius: 16px;
  511. display: inline-block;
  512. text-align: center;
  513. line-height: 32px;
  514. color: #fff;
  515. &--warm {
  516. background: #ff3b30;
  517. }
  518. }
  519. }
  520. }
  521. }
  522. }
  523. }
  524. }
  525. }
  526. }
  527. &__footer {
  528. .pagination {
  529. padding: 30px 0;
  530. text-align: center;
  531. }
  532. }
  533. .rebuild {
  534. /deep/ .el-dialog__header {
  535. display: none;
  536. }
  537. /deep/ .el-dialog__body {
  538. padding: 0;
  539. overflow: unset;
  540. }
  541. &__close {
  542. cursor: pointer;
  543. position: absolute;
  544. right: 0;
  545. top: -28px;
  546. width: 24px;
  547. height: 24px;
  548. line-height: 24px;
  549. text-align: center;
  550. color: #eee;
  551. border: 1px solid #eee;
  552. border-radius: 50%;
  553. }
  554. &__header {
  555. height: 40px;
  556. border-bottom: 1px solid #eee;
  557. line-height: 40px;
  558. font-size: 16px;
  559. font-family: Microsoft YaHei;
  560. font-weight: bold;
  561. color: #333333;
  562. padding-left: 24px;
  563. }
  564. &__body {
  565. height: 400px;
  566. padding: 0 24px;
  567. .content {
  568. height: 100%;
  569. overflow-y: auto;
  570. &__header {
  571. padding: 16px 0;
  572. border-bottom: 1px solid #eee;
  573. .title {
  574. font-size: 16px;
  575. font-family: Microsoft YaHei;
  576. font-weight: bold;
  577. color: #ff3b30;
  578. line-height: 24px;
  579. }
  580. .desc {
  581. margin-top: 10px;
  582. font-size: 16px;
  583. font-family: Microsoft YaHei;
  584. font-weight: 400;
  585. color: #ff3b30;
  586. line-height: 24px;
  587. }
  588. }
  589. &__body {
  590. .list {
  591. &__item {
  592. padding: 16px 0;
  593. border-bottom: 1px solid #eee;
  594. .title {
  595. font-size: 14px;
  596. font-family: Microsoft YaHei;
  597. font-weight: 400;
  598. color: #333333;
  599. .note {
  600. display: inline-block;
  601. text-align: center;
  602. line-height: 18px;
  603. width: 32px;
  604. height: 20px;
  605. border: 1px solid #3f8dfd;
  606. border-radius: 4px;
  607. color: #3f8dfd;
  608. font-size: 12px;
  609. &--yellow {
  610. border: 1px solid #ff9500;
  611. color: #ff9500;
  612. }
  613. }
  614. }
  615. .desc {
  616. margin-top: 10px;
  617. font-size: 14px;
  618. font-family: Microsoft YaHei;
  619. font-weight: 400;
  620. color: #333333;
  621. .note {
  622. color: #ff3b30;
  623. line-height: 20px;
  624. }
  625. .img {
  626. width: 100px;
  627. height: 100px;
  628. display: inline-block;
  629. text-align: center;
  630. img {
  631. max-width: 100%;
  632. max-height: 100%;
  633. }
  634. }
  635. }
  636. }
  637. }
  638. }
  639. }
  640. }
  641. &__footer {
  642. height: 90px;
  643. border-top: 1px solid #eee;
  644. text-align: center;
  645. .confirm {
  646. width: 200px;
  647. height: 40px;
  648. padding: 0;
  649. border-radius: 20px;
  650. text-align: center;
  651. line-height: 40px;
  652. color: #fff;
  653. margin: 24px auto;
  654. }
  655. }
  656. }
  657. }
  658. </style>