shuisheng 1 rok pred
rodič
commit
b5a5e6e98e

+ 10 - 10
README.md

@@ -22,16 +22,16 @@ billd 直播间,目前实现了类似 [bilibili 的 Web 在线直播](https://
 
 ## 生态
 
-| 名称         | 仓库                                                                             | star & fork                                                                                                                                                                                                                                                                                                                         | 线上地址                                                                       |
-| ------------ | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
-| 直播间前台   | [billd-live](https://github.com/galaxy-s10/billd-live)                           | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live)                                                     | [https://live.hsslive.cn](https://live.hsslive.cn)                             |
-| 直播间后端   | [billd-live-server](https://github.com/galaxy-s10/billd-live-server)             | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-server?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-server) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-server?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-server)                         | [https://live-api.hsslive.cn](https://live-api.hsslive.cn)                     |
-| 直播间后台   | [billd-live-admin](https://github.com/galaxy-s10/billd-live-admin)               | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-admin?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-admin) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-admin?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-admin)                             | [https://live-admin.hsslive.cn](https://live-admin.hsslive.cn)                 |
-| 远程桌面     | [billd-desk](https://github.com/galaxy-s10/billd-desk)                           | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-desk?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-desk) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-desk?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-desk)                                                     | [https://live.hsslive.cn/remoteDeskTop](https://live.hsslive.cn/remoteDeskTop) |
-| 直播间移动端 | [billd-live-flutter](https://github.com/galaxy-s10/billd-live-flutter)           | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-flutter?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-flutter) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-flutter?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-flutter)                     | [https://live.hsslive.cn/download](https://live.hsslive.cn/download)           |
-| 直播间移动端 | [billd-live-react-native](https://github.com/galaxy-s10/billd-live-react-native) | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-react-native?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-react-native) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-react-native?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-react-native) | [https://live.hsslive.cn/download](https://live.hsslive.cn/download)           |
-| 直播间客户端 | [billd-live-electron](https://github.com/galaxy-s10/billd-live-electron)         | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-electron?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-flutter) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-electron?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-electron)                  | [https://live.hsslive.cn/download](https://live.hsslive.cn/download)           |
-| 直播间移动端 | [billd-live-kotlin](https://github.com/galaxy-s10/billd-live-kotlin)             | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-kotlin?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-kotlin) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-kotlin?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-kotlin)                         | [https://live.hsslive.cn/download](https://live.hsslive.cn/download)           |
+| 名称         | 仓库                                                                             | star & fork                                                                                                                                                                                                                                                                                                                         | 线上地址                                                             |
+| ------------ | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
+| 直播间前台   | [billd-live](https://github.com/galaxy-s10/billd-live)                           | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live)                                                     | [https://live.hsslive.cn](https://live.hsslive.cn)                   |
+| 直播间后端   | [billd-live-server](https://github.com/galaxy-s10/billd-live-server)             | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-server?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-server) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-server?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-server)                         | [https://live-api.hsslive.cn](https://live-api.hsslive.cn)           |
+| 直播间后台   | [billd-live-admin](https://github.com/galaxy-s10/billd-live-admin)               | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-admin?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-admin) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-admin?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-admin)                             | [https://live-admin.hsslive.cn](https://live-admin.hsslive.cn)       |
+| 远程桌面     | [billd-desk](https://github.com/galaxy-s10/billd-desk)                           | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-desk?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-desk) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-desk?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-desk)                                                     | [https://desk.hsslive.cn](https://desk.hsslive.cn)                   |
+| 直播间移动端 | [billd-live-flutter](https://github.com/galaxy-s10/billd-live-flutter)           | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-flutter?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-flutter) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-flutter?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-flutter)                     | [https://live.hsslive.cn/download](https://live.hsslive.cn/download) |
+| 直播间移动端 | [billd-live-react-native](https://github.com/galaxy-s10/billd-live-react-native) | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-react-native?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-react-native) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-react-native?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-react-native) | [https://live.hsslive.cn/download](https://live.hsslive.cn/download) |
+| 直播间客户端 | [billd-live-electron](https://github.com/galaxy-s10/billd-live-electron)         | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-electron?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-flutter) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-electron?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-electron)                  | [https://live.hsslive.cn/download](https://live.hsslive.cn/download) |
+| 直播间移动端 | [billd-live-kotlin](https://github.com/galaxy-s10/billd-live-kotlin)             | [![github](https://img.shields.io/github/stars/galaxy-s10/billd-live-kotlin?label=star&logo=GitHub)](https://github.com/galaxy-s10/billd-live-kotlin) [![github](https://img.shields.io/github/forks/galaxy-s10/billd-live-kotlin?label=fork&logo=GitHub)](https://github.com/galaxy-s10/billd-live-kotlin)                         | [https://live.hsslive.cn/download](https://live.hsslive.cn/download) |
 
 ## 功能
 

+ 1 - 5
package.json

@@ -35,10 +35,6 @@
     }
   },
   "dependencies": {
-    "@ffmpeg/ffmpeg": "^0.12.10",
-    "@ffmpeg/util": "^0.12.1",
-    "@nut-tree/nut-js": "^4.0.0",
-    "@nut-tree/shared": "^4.0.0",
     "@vicons/ionicons5": "^0.12.0",
     "@vueuse/core": "^10.11.1",
     "@webav/av-recorder": "^0.3.3",
@@ -137,4 +133,4 @@
     "webpackbar": "^5.0.2",
     "windicss-webpack-plugin": "^1.7.7"
   }
-}
+}

+ 4 - 2
src/hooks/use-login.ts

@@ -30,12 +30,12 @@ document.body.appendChild(container);
 const POSTMESSAGE_TYPE = [PlatformEnum.qqLogin];
 
 export async function handleQQLogin(e) {
+  let flag = false;
   const { type, data } = e.data;
-  if (!POSTMESSAGE_TYPE.includes(type)) return;
+  if (!POSTMESSAGE_TYPE.includes(type)) return flag;
   console.log('收到消息', type, data);
   const userStore = useUserStore();
   const appStore = useAppStore();
-
   try {
     switch (type) {
       case PlatformEnum.qqLogin: {
@@ -45,6 +45,7 @@ export async function handleQQLogin(e) {
           fullLoading({
             loading: false,
           });
+          flag = true;
         }
         userStore.setToken(res.data, data.qqExp);
         userStore.getUserInfo();
@@ -57,6 +58,7 @@ export async function handleQQLogin(e) {
   } finally {
     clearThirdLoginInfo();
   }
+  return flag;
 }
 
 export function loginTip(show = false) {

+ 1 - 0
src/locales/en/home.ts

@@ -2,6 +2,7 @@ import { nameSpaceWrap } from '@/locales/util';
 
 export default nameSpaceWrap('home', {
   recommendLive: 'Recommend Live',
+  bilibiliLive: 'Bilibili Live',
   noliveRoomTip: 'There are currently no live rooms available online',
   copyrightTip:
     'Part of the content is sourced from the internet. If there is any infringement, please contact me to delete it',

+ 1 - 0
src/locales/zh/home.ts

@@ -2,6 +2,7 @@ import { nameSpaceWrap } from '@/locales/util';
 
 export default nameSpaceWrap('home', {
   recommendLive: '推荐直播',
+  bilibiliLive: '哔哩哔哩直播',
   noliveRoomTip: '当前没有在线的直播间',
   copyrightTip: '部分内容来源网络,如有侵权,请联系我删除',
 });

+ 113 - 0
src/views/h5/room/index.vue

@@ -133,6 +133,27 @@
                     {{ item.userInfo?.username || item.socket_id }}离开直播!
                   </span>
                 </template>
+                <template v-else-if="item.msgType === DanmuMsgTypeEnum.reward">
+                  <span class="time">
+                    [{{ formatTimeHour(item.send_msg_time) }}]
+                  </span>
+                  <span class="name">
+                    <span v-if="item.userInfo">
+                      <span>{{ item.userInfo.username }}</span>
+                      <span>
+                        [{{
+                          item.userInfo.roles?.map((v) => v.role_name).join()
+                        }}]
+                      </span>
+                    </span>
+                    <span v-else>
+                      <span>{{ item.socket_id }}</span>
+                      <span>[游客]</span>
+                    </span>
+                    <span>:</span>
+                  </span>
+                  <span class="msg"> 打赏了:{{ item.msg }} </span>
+                </template>
               </div>
             </div>
           </div>
@@ -190,6 +211,49 @@
           </div>
         </n-tab-pane>
       </n-tabs>
+      <div class="user-info">
+        <template v-if="!userStore.userInfo">
+          <div
+            class="btn"
+            @click="appStore.showLoginModal = true"
+          >
+            登录
+          </div>
+        </template>
+        <Dropdown v-else>
+          <template #btn>
+            <div class="info">
+              <div
+                class="btn"
+                :style="{
+                  backgroundImage: `url(${userStore.userInfo.avatar})`,
+                }"
+              ></div>
+            </div>
+          </template>
+          <template #list>
+            <div class="list">
+              <a class="item">
+                <div class="txt">用户名:{{ userStore.userInfo.username }}</div>
+              </a>
+              <a class="item">
+                <div
+                  class="txt"
+                  @click="appStore.showLoginModal = true"
+                >
+                  切换账号
+                </div>
+              </a>
+              <a
+                class="item"
+                @click.prevent="handleLogout()"
+              >
+                <div class="txt">退出登录</div>
+              </a>
+            </div>
+          </template>
+        </Dropdown>
+      </div>
     </div>
 
     <div
@@ -233,6 +297,7 @@
 </template>
 
 <script lang="ts" setup>
+import { windowReload } from 'billd-utils';
 import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
 import { useRoute } from 'vue-router';
 
@@ -252,12 +317,14 @@ import {
 import router, { mobileRouterName } from '@/router';
 import { useAppStore } from '@/store/app';
 import { usePiniaCacheStore } from '@/store/cache';
+import { useUserStore } from '@/store/user';
 import { LiveRoomTypeEnum } from '@/types/ILiveRoom';
 import { formatTimeHour } from '@/utils';
 
 const route = useRoute();
 const cacheStore = usePiniaCacheStore();
 const appStore = useAppStore();
+const userStore = useUserStore();
 
 const bottomRef = ref<HTMLDivElement>();
 const danmuListRef = ref<HTMLDivElement>();
@@ -316,6 +383,13 @@ onMounted(() => {
   handleHistoryMsg();
 });
 
+function handleLogout() {
+  userStore.logout();
+  setTimeout(() => {
+    windowReload();
+  }, 300);
+}
+
 async function handleHistoryMsg() {
   try {
     const res = await fetchGetWsMessageList({
@@ -549,6 +623,7 @@ function startPull() {
   }
 
   .n-tab-wrap {
+    position: relative;
     padding-left: 10px;
     background: #0c1622;
     color: white;
@@ -562,6 +637,44 @@ function startPull() {
     // :deep(.n-tabs-pane-wrapper) {
     //   --n-pane-text-color: white;
     // }
+
+    .user-info {
+      position: absolute;
+      top: 3px;
+      right: 10px;
+      .info {
+        display: flex;
+        align-items: center;
+      }
+      .list {
+        width: 100px;
+        .item {
+          position: relative;
+          display: flex;
+          padding: 2px 15px;
+          cursor: pointer;
+          &:hover {
+            color: $theme-color-gold;
+          }
+        }
+      }
+      .btn {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        box-sizing: border-box;
+        margin-left: 10px;
+        width: 35px;
+        height: 35px;
+        border-radius: 50%;
+        background-color: $theme-color-papayawhip;
+        color: black;
+        font-size: 13px;
+        cursor: pointer;
+
+        @extend %containBg;
+      }
+    }
   }
   .danmu-list {
     box-sizing: border-box;

+ 71 - 13
src/views/home/index.vue

@@ -202,6 +202,57 @@
           </div>
         </div>
       </div>
+      <div class="area-item">
+        <div class="title">{{ t('home.bilibiliLive') }}</div>
+        <div class="live-room-list">
+          <div
+            v-for="(iten, indey) in bilibiliLiveRoomList"
+            :key="indey"
+            class="live-room"
+            @click="joinRoom(iten.live_room)"
+          >
+            <div
+              class="cover"
+              v-lazy:background-image="
+                iten?.live_room?.cover_img || iten?.user?.avatar
+              "
+            >
+              <PullAuthTip
+                v-if="
+                  iten.live_room?.pull_is_should_auth ===
+                  LiveRoomPullIsShouldAuthEnum.yes
+                "
+              ></PullAuthTip>
+              <div
+                v-if="
+                  iten?.live_room?.cdn === LiveRoomUseCDNEnum.yes &&
+                  [
+                    LiveRoomTypeEnum.tencent_css,
+                    LiveRoomTypeEnum.tencent_css_pk,
+                  ].includes(iten.live_room?.type!)
+                "
+                class="cdn-ico"
+              >
+                <div class="txt">CDN</div>
+              </div>
+              <div class="txt">{{ iten?.user?.username }}</div>
+            </div>
+            <div class="desc">{{ iten?.live_room?.name }}</div>
+          </div>
+          <div
+            v-if="bilibiliLoading"
+            class="null"
+          >
+            {{ t('common.loading') }}
+          </div>
+          <div
+            v-else-if="!bilibiliLiveRoomList.length"
+            class="null"
+          >
+            {{ t('common.nonedata') }}
+          </div>
+        </div>
+      </div>
     </div>
 
     <!-- <div
@@ -237,7 +288,7 @@ import { fetchLiveList } from '@/api/live';
 import { fetchFindLiveConfigByKey } from '@/api/liveConfig';
 import { sliderList } from '@/constant';
 import { usePull } from '@/hooks/use-pull';
-import { IBilibiliLiveUserRecommend, ILive, LiveLineEnum } from '@/interface';
+import { ILive, LiveLineEnum } from '@/interface';
 import { routerName } from '@/router';
 import { useAppStore } from '@/store/app';
 import {
@@ -252,7 +303,7 @@ const route = useRoute();
 const router = useRouter();
 const appStore = useAppStore();
 const canvasRef = ref<Element>();
-const loading = ref(false);
+const bilibiliLoading = ref(false);
 const showJoinBtn = ref(false);
 const topNums = ref(6);
 const configBg = ref('');
@@ -262,6 +313,7 @@ const configVideo = ref();
 // );
 const topLiveRoomList = ref<ILive[]>([]);
 const otherLiveRoomList = ref<ILive[]>([]);
+const bilibiliLiveRoomList = ref<ILive[]>([]);
 const currentLiveRoom = ref<ILive>();
 const interactionList = ref<any[]>([]);
 const videoWrapTmpRef = ref<HTMLDivElement>();
@@ -280,7 +332,6 @@ const {
   handlePlay,
 } = usePull(route.params.roomId as string);
 const isBottom = ref(false);
-const first = ref(true);
 const rootMargin = {
   bottom: 600,
   top: 0,
@@ -315,16 +366,19 @@ onMounted(() => {
 watch(
   () => isBottom.value,
   async (newval) => {
-    if (newval && !first.value) {
-      const arr = await handleBilibil();
-      otherLiveRoomList.value.push(...arr);
+    if (newval) {
+      const arr = await handleBilibilData();
+      bilibiliLiveRoomList.value.push(...arr);
     }
+  },
+  {
+    immediate: true,
   }
 );
 
-async function handleBilibil() {
-  if (loading.value) return [];
-  loading.value = true;
+async function handleBilibilData() {
+  if (bilibiliLoading.value) return [];
+  bilibiliLoading.value = true;
   let arr: any = [];
   try {
     pageParams.page += 1;
@@ -349,7 +403,7 @@ async function handleBilibil() {
     pageParams.page -= 1;
     console.log(error);
   }
-  loading.value = false;
+  bilibiliLoading.value = false;
   return arr;
 }
 
@@ -418,10 +472,10 @@ async function getLiveRoomList() {
       orderBy: 'desc',
     });
     if (res.code === 200) {
-      const arr: IBilibiliLiveUserRecommend[] = await handleBilibil();
-      first.value = false;
+      // const arr: IBilibiliLiveUserRecommend[] = await handleBilibilData();
+      // first.value = false;
       // @ts-ignore
-      res.data.rows.push(...arr);
+      // res.data.rows.push(...arr);
       topLiveRoomList.value = res.data.rows.slice(0, topNums.value);
       otherLiveRoomList.value = res.data.rows.slice(topNums.value);
       if (res.data.total) {
@@ -799,6 +853,10 @@ function joinRoom(data) {
             @extend %singleEllipsis;
           }
         }
+        .null {
+          width: 100%;
+          text-align: center;
+        }
       }
     }
   }

+ 3 - 0
src/views/my/index.vue

@@ -456,6 +456,9 @@ watch(
     if (newval?.live_rooms?.[0]) {
       liveRoomInfo.value = newval?.live_rooms[0];
     }
+  },
+  {
+    immediate: true,
   }
 );
 

+ 4 - 1
src/views/oauth/index.vue

@@ -76,9 +76,12 @@ onMounted(async () => {
       const info = { type: PlatformEnum.qqLogin, data: { code, qqExp } };
       if (isMobile) {
         try {
-          await handleQQLogin({
+          const flag = await handleQQLogin({
             data: info,
           });
+          if (flag) {
+            router.push({ name: routerName.h5 });
+          }
         } catch (error) {
           console.log(error);
         }