lex-xin 3 years ago
parent
commit
9080973fc2

+ 1 - 1
src/App.vue

@@ -17,7 +17,7 @@
   font-family: Avenir, Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
-  text-align: center;
+  // text-align: center;
   color: #2c3e50;
 }
 

BIN
src/assets/home/logo.png


BIN
src/assets/home/placehorder-icon.png


+ 3 - 0
src/base.css

@@ -4,4 +4,7 @@ body{
   --live-backound-color: #25292E;
   --live-color: #fff;
   --video-backound-color: #000;
+  --live-main-color: #32363B;
+  --message-color: #575B61;
+  --live-light-color: #01A79E;
 }

+ 3 - 3
src/components/live-broadcast/index.module.less

@@ -1,15 +1,15 @@
 .main{
   --header-height: 68px;
   --action-bar-height: 88px;
-  width: 100%;
+  width: calc(100% - 385px);
   background-color: var(--live-backound-color);
   color: var(--live-color);
   display: flex;
   flex-direction: column;
-  height: 100vh;
+  height: calc(100vh - var(--header-bar-height));
   .video{
     width: 100%;
-    max-height: calc(100vh - var(--header-height) - var(--action-bar-height));
+    max-height: calc(100vh - var(--header-bar-height) - var(--header-height) - var(--action-bar-height));
     flex: 1;
     background-color: var(--video-backound-color);
   }

+ 67 - 0
src/components/live-message/index.module.less

@@ -0,0 +1,67 @@
+.container {
+  width: 385px !important;
+  height: calc(100vh - var(--header-bar-height));
+  background-color: var(--live-main-color);
+  position: relative
+}
+
+.dataCount {
+  margin: 16px;
+  border-radius: 2px;
+  background-color: var(--message-color);
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  height: 120px;
+  color: var(--live-color);
+  .num {
+    font-size: 24px;
+    font-weight: bold;
+    padding-bottom: 16px;
+  }
+  .text {
+    font-size: 14px;
+  }
+}
+
+.tabContainer {
+  :global {
+    .el-tabs__header {
+      margin-bottom: 0;
+    }
+    .el-tabs__nav-wrap {
+      &::after {
+        background-color: var(--message-color);
+      }
+    }
+    .el-tabs__nav {
+      padding: 12px 0;
+      width: 100%;
+      text-align: center;
+    }
+    .el-tabs__item {
+      color: var(--live-color);
+      font-size: 16px;
+      &.is-active {
+        color: #00FFF0;
+      }
+    }
+    .el-tabs__active-bar {
+      background-color: #00FFF0;
+    }
+    // .el-tabs__content {
+    //   padding: 32px;
+    //   background-color: #f4f5f7;
+    //   color: #6b778c;
+    //   font-size: 32px;
+    //   font-weight: 600;
+    // }
+  }
+}
+
+.tabContent {
+  --message-bar-height: 88px;
+  position: relative;
+  height: calc(100vh - var(--header-bar-height) - var(--message-bar-height) - 216px);
+  padding-bottom: var(--message-bar-height);
+}

+ 52 - 0
src/components/live-message/index.tsx

@@ -0,0 +1,52 @@
+import { defineComponent } from "vue"
+import { ElTabs, ElTabPane } from "element-plus"
+import styles from './index.module.less'
+import Message from './message'
+import SendMessage from './sendMessage';
+import ItemList from './itemList'
+
+type tabStatus = 'message' | 'join' | 'look'
+
+export default defineComponent({
+  name: 'LiveMessage',
+  data() {
+    return {
+      modelIndex: 'message' as tabStatus,
+    }
+  },
+  methods: {
+    tabChange(val: any) {
+      this.modelIndex = val.props.name
+    }
+  },
+  render() {
+    return (
+      <div class={styles.container}>
+        <div class={styles.dataCount}>
+          <div>
+            <p class={styles.num}>1361</p>
+            <p class={styles.text}>当前观看</p>
+          </div>
+          <div>
+            <p class={styles.num}>1361</p>
+            <p class={styles.text}>累计点赞</p>
+          </div>
+        </div>
+
+        <ElTabs modelValue={this.modelIndex} onTab-click={this.tabChange} class={styles.tabContainer} >
+          <ElTabPane label="聊天" name="message"></ElTabPane>
+          <ElTabPane label="连麦" name="join"></ElTabPane>
+          <ElTabPane label="观看" name="look"></ElTabPane>
+        </ElTabs>
+        <div class={styles.tabContent}>
+          <Message />
+          {this.modelIndex === 'message' && <ItemList type="message" />}
+          {this.modelIndex === 'join' && <ItemList type="join" />}
+          {this.modelIndex === 'look' && <ItemList type="look" />}
+
+          <SendMessage />
+        </div>
+      </div>
+    )
+  }
+})

+ 65 - 0
src/components/live-message/itemList.module.less

@@ -0,0 +1,65 @@
+.itemContent {
+  padding: 16px;
+  display: flex;
+  color: var(--live-color);
+  & > img {
+    width: 28px;
+    height: 28px;
+    margin-right: 8px;
+  }
+}
+
+.itemInfo {
+  width: 100%;
+}
+
+.itemName {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-top: 3px;
+  padding-bottom: 8px;
+  .userName {
+    font-size: 16px;
+    line-height: 22px;
+    display: flex;
+    align-items: center;
+  }
+  .rightTime {
+    font-size: 12px;
+  }
+  :global {
+    .el-tag--default {
+      border-radius: 20px;
+      margin-left: 8px;
+      padding: 0 12px;
+      height: 20px;
+      line-height: 20px;
+      color: var(--live-color);
+      background: var(--message-color);
+      border-color: var(--message-color);
+    }
+  }
+}
+.itemText {
+  font-size: 14px;
+  line-height: 20px;
+}
+
+.joinText {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  .join {
+    display: flex;
+    align-items: center;
+  }
+  .btn {
+    font-size: 13px;
+    line-height: 20px;
+    background-color: var(--live-light-color);
+    text-align: center;
+    padding: 3px 15px 1px;
+    border-radius: 2px;
+  }
+}

+ 47 - 0
src/components/live-message/itemList.tsx

@@ -0,0 +1,47 @@
+import { defineComponent } from "vue";
+import { ElTag, ElIcon, ElButton } from "element-plus";
+import styles from './itemList.module.less';
+type itemType = 'message' | 'join' | 'look'
+
+export default defineComponent({
+  props: {
+    type: {
+      type: String,
+      default: 'join' as itemType
+    }
+  },
+  render() {
+    return (
+      <div class={styles.itemContent}>
+        <img src="/src/assets/home/placehorder-icon.png" alt="" />
+        { this.type === 'message' ? <div class={styles.itemInfo}>
+          <div class={styles.itemName}>
+            <p class={styles.userName}>唐老师 <ElTag >主播</ElTag></p>
+            <p class={styles.rightTime}>18:30:00</p>
+          </div>
+          <div class={styles.itemText}>
+            请问老师,我在乐团学习长笛已经2年了,目前可以把1-4级都熟练吹奏,接下来要怎么继续提高呢?
+          </div>
+        </div> : null }
+
+        { this.type === 'join' ? <div class={styles.itemInfo}>
+          <div class={styles.itemName}>
+            <p class={styles.userName}>唐老师 </p>
+          </div>
+          <div class={styles.joinText}>
+            <div class={styles.join}>
+              申请连麦
+            </div>
+            <div class={styles.btn}>下麦</div>
+          </div>
+        </div> : null }
+
+        { this.type === 'look' ? <div class={styles.itemInfo}>
+          <div class={styles.itemName}>
+            <p class={styles.userName}>唐老师</p>
+          </div>
+        </div> : null }
+      </div>
+    )
+  }
+})

+ 26 - 0
src/components/live-message/message.module.less

@@ -0,0 +1,26 @@
+.message {
+  .buttonGroup {
+    display: flex;
+    align-items: center;
+    background: rgba(99, 108, 132, 0.1);
+    padding: 15px 16px;
+  }
+  .btn {
+    width: 88px;
+    height: 30px;
+    line-height: 30px;
+    font-size: 14px;
+    font-weight: 600;
+    background: var(--message-color);
+    border-radius: 2px;
+    color: var(--live-color);
+    text-align: center;
+    cursor: pointer;
+    & + .btn {
+      margin-left: 12px;
+    }
+  }
+  .active {
+    background: var(--live-light-color);
+  }
+}

+ 23 - 0
src/components/live-message/message.tsx

@@ -0,0 +1,23 @@
+import { defineComponent } from "vue";
+import styles from './message.module.less';
+
+
+type optionsType = 'ALL' | 'JOIN'
+export default defineComponent({
+  name: 'message',
+  data() {
+    return {
+      options: 'ALL' as optionsType
+    }
+  },
+  render() {
+    return (
+      <div class={styles.message}>
+        <div class={styles.buttonGroup}>
+          <div class={[this.options === 'ALL' ? styles.active : null, styles.btn]}>全体禁言</div>
+          <div class={styles.btn}>禁止连麦</div>
+        </div>
+      </div>
+    )
+  }
+})

+ 42 - 0
src/components/live-message/sendMessage.module.less

@@ -0,0 +1,42 @@
+.sendMessage {
+  position: fixed;
+  bottom: 0;
+  height: 88px;
+  width: calc(385px - 32px);
+  display: flex;
+  align-items: center;
+  padding: 0 16px;
+  .form {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    background-color: var(--message-color);
+    border-radius: 60px;
+  }
+  :global {
+    .el-input {
+      border-radius: 60px;
+      overflow: hidden;
+      font-size: 18px;
+      // background-color: transparent;
+    }
+    .el-input__inner {
+      height: 46px;
+      line-height: 46px;
+      padding-left: 20px;
+      background-color: transparent;
+      border: 0;
+    }
+    .el-button {
+      border: 0;
+      background-color: #00A79D;
+      height: 46px;
+      line-height: 46px;
+      border-radius: 46px;
+      color: var(--live-color);
+      font-weight: 600;
+      padding: 0 23px;
+      font-size: 18px;
+    }
+  }
+}

+ 16 - 0
src/components/live-message/sendMessage.tsx

@@ -0,0 +1,16 @@
+import { defineComponent } from "vue";
+import { ElInput, ElButton } from "element-plus";
+import styles from "./sendMessage.module.less";
+
+export default defineComponent({
+  render() {
+    return (
+      <div class={styles.sendMessage}>
+        <div class={styles.form}>
+          <ElInput placeholder="请输入消息" />
+          <ElButton round type="primary">发送</ElButton>
+        </div>
+      </div>
+    )
+  }
+});

+ 43 - 0
src/pages/home/header/index.module.less

@@ -0,0 +1,43 @@
+.liveHeader {
+  padding: 0 40px 0 20px;
+  height: var(--header-bar-height);
+  background: var(--live-main-color);
+  box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.25), 0px 0px 6px 2px rgba(0, 0, 0, 0.1);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  color: var(--live-color);
+
+  .liveLogo {
+    height: 36px;
+    width: 36px;
+    padding-right: 10px;
+  }
+  .liveHeaderLeft {
+    display: flex;
+    align-items: center;
+    font-weight: bold;
+    font-size: 22px;
+    .liveHeaderLeftIcon {
+      display: inherit;
+      align-items: inherit;
+    }
+    .liveHeaderLeftText {
+      padding-left: 20px;
+    }
+  }
+}
+.avatarWrapper {
+  display: flex;
+  align-items: center;
+  color: var(--live-color);
+  font-weight: 500;
+  font-size: 18px;
+  .userAvatar {
+    width: 34px;
+    height: 34px;
+  }
+  span {
+    padding-left: 8px;
+  }
+}

+ 48 - 0
src/pages/home/header/index.tsx

@@ -0,0 +1,48 @@
+import { defineComponent } from "vue";
+import { ElDropdownMenu, ElDropdown, ElDropdownItem } from "element-plus";
+import styles from './index.module.less';
+import request from '/src/helpers/request';
+
+export default defineComponent({
+  methods: {
+    async loginOut() {
+      try {
+        await request.post('/api-auth/exit');
+        this.$router.push('/login');
+      } catch(e) {
+        // TODO: handle error
+      }
+    }
+  },
+  render() {
+    return (
+      <div class={styles.liveHeader}>
+        <div class={styles.liveHeaderLeft}>
+          <div class={styles.liveHeaderLeftIcon}>
+            <img class={styles.liveLogo} src="/src/assets/home/logo.png" alt=""/>
+            大雅乐盟
+          </div>
+          <div class={styles.liveHeaderLeftText}>
+            《2022大师直播第五期》
+          </div>
+        </div>
+        <ElDropdown trigger={'hover'}
+          // @ts-ignore
+          vSlots={{
+            dropdown: () => (
+              <ElDropdownMenu>
+                <ElDropdownItem command="1" onClick={this.loginOut}>
+                  <span>安全退出</span>
+                </ElDropdownItem>
+              </ElDropdownMenu>
+            )
+          }}>
+          <div class={styles.avatarWrapper}>
+             <img class={styles.userAvatar} src="/src/assets/home/placehorder-icon.png" />
+            <span>诏老师</span>
+          </div>
+        </ElDropdown>
+      </div>
+    )
+  }
+})

+ 6 - 0
src/pages/home/index.module.less

@@ -0,0 +1,6 @@
+.container {
+  display: flex;
+}
+.home {
+  --header-bar-height: 76px;
+}

+ 9 - 2
src/pages/home/index.tsx

@@ -1,11 +1,18 @@
 import { defineComponent } from "vue";
+import Header from './header/index';
 import LiveBroadcast from '/src/components/live-broadcast'
+import LiveMessage from '/src/components/live-message'
+import styles from './index.module.less';
 
 export default defineComponent({
   render() {
     return (
-      <div>
-        <LiveBroadcast/>
+      <div class={styles.home}>
+        <Header />
+        <div class={styles.container}>
+          <LiveBroadcast/>
+          <LiveMessage />
+        </div>
       </div>
     )
   }

+ 1 - 1
src/utils/loading.ts

@@ -11,7 +11,7 @@ let loadingRequestCount = 0;
 let loadingInstance: any;
 
 // 编写一个显示loading的函数 并且记录请求次数 ++
-const showLoading = (target: any) => {
+const showLoading = (target: null | any) => {
   if (loadingRequestCount === 0) {
     // element的服务方式 target 我这边取的是表格class
     // 类似整个表格loading和在表格配置v-loading一样的效果,这么做是全局实现了,不用每个页面单独去v-loading

File diff suppressed because it is too large
+ 641 - 5
yarn.lock


Some files were not shown because too many files changed in this diff