chenxiong 3 yıl önce
ebeveyn
işleme
adc5367108
41 değiştirilmiş dosya ile 2323 ekleme ve 313 silme
  1. 1 0
      .gitignore
  2. 39 1
      src/apis/course.js
  3. 40 0
      src/apis/mock.js
  4. BIN
      src/assets/css/img/btn-like.png
  5. BIN
      src/assets/css/img/emotion.png
  6. BIN
      src/assets/css/img/favicon.ico
  7. BIN
      src/assets/css/img/flower.png
  8. BIN
      src/assets/css/img/like.png
  9. BIN
      src/assets/css/img/more.png
  10. BIN
      src/assets/css/img/person.png
  11. BIN
      src/assets/css/img/show-more.png
  12. 205 0
      src/assets/css/mobile.css
  13. 332 0
      src/assets/css/pc.css
  14. 146 0
      src/assets/css/public.css
  15. 38 0
      src/assets/css/tool.css
  16. BIN
      src/assets/img/btn-like.png
  17. BIN
      src/assets/img/emotion.png
  18. BIN
      src/assets/img/favicon.ico
  19. BIN
      src/assets/img/flower.png
  20. BIN
      src/assets/img/like.png
  21. BIN
      src/assets/img/more.png
  22. BIN
      src/assets/img/person.png
  23. BIN
      src/assets/img/show-more.png
  24. 1 0
      src/assets/jquery.min.js
  25. BIN
      src/assets/live-bg.png
  26. BIN
      src/assets/live.png
  27. BIN
      src/assets/living.gif
  28. 3 1
      src/axios.js
  29. 32 2
      src/components/goodsItem/index.vue
  30. 42 0
      src/components/header/index.vue
  31. 177 76
      src/pages/course-detail/index.vue
  32. 1 1
      src/pages/goods-detail/bank-detail.vue
  33. 59 7
      src/pages/goods-detail/live-detail.vue
  34. 9 0
      src/pages/home/index.vue
  35. 402 149
      src/pages/live-detail/index.vue
  36. 1 1
      src/pages/live-list/index.vue
  37. 277 36
      src/pages/living-room/index.vue
  38. 8 0
      src/pages/person-center/index.vue
  39. 325 0
      src/pages/person-center/my-live/index.vue
  40. 155 39
      src/pages/person-center/my-mock/index.vue
  41. 30 0
      src/router/index.js

+ 1 - 0
.gitignore

@@ -12,3 +12,4 @@ yarn-error.log*
 *.ntvs*
 *.njsproj
 *.sln
+/dist.rar

+ 39 - 1
src/apis/course.js

@@ -247,5 +247,43 @@ export default {
 		})
 	},
 
-  
+  goodsListGoodsUserLive(data) {
+		return request({
+			url:`/goods/listGoodsUserLive`,
+			method: 'get',
+			params:data
+		})
+	},
+
+  polyvLiveHistoryChatMsgList(data) {
+		return request({
+			url: '/polyv/live/historyChatMsgList',
+			method: 'get',
+			params:data
+		})
+	},
+
+  studyRecordQueryLiveLast(data) {
+		return request({
+			url: '/study/record/queryLiveLast',
+			method: 'get',
+			params:data
+		})
+	},
+
+	studyRecordGetLastLive(data) {
+		return request({
+			url: '/study/record/getLastLive',
+			method: 'get',
+			params: data
+		})
+	},
+
+  goodsLivingSectionList(data) {
+		return request({
+			url: '/goods/livingSectionList',
+			method: 'get',
+			params:data
+		})
+	},
 }

+ 40 - 0
src/apis/mock.js

@@ -21,6 +21,46 @@ export default {
 			method: 'get',
 		})
 	},
+
+  mockSubscribe(data) {
+		return request({
+			url: '/mock/subscribe',
+			method: 'post',
+			data
+		})
+	},
+	
+	mockSubscribeListSubscribe(data) {
+		return request({
+			url: '/mock/subscribe/listSubscribe',
+			method: 'GET',
+			params:data
+		})
+	},
+	
+	mockRecord(data) {
+		return request({
+			url: '/mock/record',
+			method: 'post',
+			data
+		})
+	},
+	
+	mockRecordEdit(data) {
+		return request({
+			url: '/mock/record/edit',
+			method: 'post',
+			data
+		})
+	},
+	
+	mockWrongRecordWrongNum(data) {
+		return request({
+			url:`/mock/wwrong/record/wrongNum/${data}`,
+			method: 'get'
+		})
+	},
+	
   
   
   

BIN
src/assets/css/img/btn-like.png


BIN
src/assets/css/img/emotion.png


BIN
src/assets/css/img/favicon.ico


BIN
src/assets/css/img/flower.png


BIN
src/assets/css/img/like.png


BIN
src/assets/css/img/more.png


BIN
src/assets/css/img/person.png


BIN
src/assets/css/img/show-more.png


+ 205 - 0
src/assets/css/mobile.css

@@ -0,0 +1,205 @@
+.plv-watch-mobile {
+  position: absolute;
+  display: flex;
+  height: 100%;
+  width: 100%;
+  flex-direction: column;
+  font-size: 12px;
+}
+
+.plv-watch-mobile__top {
+  padding-top: 56.25%;
+  height: 0;
+  position: relative;
+}
+
+.plv-watch-mobile-player {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 100%;
+}
+
+.plv-watch-mobile-chatroom {
+  flex: 1;
+  overflow: hidden;
+}
+
+/* 移动端聊天室SDK样式覆写 */
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room {
+  background: #202127;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-cr-head {
+  background: #3e3e4e;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-cr-navbar {
+  color: #fff;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-cr-navbar>li.polyv-crn-active {
+  color: #fff;
+  border: 0
+}
+.plv-watch-mobile .plv-skin--dark li.polyv-crn-active>span {
+  display: inline-block;
+  line-height: 35px;
+  border-bottom: 2px solid #fff;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room>.polyv-cr-body {
+  background: #202127;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-input {
+  background: #202127;
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-chat-input input {
+  color: #e4e4e4;
+  background: #2b2c35;
+  border: 0
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-mobile-send {
+  color: #fff;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-emotion-wrap {
+  background: #202127;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-emotion-wrap:after {
+  border-color: #202127 transparent transparent;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-chat-list>.polyv-msg {
+  color: #adadc0;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-msg-content {
+  background: #2b2c35;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-chat-input .polyv-icon-emotion {
+  background: url('./img/emotion.png');
+  background-size: 20px 20px;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room .polyv-chat-input .polyv-icon-flower {
+  background: url('./img/flower.png');
+  background-size: 20px 20px;
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-chat-input .polyv-icon-more {
+  background: url('./img/more.png');
+  background-size: 20px 20px;
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-show-more .polyv-icon-more {
+  background: url('./img/show-more.png');
+  background-size: 20px 20px;
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room>.polyv-cr-body .polyv-set-nickname.show {
+  background: #3e3e4e
+}
+.plv-watch-mobile .plv-skin--dark .polyv-chat-room>.polyv-cr-body .polyv-set-nickname input {
+  background: #212121;
+  border: 0;
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-set-nickname>div>button {
+  color: #fff;
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-chat-input-more {
+  background: #3e3e4e;
+}
+.plv-watch-mobile .plv-skin--dark .mobile-wrap .polyv-more-control-list>li>span {
+  color: #fff;
+}
+
+/* 移动端直播介绍 */
+.tab-intro {
+  overflow-y: auto;
+}
+
+.tab-intro .tab-intro-info {
+  position: relative;
+  padding: 16px;
+  display: flex;
+}
+.tab-intro .tab-intro-info__logo {
+  width: 40px;
+  height: 40px;
+  margin-right: 10px;
+}
+.tab-intro-info__inner {
+  position: relative;
+  flex: 1;
+}
+.tab-intro-info__title {
+  color: #fff;
+  line-height: 20px;
+  font-size: 16px;
+}
+
+.tab-intro .tab-intro-info__status::after {
+  position: absolute;
+  top: 0;
+  right: 0;
+  border-radius: 2px;
+  font-size: 12px;
+  padding: 4px;
+  border: 1px solid;
+  line-height: 1;
+}
+
+.tab-intro .tab-intro-info__status--nolive::after {
+  border-color: hsla(0,0%,100%,.6);
+  color: hsla(0,0%,100%,.6);
+  content: '暂无直播'
+}
+
+.tab-intro .tab-intro-info__status--playback::after {
+  color: #78a7ed;
+  border-color: #78a7ed;
+  content: '回放中'
+}
+
+.tab-intro .tab-intro-info__status--live::after {
+  color: #f06e6e;
+  border-color: #f06e6e;
+  content: '进行中'
+}
+
+.tab-intro .tab-intro-info__time {
+  margin-top: 8px;
+  color: #adadc0;
+  line-height: 1;
+  font-size: 12px;
+}
+
+.tab-intro .tab-intro-author {
+  display: flex;
+  padding: 10px 16px;
+  border-top: 1px solid #000;
+  border-bottom: 1px solid #000;
+  font-size: 12px;
+  color: #adadc0;
+}
+
+.tab-intro-author__publisher {
+  flex: 1;
+}
+
+.tab-intro .tab-intro-author__publisher-ico {
+  display: inline-block;
+  width: 16px;
+  height: 16px;
+  vertical-align: bottom;
+  background: url(./img/person.png) no-repeat;
+  background-size: 16px 16px;
+  margin-right: 2px;
+}
+
+.tab-intro .tab-intro-author__like-ico {
+  display: inline-block;
+  width: 14px;
+  height: 14px;
+  vertical-align: text-top;
+  background: url(./img/like.png) no-repeat;
+  background-size: 14px 14px;
+  margin-right: 2px;
+}
+
+.tab-intro .tab-intro-desc {
+  padding:  20px 16px;
+  color: #adadc0;
+  white-space: pre-wrap;
+  font-size: 16px;
+}

+ 332 - 0
src/assets/css/pc.css

@@ -0,0 +1,332 @@
+body {
+  /* background-color: #141518; */
+}
+
+.plv-watch-pc {
+  width: 1272;
+  margin: auto;
+  /* padding-top: 50px; */
+  background-color: #141518
+}
+
+.plv-pc-menu__container {
+  width: 1272;
+  margin: auto;
+  background: #fff;
+}
+
+/* 适配不同屏幕尺寸 */
+@media (min-width: 1366px) {
+  .plv-watch-pc {
+    width: 1247px;
+  }
+
+  .plv-pc-menu__container {
+    width: 1247px;
+  }
+}
+
+
+
+.plv-watch-pc__top {
+  position: relative;
+}
+
+.plv-watch-pc__top .pv-ppt-controller {
+  width: 76.2%;
+  z-index: 99;
+}
+
+/* 保持比例撑起高度 9:16=高:宽=56.25% */
+.plv-watch-pc__screen__height {
+  position: relative;
+  height: 0;
+  padding-top: 56.25%;
+}
+
+.plv-watch-pc__screen__inner {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+}
+
+/* 主屏(左侧) */
+.plv-watch-pc__screen-main {
+  width: 76.2%;
+}
+
+/* 辅屏(右侧) */
+.plv-watch-pc__screen-sub {
+  position: absolute;
+  left: 76.2%;
+  right: 0;
+  top: 0;
+}
+
+/* 侧栏聊天室 */
+.plv-watch-pc__side {
+  position: absolute;
+  left: 76.2%;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
+
+.plv-watch-pc__chat {
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding-top: 56.25%;
+  width: 100%;
+  height: 100%;
+}
+
+/* 普通直播,没有辅屏 */
+.plv-watch-pc--alone .plv-watch-pc__chat {
+  padding-top: 0;
+}
+
+
+/* 聊天室样式覆写 */
+.plv-watch-pc .plv-skin--dark .polyv-chat-room {
+  background-color: #202127;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-cr-navbar {
+  background-color: #3e3e4e;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-cr-navbar>li {
+  color: #adadc0;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-cr-navbar>li.polyv-crn-active {
+  color: #fff;
+  border-bottom: 0
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-cr-navbar>li.polyv-crn-active>span:first-child {
+  border-bottom: 3px solid #fff;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-cr-navbar>li>span:first-child {
+  display: inline-block;
+  line-height: 35px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-cr-navbar>li>span {
+  display: inline-block;
+  line-height: 35px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room>.polyv-cr-body {
+  background-color: #202127;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-input {
+  background-color: #3e3e4e;
+}
+
+.plv-watch-pc .plv-skin--dark .tab-chat-content::-webkit-scrollbar {
+  width: 6px;
+}
+
+.plv-watch-pc .plv-skin--dark .tab-chat-content::-webkit-scrollbar-thumb {
+  border-radius: 3px;
+  background-color: #46464f;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-msg-content {
+  background: #2b2c35;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-emotion-wrap {
+  background: #202127;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-emotion-wrap:after {
+  border-color: #202127 transparent transparent;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-input textarea {
+  background: #2e2e36;
+  padding: 4px;
+  color: #fff;
+  margin-bottom: 5px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-btn-info {
+  background: #2b2c35;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-input .polyv-icon-emotion {
+  background: url('../img/emotion.png');
+  background-size: 18px 18px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-input .polyv-icon-flower {
+  background: url('../img/flower.png');
+  background-size: 18px 18px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-input .polyv-icon-like {
+  background: url('../img/like.png');
+  background-size: 18px 18px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-input .polyv-pc-only-teacher {
+  color: #fff;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-input-top {
+  padding-bottom: 5px;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room>.polyv-cr-body .polyv-set-nickname.show {
+  background: #3e3e4e
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room>.polyv-cr-body .polyv-set-nickname input {
+  background: #212121;
+  border: 0;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room>.polyv-cr-body .polyv-set-nickname .polyv-btn {
+  background: #3e3e4e;
+  color: #888;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room>.polyv-cr-body .polyv-set-nickname .polyv-btn-info {
+  background: #2b2c35;
+  color: #fff;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-chat-list>.polyv-msg {
+  color: #adadc0;
+}
+
+.plv-watch-pc .plv-skin--dark .polyv-chat-room .polyv-fr>span {
+  color: #adadc0;
+}
+
+
+/* 全屏样式处理 */
+.plv-watch-pc__top--fullscreen .plv-watch-pc__screen-main {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 88;
+}
+
+.plv-watch-pc__top--fullscreen .plv-watch-pc__screen-main .plv-watch-pc__screen__height {
+  position: static;
+}
+
+.plv-watch-pc__top--fullscreen .plv-watch-pc__side {
+  display: none;
+}
+
+.plv-watch-pc__top--fullscreen .plv-watch-pc__screen-sub {
+  position: static;
+}
+
+.plv-watch-pc .plv-watch-pc__top--fullscreen .pv-ppt-controller {
+  width: 100%;
+}
+
+
+/* 频道信息 */
+.plv-watch-pc__info {
+  display: none;
+  padding: 30px 0;
+  color: #fff;
+  font-size: 0;
+}
+
+.plv-watch-pc__info__logo {
+  width: 50px;
+  margin-right: 10px;
+}
+
+.plv-watch-pc__info__desc {
+  display: inline-block;
+  vertical-align: top;
+}
+
+.plv-watch-pc__info__desc__name {
+  margin-bottom: 8px;
+  line-height: 24px;
+  font-size: 18px;
+}
+
+.plv-watch-pc__info__desc__publisher-ico {
+  display: inline-block;
+  width: 18px;
+  height: 18px;
+  vertical-align: middle;
+  background: url(../img/person.png) no-repeat;
+  background-size: 18px 18px;
+  margin-right: 4px;
+}
+
+.plv-watch-pc__info__desc__publisher,
+.plv-watch-pc__info__desc__view {
+  font-size: 14px;
+  vertical-align: middle;
+}
+
+.plv-watch-pc__info__desc__publisher::after {
+  content: '|';
+  margin: 0 16px;
+}
+
+
+/* IE*/
+.plv-watch-pc .ply-liveppt-container>object {
+  width: 100%;
+  height: 100%;
+}
+
+/*PC 菜单栏 */
+
+.plv-pc-menu {
+  background: #fff;
+  margin: auto;
+}
+
+.plv-pc-menu__tab {
+  border-bottom: 1px solid #ededef;
+}
+
+.plv-pc-menu__tab>li {
+  padding: 0 15px;
+  display: inline-block;
+  height: 80px;
+  line-height: 80px;
+  font-size: 18px;
+  color: #aaa;
+  border-bottom: 2px solid transparent;
+  cursor: pointer;
+}
+
+.plv-pc-menu__tab>li.active {
+  color: #333;
+  border-bottom: 2px solid #2196f3;
+}
+
+.plv-pc-menu__content {
+  padding: 40px 0;
+  min-height: 200px;
+}
+
+.plv-pc-menu__content>div {
+  display: none;
+}
+
+.plv-pc-menu__content>div.active {
+  display: block;
+}

+ 146 - 0
src/assets/css/public.css

@@ -0,0 +1,146 @@
+* {
+  box-sizing: border-box;
+}
+
+html, body, p {
+  margin: 0;
+  padding: 0;
+}
+
+body {
+  font-size: 14px;
+}
+
+.plv-config {
+  position: fixed;
+  width: 300px;
+  height: 430px;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  padding: 20px;
+  margin: auto;
+  text-align: center;
+  background: #fff;
+  border-radius: 2px;
+}
+
+.plv-config__title {
+  font-size: 18px;
+  font-weight: 400;
+  margin-top: 20px
+}
+
+.plv-config__content {
+  margin-top: 40px;
+}
+
+.plv-config__input {
+  position: relative;
+  margin: 0 auto;
+  margin-bottom: 20px;
+  padding: 0 5px;
+  width: 220px;
+  height: 38px;
+  line-height: 38px;
+  border: 1px solid #bfbfbf;
+  border-radius: 3px;
+}
+
+.plv-config__checkbox {
+  text-align: left;
+  font-size: 13px;
+}
+
+.plv-config__checkbox__input {
+  margin-left: 20px;
+  vertical-align: top;
+}
+
+.plv-config__button {
+  margin-top: 7px;
+  width: 220px;
+  line-height: 38px;
+  background: #222791;
+  color: #fff;
+  border-radius: 3px;
+  outline: none;
+  border: none;
+}
+
+/* 点赞 */
+.plv-watch__likes {
+  position: absolute;
+  text-align: center;
+}
+
+.plv-watch-pc .plv-watch__likes {
+  /* pc端位置 */
+  right: 30px;
+  top: 20%;
+  bottom: auto;
+}
+#tab-chat .plv-watch__likes {
+  /* 移动端位置 */
+  right: 16px;
+  bottom: 120px;
+}
+.plv-watch__likes-icon {
+  display: inline-block;
+  width: 40px;
+  height: 40px;
+  background: url('../img/btn-like.png');
+  background-size: cover;
+  cursor: pointer;
+}
+.plv-watch__likes-num {
+  color: #adadc0;
+  font-size: 14px;
+  opacity: 0.8;
+}
+
+/* 直播状态 */
+.plv-watch-mobile #plv-watch__status {
+  position: absolute;
+  top: 0;
+  right: 0;
+}
+
+.plv-watch-mobile #plv-watch__status::after {
+  border-radius: 2px;
+  font-size: 12px;
+  padding: 4px;
+  border: 1px solid;
+  line-height: 1;
+}
+
+.plv-watch-pc #plv-watch__status {
+  display: inline-block;
+  margin-left: 10px;
+}
+.plv-watch-pc #plv-watch__status::after {
+  border-radius: 2px;
+  font-size: 12px;
+  padding: 0 4px;
+  border: 1px solid;
+  line-height: 1;
+}
+
+.plv-watch__status--end::after {
+  border-color: hsla(0,0%,100%,.6);
+  color: hsla(0,0%,100%,.6);
+  content: '暂无直播'
+}
+
+.plv-watch__status--playback::after {
+  color: #78a7ed;
+  border-color: #78a7ed;
+  content: '回放中'
+}
+
+.plv-watch__status--live::after {
+  color: #f06e6e;
+  border-color: #f06e6e;
+  content: '进行中'
+}

+ 38 - 0
src/assets/css/tool.css

@@ -0,0 +1,38 @@
+.tool-entrance {
+  position: absolute;
+  z-index: 99;
+  top: 0;
+  left: -30px;
+  bottom: 0;
+  margin: auto;
+  display: inline-block;
+  width: 30px;
+  height: 85px;
+  padding: 5px;
+  background: #333;
+  text-align: center;
+  color: #fff;
+  cursor: pointer;
+  user-select: none;
+}
+
+.tool-main {
+  position: absolute;
+  z-index: 90;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background: #ccc;
+}
+.tool-input-group > input {
+  width: 40%;
+}
+.tool-input-group > button {
+  width: 50%;
+}
+
+
+.tool-btn {
+  box-sizing: border-box;
+  margin: 5px;
+}

BIN
src/assets/img/btn-like.png


BIN
src/assets/img/emotion.png


BIN
src/assets/img/favicon.ico


BIN
src/assets/img/flower.png


BIN
src/assets/img/like.png


BIN
src/assets/img/more.png


BIN
src/assets/img/person.png


BIN
src/assets/img/show-more.png


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
src/assets/jquery.min.js


BIN
src/assets/live-bg.png


BIN
src/assets/live.png


BIN
src/assets/living.gif


+ 3 - 1
src/axios.js

@@ -1,7 +1,9 @@
 import axios from 'axios'
 import store from './store'
 // export const BASE_URL = 'https://api.xyyxt.net'   //release
-export const BASE_URL = 'http://42.192.164.187:19005'    //test
+// export const BASE_URL = 'http://42.192.164.187:19005'    //test
+// export const BASE_URL = 'http://120.79.166.78:19009'   //预发布
+export const BASE_URL = 'http://192.168.1.222:5055'    //dev
 export const tenantId = '867735392558919680'
 
 

+ 32 - 2
src/components/goodsItem/index.vue

@@ -2,7 +2,13 @@
   <div>
     <div class="course-item" @click="goodsDetail(item)">
       <div class="course-item__img">
-        <div class="note" v-if="item.year">{{ item.year }}</div>
+        <div
+          class="note"
+          :class="{ note__yellow: item.goodsType == 6 }"
+          v-if="item.year"
+        >
+          {{ item.year }}
+        </div>
         <img
           v-if="item.coverUrl"
           :src="$tools.splitImgHost(item.coverUrl)"
@@ -10,6 +16,7 @@
         />
       </div>
       <div class="course-item__title">
+        <span v-if="item.goodsType == 6" class="note">直播</span>
         {{ item.goodsName }}
       </div>
       <div class="course-item__desc">
@@ -61,6 +68,12 @@ export default {
             path: "/bank-detail/" + res.goodsId,
           });
         }
+
+        if (res.goodsType === 6) {
+          this.$router.push({
+            path: "/live-detail/" + res.goodsId,
+          });
+        }
       });
     },
 
@@ -79,7 +92,7 @@ export default {
           if (res.goodsType === 1) {
             this.$refs.selectClassModal.showModal(res);
           }
-          if (res.goodsType === 2) {
+          if (res.goodsType === 2 || res.goodsType === 6) {
             let selectGoodsList = JSON.parse(JSON.stringify([res]));
             localStorage.setItem(
               "checkGoodsList",
@@ -174,6 +187,10 @@ export default {
       text-align: center;
       line-height: 24px;
       color: #fff;
+
+      &__yellow {
+        background: #ffb001;
+      }
     }
     img {
       width: 100%;
@@ -190,6 +207,19 @@ export default {
     line-height: 24px;
     height: 48px;
     overflow: hidden;
+
+    .note {
+      display: inline-block;
+      width: 48px;
+      height: 20px;
+      background: #fff8e8;
+      border: 1px solid #ffb001;
+      border-radius: 10px;
+      text-align: center;
+      color: #ffb001;
+      line-height: 18px;
+      font-size: 12px;
+    }
   }
 
   &__desc {

+ 42 - 0
src/components/header/index.vue

@@ -18,6 +18,7 @@
             <a v-if="item.name == '课程'" @click="go('/course-list')">课程</a>
             <a v-if="item.name == '题库'" @click="go('/bank-list')">题库</a>
           </li>
+          <li><a @click="go('/live-list')">直播</a></li>
         </ul>
       </nav>
 
@@ -65,6 +66,7 @@
           <select v-model="type">
             <option value="1">课程</option>
             <option value="2">题库</option>
+            <option value="6">直播</option>
           </select>
         </div>
         <div class="search__input">
@@ -160,6 +162,13 @@ export default {
         //在题库列表页面直接传参
         if (type == "2") {
           this.$emit("search", this.searchKey);
+        } else if (type == "6") {
+          this.$router.push({
+            path: "/live-list",
+            query: {
+              searchKey: this.searchKey,
+            },
+          });
         } else {
           this.$router.push({
             path: "/course-list",
@@ -172,6 +181,32 @@ export default {
         //在课程列表页面直接传参
         if (type == "1") {
           this.$emit("search", this.searchKey);
+        } else if (type == "6") {
+          this.$router.push({
+            path: "/live-list",
+            query: {
+              searchKey: this.searchKey,
+            },
+          });
+        } else {
+          this.$router.push({
+            path: "/bank-list",
+            query: {
+              searchKey: this.searchKey,
+            },
+          });
+        }
+      } else if (path == "/live-list") {
+        //在课程列表页面直接传参
+        if (type == "6") {
+          this.$emit("search", this.searchKey);
+        } else if (type == "1") {
+          this.$router.push({
+            path: "/course-list",
+            query: {
+              searchKey: this.searchKey,
+            },
+          });
         } else {
           this.$router.push({
             path: "/bank-list",
@@ -190,6 +225,13 @@ export default {
               searchKey: this.searchKey,
             },
           });
+        } else if (type == "6") {
+          this.$router.push({
+            path: "/live-list",
+            query: {
+              searchKey: this.searchKey,
+            },
+          });
         } else {
           this.$router.push({
             path: "/bank-list",

+ 177 - 76
src/pages/course-detail/index.vue

@@ -163,7 +163,7 @@
                                                 >
                                                   {{ section.name }}
                                                   <div
-                                                    style="zoom: 0.7"
+                                                    style="font-size: 12px"
                                                     v-if="
                                                       section.liveStartTime >
                                                       nowTime
@@ -377,7 +377,7 @@
                                               >
                                                 {{ section.name }}
                                                 <div
-                                                  style="zoom: 0.7"
+                                                  style="font-size: 12px"
                                                   v-if="
                                                     section.liveStartTime >
                                                     nowTime
@@ -556,7 +556,7 @@
                                           <div class="bank-section__item__text">
                                             {{ menu.name }}
                                             <div
-                                              style="zoom: 0.7"
+                                              style="font-size: 12px"
                                               v-if="
                                                 menu.liveStartTime > nowTime
                                               "
@@ -733,7 +733,7 @@
                                                 >
                                                   {{ section.name }}
                                                   <div
-                                                    style="zoom: 0.7"
+                                                    style="font-size: 12px"
                                                     v-if="
                                                       section.liveStartTime >
                                                       nowTime
@@ -947,7 +947,7 @@
                                               >
                                                 {{ section.name }}
                                                 <div
-                                                  style="zoom: 0.7"
+                                                  style="font-size: 12px"
                                                   v-if="
                                                     section.liveStartTime >
                                                     nowTime
@@ -1126,7 +1126,7 @@
                                           <div class="bank-section__item__text">
                                             {{ menu.name }}
                                             <div
-                                              style="zoom: 0.7"
+                                              style="font-size: 12px"
                                               v-if="
                                                 menu.liveStartTime > nowTime
                                               "
@@ -1700,10 +1700,10 @@
               :label="item.fieldName"
               :required="item.required"
               label-width="120px"
-              :disabled="true"
               :prop="item.required ? item.fieldKey : ''"
             >
               <el-input
+                :disabled="true"
                 v-model="infoForm.name"
                 :placeholder="`请输入${item.fieldName}`"
               />
@@ -1713,11 +1713,11 @@
               v-if="item.fieldKey == 'idcard'"
               :label="item.fieldName"
               :required="item.required"
-              :disabled="true"
               label-width="120px"
               :prop="item.required ? item.fieldKey : ''"
             >
               <el-input
+                :disabled="true"
                 v-model="infoForm.idcard"
                 :placeholder="`请输入${item.fieldName}`"
               />
@@ -1725,13 +1725,13 @@
             <el-form-item
               :key="index"
               v-if="item.fieldKey == 'telphone'"
-              :disabled="true"
               :label="item.fieldName"
               :required="item.required"
               label-width="120px"
               :prop="item.required ? item.fieldKey : ''"
             >
               <el-input
+                :disabled="true"
                 v-model="infoForm.telphone"
                 :placeholder="`请输入${item.fieldName}`"
               />
@@ -2313,6 +2313,7 @@ export default {
       menuList: [],
       goodsData: {},
       tabList: [],
+      historyChatMsgList: [],
       vid: "",
       vidzb: "",
       player: "",
@@ -2569,6 +2570,7 @@ export default {
       needOpen: true, //是否需要展开第一章节
       menuIndex: [],
       clickLock: false,
+      liveLast: null,
     };
   },
   computed: {
@@ -2626,7 +2628,7 @@ export default {
       //   earlyTime = liveMenu[0].liveStartTime;
       // }
 
-      this.courseCourseList();
+      await this.courseCourseList();
       if (this.sectionItem.recordingUrl) {
         let noteSecond = this.$route.query.noteSecond;
         if (noteSecond > 0) {
@@ -2644,6 +2646,8 @@ export default {
             this.noteClick(item);
           }, 1000);
         }
+      } else {
+        this.studyRecordQueryLiveLast();
       }
       // let noteSecond = this.$route.query.noteSecond;
       // if (noteSecond > 0) {
@@ -2687,6 +2691,63 @@ export default {
   },
   methods: {
     ...mapMutations(["getCartCount"]),
+    isLast(item) {
+      if (this.liveLast) {
+        let sectionASame =
+          this.liveLast.sectionId == (item.sectionId || item.menuId);
+        let chapterSame = this.liveLast.chapterId == (item.chapterId || 0);
+        let moduleSame = this.liveLast.moduleId == (item.moduleId || 0);
+
+        return sectionASame && chapterSame && moduleSame;
+      } else {
+        return false;
+      }
+    },
+    /**
+     * 获取上次观看的直播
+     */
+    studyRecordGetLastLive() {
+      this.$request
+        .studyRecordGetLastLive({
+          orderGoodsId: this.orderGoodsId,
+          courseId: this.courseId,
+        })
+        .then((res) => {
+          this.liveLast = res.data;
+        });
+    },
+    studyRecordQueryLiveLast() {
+      this.$request
+        .studyRecordQueryLiveLast({
+          orderGoodsId: this.orderGoodsId,
+          courseId: this.courseId,
+        })
+        .then((res) => {
+          console.log(res, "couse");
+          if (res.data) {
+            if (res.data.sectionType == 1) {
+              //录播
+              this.chapterId = res.data.chapterId;
+              this.moduleId = res.data.moduleId;
+              this.playSectionId = res.data.sectionId;
+              this.vid = res.data.recordingUrl;
+              this.sectionItem = res.data;
+              this.playVideo(res.data);
+            } else if (res.data.sectionType == 2) {
+              //直播
+              this.studyRecordGetLastLive();
+            } else if (res.data.sectionType == 3) {
+              //回放
+              this.chapterId = res.data.chapterId;
+              this.moduleId = res.data.moduleId;
+              this.playSectionId = res.data.sectionId;
+              this.vid = res.data.recordingUrl;
+              this.sectionItem = res.data;
+              this.playVideo(res.data);
+            }
+          }
+        });
+    },
     /**
      * 
      获取推荐列表
@@ -2799,7 +2860,7 @@ export default {
       this.$upload
         .upload(file, 0)
         .then((res) => {
-          this.$set(this.stampForm, "commitment_seal", res);
+          this.$set(this.infoForm, "commitment_seal", res);
           this.fileListStamp = [
             {
               name: res,
@@ -4217,32 +4278,47 @@ export default {
      * 切换科目
      */
     courseChange() {
-      this.noteParams = {
-        pageNum: 1,
-        // pageSize: 4,
-      };
-      this.duration = 0;
-      this.playSectionId = 0;
-      this.vid = "";
-      if (this.player) {
-        this.player.destroy();
-      }
-      this.player = "";
-      if (this.playerzb) {
-        this.playerzb.destroy();
-      }
-      this.playerzb = "";
-      this.vidzb = "";
-      this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
-      this.courseDetail(); //课程详情
-      this.getGoodsDetail(); //商品详情
-      this.getAnswerList(); //答疑列表
-      this.answerTimer = setInterval(() => {
-        this.getAnswerList();
-      }, 5000);
-      this.getMenuList(); //学习目录
-      this.getReMenuList(); //获取重修目录
-      this.getNoteList(); //获取节笔记
+      return new Promise((resolve) => {
+        this.noteParams = {
+          pageNum: 1,
+          // pageSize: 4,
+        };
+        this.duration = 0;
+        this.playSectionId = 0;
+        this.vid = "";
+        if (this.player) {
+          this.player.destroy();
+        }
+        this.player = "";
+        if (this.playerzb) {
+          this.playerzb.destroy();
+        }
+        this.playerzb = "";
+        this.vidzb = "";
+        this.historyChatMsgList = [];
+        this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
+        this.courseDetail(); //课程详情
+        this.getGoodsDetail(); //商品详情
+        this.getAnswerList(); //答疑列表
+        this.answerTimer = setInterval(() => {
+          this.getAnswerList();
+        }, 5000);
+        this.getMenuList(); //学习目录
+        this.getReMenuList(); //获取重修目录
+        this.getNoteList(); //获取节笔记
+
+        resolve();
+      });
+    },
+    polyvLiveHistoryChatMsgList() {
+      this.$request
+        .polyvLiveHistoryChatMsgList({
+          sectionId: this.playSectionId,
+          channelId: this.sectionItem.liveUrl,
+        })
+        .then((res) => {
+          this.historyChatMsgList = res.data;
+        });
     },
     courseDetail() {
       let self = this;
@@ -4398,8 +4474,12 @@ export default {
 
           if (this.needOpen) {
             this.needOpen = false;
-            if (chapter.list && !this.sectionItem.recordingUrl) {
-              this.getResource(chapter.list[0]);
+            if (
+              chapter.list &&
+              !this.sectionItem.recordingUrl &&
+              this.sectionItem.sectionType != 2
+            ) {
+              // this.getResource(chapter.list[0]);
             }
           }
         });
@@ -4860,6 +4940,10 @@ export default {
         await this.clears();
 
         this.vid = option.recordingUrl;
+        this.historyChatMsgList = [];
+        if (option.sectionType == 3) {
+          this.polyvLiveHistoryChatMsgList();
+        }
         this.loadPlayerScript(this.loadPlayer);
         setTimeout(() => {
           this.clickLock = false;
@@ -4896,14 +4980,23 @@ export default {
         //设置播放的节ID
         await this.clears();
         this.vidzb = option.liveUrl;
-        this.loadPlayerScriptzb(this.loadPlayerzb);
-        setTimeout(() => {
-          this.clickLock = false;
-        }, 3000);
-        // uni.$emit("levelId", this.levelId);
-        // uni.$emit("getChannel", this.menuItem);
-        // uni.$emit("isRebuild", this.isRebuild);
-        // console.log(this.menuItem, "menuItem");
+
+        this.$router.push({
+          path: "/living-room/" + option.liveUrl,
+          query: {
+            goodsId: this.goodsId,
+            courseId: this.courseId,
+            gradeId: this.gradeId,
+            orderGoodsId: this.orderGoodsId,
+            sectionId: option.sectionId || option.menuId,
+            chapterId: option.chapterId || 0,
+            moduleId: option.moduleId || 0,
+          },
+        });
+        // this.loadPlayerScriptzb(this.loadPlayerzb);
+        // setTimeout(() => {
+        //   this.clickLock = false;
+        // }, 3000);
       }
     },
 
@@ -5399,7 +5492,10 @@ export default {
         chapterId: parseInt(this.chapterId),
         moduleId: parseInt(this.moduleId),
         videoCurrentTime: parseInt(currentTime > 0 ? currentTime : 0),
+        orderGoodsId: parseInt(this.orderGoodsId),
       };
+
+      console.log(data, "data");
       if (status > 0) {
         data.status = status;
       }
@@ -5857,9 +5953,10 @@ export default {
             if (self.menuList.length) {
               if (
                 self.menuList[0].type == 3 &&
-                !this.sectionItem.recordingUrl
+                !this.sectionItem.recordingUrl &&
+                self.menuList[0].sectionType != 2
               ) {
-                this.getResource(self.menuList[0]);
+                // this.getResource(self.menuList[0]);
               }
             }
           }
@@ -5918,20 +6015,22 @@ export default {
      * 获取讲义权限
      */
     courseHandouts() {
-      this.$request
-        .courseHandouts(this.goodsData.handoutsId)
-        .then((res) => {
-          this.courseHandoutsData = res.data;
-          const loadingTask = pdf.createLoadingTask(
-            this.$tools.splitImgHost(this.courseHandoutsData.handoutsUrl)
-          );
-          loadingTask.promise
-            .then((pdf) => {
-              this.numPages = pdf.numPages;
-            })
-            .catch((err) => {});
-        })
-        .catch((err) => {});
+      if (this.goodsData.handoutsId) {
+        this.$request
+          .courseHandouts(this.goodsData.handoutsId)
+          .then((res) => {
+            this.courseHandoutsData = res.data;
+            const loadingTask = pdf.createLoadingTask(
+              this.$tools.splitImgHost(this.courseHandoutsData.handoutsUrl)
+            );
+            loadingTask.promise
+              .then((pdf) => {
+                this.numPages = pdf.numPages;
+              })
+              .catch((err) => {});
+          })
+          .catch((err) => {});
+      }
     },
 
     /**
@@ -6045,15 +6144,19 @@ export default {
         });
     },
     courseCourseList() {
-      this.param.goodsId = this.goodsId;
-      this.param.gradeId = this.gradeId;
-      this.$request.courseCourseList(this.param).then((res) => {
-        this.courseList.push(...res.rows);
-        if (!this.courseId) {
-          this.courseId = this.courseList[0].courseId;
-        }
-        this.param.total = res.total;
-        this.courseChange();
+      return new Promise((resolve) => {
+        this.param.goodsId = this.goodsId;
+        this.param.gradeId = this.gradeId;
+        this.$request.courseCourseList(this.param).then(async (res) => {
+          this.courseList.push(...res.rows);
+          if (!this.courseId) {
+            this.courseId = this.courseList[0].courseId;
+          }
+          this.param.total = res.total;
+          await this.courseChange();
+
+          resolve();
+        });
       });
     },
 
@@ -6298,9 +6401,7 @@ export default {
                         font-size: 14px;
 
                         &__text {
-                          height: 40px;
-                          line-height: 40px;
-                          padding-left: 24px;
+                          padding: 8px 8px 8px 24px;
                           cursor: pointer;
                           flex: 1;
 
@@ -6328,8 +6429,8 @@ export default {
                         }
 
                         &__text {
-                          padding-left: 12px;
                           flex: 1;
+                          padding: 8px 8px 8px 12px;
                           height: 40px;
                           display: flex;
                           flex-direction: column;

+ 1 - 1
src/pages/goods-detail/bank-detail.vue

@@ -202,7 +202,7 @@
                       <div class="right-box">
                         <div class="title">
                           推荐题库
-                          <span class="more">更多></span>
+                          <a class="more" @click="comeMoreList">更多></a>
                         </div>
                         <ul class="list">
                           <li

+ 59 - 7
src/pages/goods-detail/live-detail.vue

@@ -61,9 +61,9 @@
                   <el-tab-pane label="章节目录" name="2">
                     <div slot="label" style="position: relative">
                       <span class="label">章节目录</span>
-                      <span v-if="listenConfigList.length" class="view-note"
+                      <!-- <span v-if="listenConfigList.length" class="view-note"
                         >试看</span
-                      >
+                      > -->
                     </div>
                     <div class="goods-menu clearfix">
                       <div class="left-box">
@@ -146,6 +146,24 @@
                                               class="bank-section__item__text"
                                             >
                                               {{ section.name }}
+                                              <div
+                                                style="
+                                                  color: #999;
+                                                  font-size: 12px;
+                                                "
+                                              >
+                                                直播时间{{
+                                                  $tools.timestampToTime(
+                                                    section.liveStartTime
+                                                  )
+                                                }}
+                                                -
+                                                {{
+                                                  $tools.timestampToTime(
+                                                    section.liveEndTime
+                                                  )
+                                                }}
+                                              </div>
                                             </div>
                                             <div
                                               v-if="section.tryListen"
@@ -197,6 +215,25 @@
                                               class="bank-section__item__text"
                                             >
                                               {{ section.name }}
+                                              <div
+                                                style="
+                                                  color: #999;
+                                                  font-size: 12px;
+                                                "
+                                              >
+                                                直播时间
+                                                {{
+                                                  $tools.timestampToTime(
+                                                    section.liveStartTime
+                                                  )
+                                                }}
+                                                -
+                                                {{
+                                                  $tools.timestampToTime(
+                                                    section.liveEndTime
+                                                  )
+                                                }}
+                                              </div>
                                             </div>
                                             <div
                                               v-if="section.tryListen"
@@ -220,6 +257,21 @@
                                       <div class="bank-section__item">
                                         <div class="bank-section__item__text">
                                           {{ item.name }}
+                                          <div
+                                            style="color: #999; font-size: 12px"
+                                          >
+                                            直播时间{{
+                                              $tools.timestampToTime(
+                                                item.liveStartTime
+                                              )
+                                            }}
+                                            -
+                                            {{
+                                              $tools.timestampToTime(
+                                                item.liveEndTime
+                                              )
+                                            }}
+                                          </div>
                                         </div>
                                         <div
                                           v-if="item.tryListen"
@@ -239,7 +291,7 @@
                       </div>
                       <div class="right-box">
                         <div class="title" v-if="recommendList.goodsList">
-                          推荐课程
+                          推荐直播
                           <a class="more" @click="comeMoreList">更多></a>
                         </div>
                         <ul class="list" v-if="recommendList.goodsList">
@@ -618,7 +670,7 @@ export default {
      */
     comeMoreList() {
       this.$router.push({
-        path: "/course-list",
+        path: "/live-list",
         query: {
           educationId: this.goodsDetail.educationTypeId,
           projectId: this.goodsDetail.projectId,
@@ -644,7 +696,7 @@ export default {
       this.$request
         .appCommonActivityRecommendList({
           businessId: this.goodsDetail.businessId,
-          type: 1,
+          type: 6,
         })
         .then((res) => {
           if (res.rows.length) {
@@ -1534,7 +1586,7 @@ export default {
             let menuIndexOrFalse = await this.getCourseMenus(
               this.courseList[i]
             );
-
+            console.log(menuIndexOrFalse, 123);
             if (menuIndexOrFalse !== false) {
               this.menuIndex = [i, menuIndexOrFalse];
               this.openCourse(this.courseList[i]);
@@ -1550,7 +1602,7 @@ export default {
         this.$request.menuList({ courseId: item.courseId }).then((res) => {
           if (res.code == 200) {
             for (let i = 0; i < res.rows.length; i++) {
-              if (res.rows[i].type == 1 || res.rows[i].type == 2) {
+              if (res.rows[i].type == 3) {
                 resolve(i);
                 break;
               }

+ 9 - 0
src/pages/home/index.vue

@@ -45,6 +45,7 @@
               <select v-model="type">
                 <option value="1">课程</option>
                 <option value="2">题库</option>
+                <option value="6">直播</option>
               </select>
             </div>
             <div class="search__input">
@@ -97,6 +98,7 @@
               >题库</a
             >
           </template>
+          <a class="tab" @click="go('/live-list')">直播</a>
         </div>
       </div>
       <div class="swiper-wrap" :style="{ background: color }">
@@ -669,6 +671,13 @@ export default {
             searchKey: this.searchKey,
           },
         });
+      } else if (type == "6") {
+        this.$router.push({
+          path: "/live-list",
+          query: {
+            searchKey: this.searchKey,
+          },
+        });
       } else {
         this.$router.push({
           path: "/bank-list",

Dosya farkı çok büyük olduğundan ihmal edildi
+ 402 - 149
src/pages/live-detail/index.vue


+ 1 - 1
src/pages/live-list/index.vue

@@ -165,7 +165,7 @@ export default {
         pageNum: 1,
         pageSize: 15,
         goodsStatus: 1,
-        goodsType: 2,
+        goodsType: 6,
         sortType: 1,
         searchKey: "",
       },

+ 277 - 36
src/pages/living-room/index.vue

@@ -1,7 +1,64 @@
 <template>
   <div class="living-room">
     <Header></Header>
+
     <div class="container">
+      <div class="clearfix top-line">
+        <el-button
+          class="float-right"
+          type="primary"
+          size="small"
+          round
+          @click="$router.back(-1)"
+          >返回</el-button
+        >
+      </div>
+      <!-- pc端 -->
+      <div class="plv-watch-pc">
+        <div class="plv-watch-pc__top" id="plv-pc-top">
+          <div class="plv-watch-pc__screen plv-watch-pc__screen-main">
+            <div class="plv-watch-pc__screen__height">
+              <div class="plv-watch-pc__screen__inner" id="plv-pc-main"></div>
+            </div>
+          </div>
+
+          <div class="plv-watch-pc__screen plv-watch-pc__screen-sub">
+            <div class="plv-watch-pc__screen__height">
+              <div class="plv-watch-pc__screen__inner" id="plv-pc-side"></div>
+            </div>
+          </div>
+
+          <div class="plv-watch-pc__side">
+            <div
+              class="plv-watch-pc__chat plv-skin--dark"
+              id="plv-pc-chat"
+            ></div>
+          </div>
+        </div>
+
+        <div id="plv-pc-channel-info" class="plv-watch-pc__info">
+          <img
+            class="plv-watch-pc__info__logo"
+            src="https://live.polyv.cn/assets/wimages/pc_images/logo.png"
+          />
+          <div class="plv-watch-pc__info__desc">
+            <p class="plv-watch-pc__info__desc__name"></p>
+            <span class="plv-watch-pc__info__desc__publisher-ico"></span>
+            <span class="plv-watch-pc__info__desc__publisher"></span>
+            <span class="plv-watch-pc__info__desc__view"></span>
+          </div>
+        </div>
+      </div>
+
+      <!-- pc菜单栏 -->
+      <!-- <div class="plv-pc-menu">
+        <div class="plv-pc-menu__container">
+          <ul id="plv-menu-tab" class="plv-pc-menu__tab"></ul>
+          <div id="plv-menu-content" class="plv-pc-menu__content"></div>
+        </div>
+      </div> -->
+    </div>
+    <!-- <div class="container">
       <div ref="living" id="living" class="living">
         <div
           :style="
@@ -31,7 +88,7 @@
         <div ref="wrap" id="wrap"></div>
         <div class="controller" ref="controller"></div>
       </div>
-    </div>
+    </div> -->
     <Footer></Footer>
   </div>
 </template>
@@ -41,7 +98,11 @@ import Footer from "@/components/footer/index";
 import Header from "@/components/header/index";
 import ToolBar from "@/components/toolbar/index";
 import { mapGetters, mapMutations } from "vuex";
+import "@/assets/jquery.min.js";
 import "@/assets/css/chatroom.css";
+import "@/assets/css/pc.css";
+import "@/assets/css/tool.css";
+import "@/assets/css/public.css";
 
 export default {
   components: {
@@ -58,16 +119,41 @@ export default {
       appId: "",
       sign: "",
       timestamp: "",
+      timer: null,
       mediaChannelKey: "",
       changeState: false,
       liveSdk: null,
       token: "",
+      plv: {
+        liveSdk: null, // 保存直播 JS-SDK 实例
+        socket: null, // 保存 WebSocket 实例
+        scene: "", // 场景
+        mainPosition: "player", // 用于记录当前主屏幕是文档还是播放器
+      },
+      sectionId: 0,
+      goodsId: 0,
+      courseId: 0,
+      orderGoodsId: 0,
+      gradeId: 0,
+      chapterId: 0,
+      moduleId: 0,
+      playTime: 0,
+      duraing: 0,
+      timer: null,
+      isFirst: true,
     };
   },
   computed: {
     ...mapGetters(["userInfo"]),
   },
   mounted() {
+    this.sectionId = this.$route.query.sectionId;
+    this.goodsId = this.$route.query.goodsId;
+    this.courseId = this.$route.query.courseId;
+    this.orderGoodsId = this.$route.query.orderGoodsId;
+    this.gradeId = this.$route.query.gradeId;
+    this.chapterId = this.$route.query.chapterId;
+    this.moduleId = this.$route.query.moduleId;
     this.channelId = this.$route.params.channelId;
     this.playVideo();
   },
@@ -93,13 +179,39 @@ export default {
     },
 
     async playVideo() {
+      // await this.jquery();
       await this.loadPlayerScriptzb();
       await this.loadChatroomScriptzb();
       console.log(this.userInfo);
       this.polyvLivesign();
     },
 
+    jquery() {
+      return new Promise((resolve) => {
+        if (!window.polyvLivePlayer) {
+          const myScript = document.createElement("script");
+          myScript.setAttribute("src", "../../assets/jquery.min.js");
+          document.body.appendChild(myScript);
+          myScript.onload = resolve;
+        } else {
+          resolve();
+        }
+      });
+    },
+
     loadPlayerzb() {
+      var els = {
+        playerEl: "", // 播放器容器选择器, 移动端和PC的el参数设置不
+        pptEl: "", // 文档容器选择器, 普通直播不需要设置pptEl
+        controllerEl: "", // 三分屏控制栏的容器选择器, pc三分屏的场景才需要设置controllerEl,
+        chatContainer: "", // 聊天室的容器选择器
+        pptEl: "#tab-ppt",
+      };
+
+      els.chatContainer = "#plv-pc-chat"; // DOM选择器,HTML元素,用于渲染聊天室
+      els.pptEl = "#plv-pc-side"; // ppt文档元素选择器,非云课堂可不填
+      els.playerEl = "#plv-pc-main"; // 讲师区域元素
+      els.controllerEl = $("#plv-pc-top")[0]; // 控制栏父元素
       var chatroom = new PolyvChatRoom({
         //实例聊天室SDK
         roomId: this.channelId,
@@ -109,24 +221,29 @@ export default {
         pic:
           this.$tools.splitImgHost(this.userInfo.avatar, true) ||
           "http://livestatic.videocc.net/assets/wimages/missing_face.png",
-        container: "#wrap",
+        container: els.chatContainer,
         userType: "slice",
         version: "2.0",
         showUserList: false,
-        width: 300,
-        height: 400,
+        width: "100%",
+        height: "100%",
         token: this.token,
         mediaChannelKey: this.mediaChannelKey,
         roomMessage: (data) => {
           // data为聊天室socket消息,当有聊天室消息时会触发此方法
-          if (this.liveSdk && this.liveSdk.player) {
-            console.log(data.content);
-            this.liveSdk.player.sendBarrage(data.content);
+          console.log(data);
+          if (this.plv.liveSdk && this.plv.liveSdk.player) {
+            var event = data.EVENT;
+            if (event === "sendMessage" || event === "SPEAK") {
+              this.plv.liveSdk.player.sendBarrage(data.content);
+            }
           }
         },
       });
 
-      var liveSdk = new PolyvLiveSdk({
+      this.plv.socket = chatroom.chat.socket;
+
+      this.plv.liveSdk = new PolyvLiveSdk({
         //实例直播SDK
         channelId: this.channelId,
         appId: this.appId,
@@ -142,38 +259,98 @@ export default {
         },
       });
 
-      this.liveSdk = liveSdk;
+      this.plv.liveSdk.on(
+        PolyvLiveSdk.EVENTS.STREAM_UPDATE,
+        (event, status) => {
+          if (status == "end") {
+            clearInterval(this.timer);
+            let duraing = this.playTime - this.duraing;
+            this.duraing = 0;
+            this.studyRecord(1, duraing);
+          }
+        }
+      ); // 监听流状态变化
 
       // 第四步:监听频道信息读取完成事件,初始化播放器
-      liveSdk.on(PolyvLiveSdk.EVENTS.CHANNEL_DATA_INIT, (event, data) => {
-        liveSdk.setupPlayer({
-          pptEl: "#ppt",
-          el: "#player",
-          type: "auto",
-          switchPlayer: true,
-          controllerPosition: "ppt",
-          pptNavBottom: "180px",
-          controllerPosition: "player",
-          fixedController: true,
-          barrage: true,
-          defaultBarrageStatus: true,
-          controllerEl: this.$refs.controller,
-          fullscreenEl: this.$refs.ppt,
-          autoplay: true, // 设置自动播放
-        });
+      this.plv.liveSdk.on(
+        PolyvLiveSdk.EVENTS.CHANNEL_DATA_INIT,
+        (event, data) => {
+          this.plv.liveSdk.setupPlayer({
+            el: els.playerEl,
+            pptEl: els.pptEl,
+            pptPlaceholder: true,
+            switchPlayer: true,
+            controllerPosition: "ppt",
+            fixedController: true,
+            controllerEl: els.controllerEl,
+            pptNavBottom: "80px",
+            barrage: true, // 是否开启弹幕
+            defaultBarrageStatus: true,
+            autoplay: true,
+          });
 
-        liveSdk.player.on("switchPlayer", () => {
-          this.changeState = !this.changeState;
-          if (this.changeState) {
-            liveSdk.player.setFullscreenEl(this.$refs.ppt);
-          } else {
-            liveSdk.player.setFullscreenEl(this.$refs.player);
-          }
-        });
+          this.plv.liveSdk.player.on(
+            "fullscreenChange",
+            this.handleFullscreenChange
+          );
+          this.plv.liveSdk.player.on("switchPlayer", this.handleSwitchPlayer); // 点击控制栏切换按钮触发
+          this.plv.liveSdk.player.on("switchMainScreen", this.switchPlayer);
 
-        liveSdk.player.on("switchMainScreen", (main) => {
-          console.log("切换主讲位置,当前主屏为", main); // 'player'|'ppt'
-        });
+          // this.plv.liveSdk.player.on("switchPlayer", () => {
+          //   var switchPosition = plv.mainPosition === 'ppt' ? 'player' : 'ppt';
+          //   switchPlayer(switchPosition);
+          // });
+
+          // this.plv.liveSdk.player.on("switchMainScreen", (main) => {
+          //   console.log("切换主讲位置,当前主屏为", main); // 'player'|'ppt'
+          // });
+
+          // this.plv.liveSdk.player.on("ended", () => {
+          //   this.duraing += this.playTime;
+          //   clearInterval(this.timer);
+          //   this.studyRecord(1);
+          // });
+
+          this.plv.liveSdk.player.on("pause", (state) => {
+            let duraing = this.playTime - this.duraing;
+            this.duraing = 0;
+            this.studyRecord(0, duraing);
+            clearInterval(this.timer);
+          });
+
+          this.plv.liveSdk.player.on("loadedmetadata", (state) => {
+            if (this.isFirst) {
+              this.studyRecord(0);
+              this.isFirst = false;
+            }
+
+            clearInterval(this.timer);
+            this.timer = setInterval(() => {
+              this.studyRecord(0, 20);
+              this.duraing += 20;
+            }, 20000);
+          });
+
+          this.plv.liveSdk.player.on("timeupdate", (time) => {
+            this.playTime = time;
+          });
+        }
+      );
+    },
+
+    studyRecord(status, duraing) {
+      let self = this;
+      this.$request.studyRecord({
+        sectionId: parseInt(this.sectionId),
+        goodsId: parseInt(self.goodsId),
+        courseId: parseInt(self.courseId),
+        orderGoodsId: this.orderGoodsId,
+        studyDuration: parseInt(duraing) || 0,
+        gradeId: parseInt(self.gradeId),
+        chapterId: parseInt(self.chapterId),
+        moduleId: parseInt(self.moduleId),
+        videoCurrentTime: 2,
+        status: status,
       });
     },
     /**
@@ -206,6 +383,59 @@ export default {
         }
       });
     },
+
+    handleSwitchPlayer() {
+      var switchPosition = this.plv.mainPosition === "ppt" ? "player" : "ppt";
+      this.switchPlayer(switchPosition);
+    },
+
+    // 控制栏切换按钮的点击处理函数,仅适用PC端
+    handleSwitchPlayer() {
+      var switchPosition = this.plv.mainPosition === "ppt" ? "player" : "ppt";
+      this.switchPlayer(switchPosition);
+    },
+
+    // 点击到文档tab时调用播放器的resize方法,原因:
+    // ppt父容器样式改变会导致ppt显示异常,需要调用resize刷新ppt尺寸,该函数用于移动端三分屏场景
+    handlePptTabClick() {
+      $("[data-type=ppt]").click(function () {
+        setTimeout(function () {
+          this.plv.liveSdk.player.resize();
+        }, 0);
+      });
+    },
+
+    // 全屏/退出全屏回调
+    handleFullscreenChange(isFullScreen, fullScreenElement) {
+      if (isFullScreen) {
+        $(fullScreenElement).addClass("plv-watch-pc__top--fullscreen");
+      } else {
+        $(fullScreenElement).removeClass("plv-watch-pc__top--fullscreen");
+      }
+    },
+
+    // 切换主副屏,如需兼容ie,建议通过css的方式去切换位置,dom操作可能导致播放器异常
+    switchPlayer(nextMainPosition) {
+      var pcScreens = $(".plv-watch-pc__screen").removeClass(
+        "plv-watch-pc__screen-main plv-watch-pc__screen-sub"
+      );
+
+      switch (nextMainPosition) {
+        case "player":
+          pcScreens.eq(0).addClass("plv-watch-pc__screen-sub");
+          pcScreens.eq(1).addClass("plv-watch-pc__screen-main");
+          break;
+
+        case "ppt":
+          pcScreens.eq(0).addClass("plv-watch-pc__screen-main");
+          pcScreens.eq(1).addClass("plv-watch-pc__screen-sub");
+          break;
+      }
+
+      this.plv.mainPosition = nextMainPosition;
+      this.plv.liveSdk.player.resize(); // ppt容器宽高修改,调用resize刷新ppt尺寸
+      this.plv.liveSdk.player.resizeBarrage(); // 刷新弹幕显示区域尺寸
+    },
   },
 };
 </script>
@@ -214,6 +444,17 @@ export default {
 <style scoped lang="scss">
 .living-room {
   background: #eee;
+  .container {
+    margin: 10px auto;
+  }
+  .top-line {
+    margin: 10px 0;
+    .float-right {
+      float: right;
+      width: 100px;
+    }
+  }
+
   .living {
     position: relative;
     width: 900px;

+ 8 - 0
src/pages/person-center/index.vue

@@ -35,6 +35,14 @@
                 </router-link>
               </div>
             </div>
+            <div class="nav__section">
+              <div class="title">我的直播课</div>
+              <div class="list">
+                <router-link to="/person-center/my-live">
+                  <div class="item">学习列表</div>
+                </router-link>
+              </div>
+            </div>
             <div class="nav__section">
               <div class="title">我的题库</div>
               <div class="list">

+ 325 - 0
src/pages/person-center/my-live/index.vue

@@ -0,0 +1,325 @@
+<template>
+  <div class="my-course">
+    <div
+      class="my-course__header"
+      v-if="livingSectionList[0]"
+      @click="goLive(livingSectionList[0])"
+    >
+      <img src="@/assets/live.png" class="img" alt="" />
+      <div class="text">
+        {{ livingSectionList[0].name }}
+      </div>
+      <div class="note">正在直播中</div>
+      <div class="note">></div>
+    </div>
+    <div class="my-course__body">
+      <div class="list">
+        <div
+          class="course-item"
+          v-for="(item, index) in courseList"
+          :key="index"
+        >
+          <div class="course-item__header">
+            <div class="state">
+              <div class="note note--yellow">直播</div>
+              <span class="title">{{ item.goodsName }}</span>
+            </div>
+          </div>
+          <div class="course-item__body clearfix">
+            <div class="img">
+              <img :src="$tools.splitImgHost(item.coverUrl, true)" alt="" />
+            </div>
+            <div class="text">
+              <div class="title">
+                <div class="note">{{ item.studyCount }}学时</div>
+              </div>
+              <div class="desc">
+                直播日期: {{ $tools.timestampToTime(item.liveStartTime) }} -
+                {{ $tools.timestampToTime(item.liveEndTime) }}
+              </div>
+            </div>
+            <div class="btns-wrap">
+              <div class="btns">
+                <el-button
+                  type="primary"
+                  class="btn btn--normal"
+                  @click="goCourseDetail(item)"
+                  >进入学习</el-button
+                >
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="pagination">
+        <el-pagination
+          @current-change="currentChange"
+          background
+          layout="prev, pager, next"
+          :total="total"
+          :pager-count="5"
+          :page-size="param.pageSize"
+        >
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+import * as baseUrls from "@/axios.js";
+export default {
+  name: "MyCourse",
+  data() {
+    return {
+      param: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      livingSectionList: [],
+      total: 0,
+      courseList: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["userInfo"]),
+  },
+  async mounted() {
+    this.goodsListGoodsUserLive();
+    this.goodsLivingSectionList();
+  },
+  methods: {
+    goLive() {
+      this.$router.push({
+        path: "/living-room/" + this.livingSectionList[0].liveUrl,
+        query: {
+          goodsId: this.livingSectionList[0].goodsId,
+          courseId: this.livingSectionList[0].courseId,
+          gradeId: 0,
+          orderGoodsId: this.livingSectionList[0].orderGoodsId,
+          sectionId: this.livingSectionList[0].sectionId,
+          chapterId: this.livingSectionList[0].chapterId || 0,
+          moduleId: this.livingSectionList[0].moduleId || 0,
+        },
+      });
+    },
+    goodsLivingSectionList() {
+      this.$request.goodsLivingSectionList().then((res) => {
+        this.livingSectionList = res.data;
+      });
+    },
+    currentChange(e) {
+      this.param.pageNum = e;
+      this.goodsListGoodsUserLive();
+    },
+    async goCourseDetail(item) {
+      this.$request
+        .courseCourseList({
+          pageNum: 1,
+          pageSize: 1,
+          goodsId: item.goodsId,
+          gradeId: 0,
+          orderGoodsId: item.orderGoodsId,
+        })
+        .then((res) => {
+          if (res.code == 200) {
+            if (res.rows.length) {
+              this.$router.push({
+                path: `/my-live-detail/${item.goodsId}`,
+                query: {
+                  gradeId: 0,
+                  orderGoodsId: item.orderGoodsId,
+                  courseId: res.rows[0].courseId || "",
+                },
+              });
+            } else {
+              this.$message({
+                type: "warning",
+                message: "暂无可观看的直播课程",
+              });
+            }
+          }
+        });
+    },
+
+    goodsListGoodsUserLive() {
+      this.$request.goodsListGoodsUserLive(this.param).then((res) => {
+        this.courseList = res.rows;
+        this.total = res.total;
+      });
+    },
+  },
+};
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.my-course {
+  &__header {
+    margin-top: 16px;
+    height: 40px;
+    background: linear-gradient(-90deg, #9254de, #d3adf7);
+    border-radius: 8px;
+    display: flex;
+    align-items: center;
+    padding-left: 16px;
+
+    .img {
+      width: 23px;
+    }
+
+    .text {
+      flex: 1;
+      font-size: 16px;
+      font-family: Microsoft YaHei;
+      font-weight: bold;
+      color: #ffffff;
+      margin-left: 16px;
+    }
+
+    .note {
+      font-size: 16px;
+      font-family: Microsoft YaHei;
+      font-weight: bold;
+      color: #ffffff;
+      margin-right: 16px;
+    }
+  }
+  &__body {
+    .list {
+      .course-item {
+        margin-top: 24px;
+        background: #fafbfc;
+        border-radius: 8px;
+        overflow: hidden;
+
+        &__header {
+          height: 40px;
+          border-bottom: 1px solid #eee;
+          padding: 0 18px;
+
+          .state {
+            margin-top: 8px;
+            float: left;
+            font-size: 14px;
+            font-family: Microsoft YaHei;
+            font-weight: 400;
+            color: #666666;
+
+            .note {
+              vertical-align: middle;
+              display: inline-block;
+              padding: 0 10px;
+              height: 24px;
+              background: #ffeceb;
+              border: 1px solid #ff3b30;
+              border-radius: 12px;
+              font-size: 14px;
+              font-family: Microsoft YaHei;
+              font-weight: 400;
+              color: #ff3b30;
+              text-align: center;
+              line-height: 24px;
+              margin-right: 10px;
+
+              &--yellow {
+                border-color: #ffb001;
+                color: #ffb001;
+                background: #fff8e8;
+              }
+            }
+
+            .title {
+              margin-top: 10px;
+              font-size: 16px;
+              font-family: Microsoft YaHei;
+              font-weight: bold;
+              color: #333333;
+            }
+          }
+        }
+
+        &__body {
+          .img {
+            float: left;
+            width: 160px;
+            height: 90px;
+
+            img {
+              max-width: 100%;
+              max-height: 100%;
+            }
+          }
+
+          .text {
+            float: left;
+            margin-left: 12px;
+            .title {
+              margin-top: 10px;
+              .note {
+                display: inline-block;
+                vertical-align: middle;
+                border: 1px solid #333333;
+                border-radius: 4px;
+                font-size: 12px;
+                font-family: Microsoft YaHei;
+                font-weight: 400;
+                color: #333333;
+                padding: 2px 5px;
+              }
+            }
+
+            .desc {
+              margin-top: 30px;
+              font-size: 12px;
+              font-family: Microsoft YaHei;
+              font-weight: 400;
+              color: #666666;
+            }
+          }
+
+          .btns-wrap {
+            display: table;
+            float: right;
+            height: 90px;
+            width: 130px;
+
+            .btns {
+              display: table-cell;
+              vertical-align: middle;
+              text-align: center;
+
+              .btn {
+                cursor: pointer;
+                margin: 2px 0;
+                width: 122px;
+                height: 32px;
+                padding: 0;
+                border-radius: 16px;
+                display: inline-block;
+                text-align: center;
+                line-height: 32px;
+                color: #fff;
+
+                &--normal {
+                  &.disabled {
+                    background: rgb(101, 164, 253);
+                    border-color: rgb(101, 164, 253);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    .pagination {
+      padding: 30px 0;
+      text-align: center;
+    }
+  }
+}
+</style>

+ 155 - 39
src/pages/person-center/my-mock/index.vue

@@ -21,14 +21,14 @@
             <div class="tabs">
               <div
                 class="tab"
-                :class="{ active: state == 0 }"
+                :class="{ active: examParam.mockStatus == 0 }"
                 @click="stateChange(0)"
               >
                 未考试
               </div>
               <div
                 class="tab"
-                :class="{ active: state == 1 }"
+                :class="{ active: examParam.mockStatus == 1 }"
                 @click="stateChange(1)"
               >
                 已结束
@@ -42,8 +42,9 @@
                 <div class="select">
                   <el-date-picker
                     value-format="yyyy-MM-dd"
-                    v-model="date"
+                    v-model="examParam.dateRange"
                     type="daterange"
+                    @change="mockSubscribeListSubscribe"
                     placeholder="选择日期"
                   >
                   </el-date-picker>
@@ -66,36 +67,44 @@
             </div>
 
             <div class="list">
-              <div class="mock-item" v-for="item in 4" :key="item">
-                <template v-if="state == 0">
+              <div
+                class="mock-item"
+                v-for="(item, index) in examList"
+                :key="index"
+              >
+                <template v-if="examParam.mockStatus == 0">
                   <div class="mock-item__header">
-                    <div class="title">2022年考前一建模拟考试</div>
-                    <div class="time">2022/4/15 9:30:00</div>
+                    <div class="title">{{ item.applyName }}</div>
+                    <!-- <div class="time">2022/4/15 9:30:00</div> -->
                   </div>
 
                   <div class="mock-item__body">
                     <div class="content">
                       <div class="item">
                         <span class="item__left">项目:</span>
-                        <span class="item__right">一级建造师</span>
+                        <span class="item__right"
+                          >{{ item.businessName }} {{ item.projectName }}</span
+                        >
                       </div>
                       <div class="item">
                         <span class="item__left">专业:</span>
-                        <span class="item__right">市政专业</span>
+                        <span class="item__right">{{ item.categoryName }}</span>
                       </div>
                       <div class="item">
                         <span class="item__left">科目:</span>
-                        <span class="item__right">建设工程经济</span>
+                        <span class="item__right">{{ item.subjectName }}</span>
                       </div>
                       <div class="item">
                         <span class="item__left">考试时间:</span>
                         <span class="item__right">
-                          2022年4月15日(周五)9:00-10:00
+                          {{ $tools.timestampToTime(item.applySiteExamTime) }}
+                          {{ item.applySiteStartTime }} -
+                          {{ item.applySiteEndTime }}
                         </span>
                       </div>
                     </div>
                     <div class="btn-wrap">
-                      <div class="btn-item" v-if="item % 2 == 0">
+                      <div class="btn-item" v-if="goTest(item)">
                         <el-button class="btn" disabled type="primary"
                           >去考试</el-button
                         >
@@ -105,7 +114,7 @@
                       <div class="btn-item" v-else>
                         <el-button
                           class="btn"
-                          @click="go('/mock-countdown')"
+                          @click="goExamCount(item)"
                           type="primary"
                           >去考试</el-button
                         >
@@ -114,30 +123,34 @@
                   </div>
                 </template>
 
-                <template v-if="state == 1">
+                <template v-if="examParam.mockStatus == 1">
                   <div class="mock-item__header">
-                    <div class="title">2022年考前一建模拟考试</div>
-                    <div class="time">2022/4/15 9:30:00</div>
+                    <div class="title">{{ item.applyName }}</div>
+                    <!-- <div class="time">2022/4/15 9:30:00</div> -->
                   </div>
 
                   <div class="mock-item__body">
                     <div class="content">
                       <div class="item">
                         <span class="item__left">项目:</span>
-                        <span class="item__right">一级建造师</span>
+                        <span class="item__right"
+                          >{{ item.businessName }} {{ item.projectName }}</span
+                        >
                       </div>
                       <div class="item">
                         <span class="item__left">专业:</span>
-                        <span class="item__right">市政专业</span>
+                        <span class="item__right">{{ item.categoryName }}</span>
                       </div>
                       <div class="item">
                         <span class="item__left">科目:</span>
-                        <span class="item__right">建设工程经济</span>
+                        <span class="item__right">{{ item.subjectName }}</span>
                       </div>
                       <div class="item">
                         <span class="item__left">考试时间:</span>
                         <span class="item__right">
-                          2022年4月15日(周五)9:00-10:00
+                          {{ $tools.timestampToTime(item.applySiteExamTime) }}
+                          {{ item.applySiteStartTime }} -
+                          {{ item.applySiteEndTime }}
                         </span>
                       </div>
                     </div>
@@ -208,7 +221,7 @@
                 @current-change="currentChange"
                 background
                 layout="prev, pager, next"
-                :total="total"
+                :total="examParam.total"
                 :pager-count="5"
                 :page-size="formData.pageSize"
               >
@@ -296,12 +309,12 @@
                     </div>
                     <div class="item">
                       <span class="item__left">专业:</span>
-                      <span class="item__right">{{ item.subjectName }}</span>
+                      <span class="item__right">{{ item.categoryName }}</span>
                     </div>
-                    <!-- <div class="item">
+                    <div class="item">
                       <span class="item__left">科目:</span>
-                      <span class="item__right">建设工程经济</span>
-                    </div> -->
+                      <span class="item__right">{{ item.subjectName }}</span>
+                    </div>
                     <div class="item">
                       <span class="item__left">考试时间:</span>
                       <span class="item__right">
@@ -311,12 +324,12 @@
                     </div>
                   </div>
                   <div class="btn-wrap">
-                    <div class="btn-item">
-                      <el-button class="btn" type="primary" plain
+                    <div class="btn-item" v-if="!item.isSubscribe">
+                      <el-button class="btn" disabled type="primary" plain
                         >已预约</el-button
                       >
                     </div>
-                    <div class="btn-item">
+                    <div class="btn-item" v-else>
                       <el-button
                         class="btn"
                         type="primary"
@@ -427,23 +440,28 @@
           您预约的模拟考试,安排如下:
           <div class="item">
             <span class="item__left">模考场次:</span>
-            <span class="item__right">2022年考前一建模拟考试 </span>
+            <span class="item__right">{{ showItem.applyName }} </span>
           </div>
           <div class="item">
             <span class="item__left">项目:</span>
-            <span class="item__right">一级建造师 </span>
+            <span class="item__right"
+              >{{ showItem.businessName }} {{ showItem.projectName }}
+            </span>
           </div>
-          <div class="item">
+          <!-- <div class="item">
             <span class="item__left">专业:</span>
-            <span class="item__right">市政专业 </span>
-          </div>
+            <span class="item__right">{{ showItem.subjectName }} </span>
+          </div> -->
           <div class="item">
             <span class="item__left">科目:</span>
-            <span class="item__right">建设工程经济 </span>
+            <span class="item__right">{{ showItem.subjectName }} </span>
           </div>
           <div class="item">
             <span class="item__left">考试时间:</span>
-            <span class="item__right">2022年4月15日(周五)9:00-10:00 </span>
+            <span class="item__right">
+              {{ $tools.timestampToTime(showItem.examTime) }}
+              {{ showItem.startTime }} - {{ showItem.endTime }}
+            </span>
           </div>
           请准时参加考试哦~
 
@@ -467,12 +485,22 @@ export default {
         pageSize: 10,
         businessId: "",
         subjectId: "",
+        total: 0,
+      },
+      examParam: {
+        dateRange: "",
+        pageNum: 1,
+        pageSize: 10,
+        mockStatus: 0,
+        total: 0,
       },
       total: 1,
       title: 0,
       orderList: [],
       mockList: [],
+      examList: [],
       sList: [],
+      showItem: {},
       businesslist: [],
       activeName: "1",
       formData: {
@@ -504,9 +532,75 @@ export default {
   },
   mounted() {
     this.nowTime = +this.$tools.timest();
+    this.mockSubscribeListSubscribe();
   },
   methods: {
-    appoint() {},
+    goTest(item) {
+      let nowTime = +this.$tools.timest();
+      let startTime = this.$tools.TimeTotimestamp(
+        this.$tools.timestampToTime(item.applySiteExamTime) +
+          " " +
+          item.applySiteStartTime
+      );
+      let canGo =
+        startTime - nowTime <= 600 &&
+        startTime - nowTime >= (-(item.timeLimit * 60) || 0);
+
+      return !canGo;
+    },
+    goExamCount(item) {
+      if (this.goTest(item)) {
+        this.$message.warning("不在考试时间");
+        return;
+      }
+
+      this.go("/mock-countdown", {
+        start: this.$tools.TimeTotimestamp(
+          this.$tools.timestampToTime(item.applySiteExamTime) +
+            " " +
+            item.applySiteStartTime
+        ),
+        limit: item.timeLimit,
+        examId: item.examId,
+        eachExamId: item.eachExamId,
+      });
+    },
+    appoint(item) {
+      let canApply = this.canApply(item);
+      if (!canApply) {
+        this.$message.warning("不在预约时间范围");
+
+        return;
+      }
+
+      if (!item.isSubscribe) {
+        this.$message.warning("您已预约");
+        return;
+      }
+
+      this.$api
+        .mockSubscribe({
+          applySiteExamTime: item.examTime,
+          applySiteEndTime: item.endTime,
+          applySiteStartTime: item.startTime,
+          applyId: item.applyId,
+          mockMajorSubjectId: item.mockMajorSubjectId,
+          eachExamId: item.eachExamId,
+          // applySiteExamTime:1653899220,
+          // applySiteEndTime:"17:27:54",
+          // applySiteStartTime:'16:27:54',
+          // applyId:26,
+          // mockMajorSubjectId:49
+        })
+        .then((res) => {
+          console.log(res);
+          this.showItem = item;
+          this.appointModal = true;
+        })
+        .catch((err) => {
+          this.$message.warning(err.msg);
+        });
+    },
     canApply(item) {
       let startTime = this.$tools.TimeTotimestamp(
         this.$tools.timestampToTime(item.examTime) + " " + item.startTime
@@ -587,6 +681,10 @@ export default {
       this.formData.pageNum = 1;
       this.activeName = e.name;
 
+      if (this.activeName == "1") {
+        this.mockSubscribeListSubscribe();
+      }
+
       if (this.activeName == "2") {
         await this.mockApplyListApplyBusiness();
 
@@ -594,15 +692,32 @@ export default {
       }
     },
 
+    mockSubscribeListSubscribe() {
+      let examParam = JSON.parse(JSON.stringify(this.examParam));
+      if (examParam.dateRange && examParam.dateRange[0]) {
+        examParam.endTime = this.$tools.TimeTotimestamp(examParam.dateRange[0]);
+      }
+
+      if (examParam.dateRange && examParam.dateRange[1]) {
+        examParam.startTime = this.$tools.TimeTotimestamp(
+          examParam.dateRange[1]
+        );
+      }
+      this.$request.mockSubscribeListSubscribe(examParam).then((res) => {
+        this.examList = res.rows;
+        this.examParam.total = res.total;
+      });
+    },
+
     mockApplyListApply() {
       let appointParam = JSON.parse(JSON.stringify(this.appointParam));
-      if (appointParam.dateRange[0]) {
+      if (appointParam.dateRange && appointParam.dateRange[0]) {
         appointParam.endTime = this.$tools.TimeTotimestamp(
           appointParam.dateRange[0]
         );
       }
 
-      if (appointParam.dateRange[1]) {
+      if (appointParam.dateRange && appointParam.dateRange[1]) {
         appointParam.startTime = this.$tools.TimeTotimestamp(
           appointParam.dateRange[1]
         );
@@ -615,7 +730,8 @@ export default {
       });
     },
     stateChange(state) {
-      this.state = state;
+      this.examParam.mockStatus = state;
+      this.mockSubscribeListSubscribe();
     },
   },
 };

+ 30 - 0
src/router/index.js

@@ -146,6 +146,18 @@ const router =  new Router({
         }
       }
     },
+    {
+      path: '/live-detail/:goodsId',
+      name: '直播详情',
+      component: resolve => require(['@/pages/goods-detail/live-detail'],resolve),
+      meta: {
+        title: '祥粤云学堂-题库-一建二建试题下载_考试科目题库_考题答案_历年试题_在线真题_水平测试_历年真题_在线题库',
+        content: {
+          keywords: '祥粤云学堂-模拟试题练习,试题答案,一级建造师试题查找,二级建造师试题练习,题目类型,考试书籍,考试图书,考试教材',
+          description: '祥粤云学堂-提供一二级建造师学习资料、教材教辅,一二级建造师考试专业培训辅导课程,免费试听,建造师内部习题资料、工程师教学辅导视频、建筑考试课件视频等资料'
+        }
+      }
+    },
     {
       path: '/my-course-detail/:goodsId',
       name: '课程详情',
@@ -158,6 +170,19 @@ const router =  new Router({
         }
       }
     },
+    
+    {
+      path: '/my-live-detail/:goodsId',
+      name: '直播详情',
+      component: resolve => require(['@/pages/live-detail/index'],resolve),
+      meta: {
+        title: '祥粤云学堂-一二级建造师、工程师、建筑师视频课程、免费直播课',
+        content: {
+          keywords: '祥粤云学堂-一级建造师视频课件,二级建造师视频课件,建筑师工程师学习视频课程',
+          description: '祥粤云学堂-提供一二级建造师视频学习、免费直播公开课  ,免费试听,建造师内部习题资料、工程师教学辅导视频、建筑考试课件视频等资料。'
+        }
+      }
+    },
     {
       path: '/living-room/:channelId',
       name: '课程详情',
@@ -370,6 +395,11 @@ const router =  new Router({
           component: resolve => require(['@/pages/person-center/my-course/index'],resolve),
           name: '我的课程'
         },
+        {
+          path: 'my-live',
+          component: resolve => require(['@/pages/person-center/my-live/index'],resolve),
+          name: '我的直播课'
+        },
         {
           path: 'play-record',
           component: resolve => require(['@/pages/person-center/play-record/index'],resolve),

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor