Explorar o código

fix: 全面优化

shuisheng hai 1 ano
pai
achega
5df8661881

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 9212 - 0
public/TXLivePusher-2.1.1.min.js


+ 1 - 1
public/index.html

@@ -16,7 +16,7 @@
 
   <body>
     <script
-      src="https://video.sdk.qcloudecdn.com/web/TXLivePusher-2.1.1.min.js"
+      src="<%= BASE_URL %>TXLivePusher-2.1.1.min.js"
       charset="utf-8"
     ></script>
     <noscript>

+ 1 - 1
src/components/Avatar/index.vue

@@ -23,7 +23,7 @@ withDefaults(
   defineProps<{
     avatar: string;
     size: number;
-    living: boolean;
+    living?: boolean;
   }>(),
   {
     avatar: '',

+ 8 - 120
src/components/LoginModal/index.vue

@@ -74,27 +74,11 @@
                 登录
               </n-button>
             </n-tab-pane>
-            <n-tab-pane
-              v-if="MODULE_CONFIG_SWITCH.wechatQrcodeLogin && !isMobile()"
-              name="qrcodelogin"
-              tab="微信扫码登录"
-            >
-              <div
-                class="qrcode"
-                :style="{
-                  backgroundImage: `url(${base64})`,
-                }"
-              ></div>
-            </n-tab-pane>
           </n-tabs>
         </n-card>
-        <div
-          class="other-login"
-          v-if="MODULE_CONFIG_SWITCH.thirdLogin"
-        >
+        <div class="other-login">
           <span>第三方登录:</span>
           <div
-            v-if="MODULE_CONFIG_SWITCH.qqLogin"
             class="logo-wrap"
             @click="handleQQLogin()"
           >
@@ -104,17 +88,6 @@
             />
           </div>
           <div
-            v-if="MODULE_CONFIG_SWITCH.wechatLogin"
-            class="logo-wrap"
-            @click="handleWechatLogin()"
-          >
-            <img
-              class="logo"
-              src="@/assets/img/wechat_logo.webp"
-            />
-          </div>
-          <div
-            v-if="MODULE_CONFIG_SWITCH.githubLogin"
             class="logo-wrap"
             @click="handleGithubLogin"
           >
@@ -131,13 +104,9 @@
 
 <script lang="ts" setup>
 import { LockClosedOutline, PersonOutline } from '@vicons/ionicons5';
-import { getRandomString, isMobile, isWechat } from 'billd-utils';
-import QRCode from 'qrcode';
-import { onMounted, onUnmounted, reactive, ref } from 'vue';
+import { onMounted, onUnmounted, ref } from 'vue';
 
-import { fetchQrcodeLogin, fetchQrcodeLoginStatus } from '@/api/user';
-import { MODULE_CONFIG_SWITCH, QRCODE_LOGIN_URI } from '@/constant';
-import { useQQLogin, useWechatLogin } from '@/hooks/use-login';
+import { useQQLogin } from '@/hooks/use-login';
 import { useAppStore } from '@/store/app';
 import { useUserStore } from '@/store/user';
 
@@ -153,14 +122,8 @@ const loginForm = ref({
   id: '',
   password: '',
 });
-const qrcodeParams = reactive({
-  platform: 'wechat',
-  exp: 24,
-  loginId: '',
-});
-const base64 = ref('');
 const loginFormRef = ref(null);
-const currentTab = ref('pwdlogin'); // qrcodelogin,pwdlogin
+const currentTab = ref('pwdlogin'); // pwdlogin
 const loopTimer = ref();
 const emits = defineEmits(['close']);
 
@@ -169,18 +132,6 @@ onUnmounted(() => {
   clearInterval(loopTimer.value);
 });
 
-async function generateQR(text) {
-  let base64 = '';
-  try {
-    base64 = await QRCode.toDataURL(text, {
-      margin: 1,
-    });
-  } catch (err) {
-    console.error('生成二维码失败!', err);
-  }
-  return base64;
-}
-
 function handleGithubLogin() {
   window.$message.warning('敬请期待!');
 }
@@ -189,62 +140,6 @@ function handleQQLogin() {
   useQQLogin({ exp: 24 });
 }
 
-function handleWechatLogin() {
-  if (!isWechat()) {
-    window.$message.warning('请在微信打开!');
-  } else {
-    useWechatLogin({
-      platform: 'wechat',
-      exp: 24,
-      loginId: getRandomString(8),
-    });
-  }
-}
-
-async function handleWechatQrcodeLogin() {
-  const res = await fetchQrcodeLogin({
-    platform: qrcodeParams.platform,
-    exp: qrcodeParams.exp,
-  });
-  if (res.code === 200) {
-    qrcodeParams.loginId = res.data.login_id;
-    base64.value = await generateQR(
-      `${QRCODE_LOGIN_URI}?platform=${qrcodeParams.platform}&exp=${qrcodeParams.exp}&loginId=${qrcodeParams.loginId}`
-    );
-    handleLoopQrcodeLoginStatus();
-  } else {
-    window.$message.error(res.message);
-  }
-}
-
-function handleLoopQrcodeLoginStatus() {
-  clearInterval(loopTimer.value);
-  async function loopFn() {
-    try {
-      const res = await fetchQrcodeLoginStatus({
-        platform: qrcodeParams.platform,
-        login_id: qrcodeParams.loginId,
-      });
-      if (res.code === 200) {
-        if (res.data.isLogin && res.data.token) {
-          userStore.setToken(res.data.token, res.data.exp);
-          userStore.getUserInfo();
-          appStore.showLoginModal = false;
-          clearInterval(loopTimer.value);
-        }
-      } else {
-        window.$message.error(res.message);
-      }
-    } catch (error) {
-      console.log(error);
-    }
-  }
-
-  loopTimer.value = setInterval(() => {
-    loopFn();
-  }, 1000);
-}
-
 function handleClose() {
   appStore.showLoginModal = false;
   emits('close');
@@ -252,14 +147,10 @@ function handleClose() {
 
 const handleLogin = async () => {
   let token = null;
-  if (currentTab.value === 'qrcodelogin') {
-    handleWechatQrcodeLogin();
-  } else {
-    token = await userStore.pwdLogin({
-      id: +loginForm.value.id,
-      password: loginForm.value.password,
-    });
-  }
+  token = await userStore.pwdLogin({
+    id: +loginForm.value.id,
+    password: loginForm.value.password,
+  });
   if (token) {
     window.$message.success('登录成功!');
     userStore.getUserInfo();
@@ -278,9 +169,6 @@ const handleLoginSubmit = (e) => {
 const tabChange = (v) => {
   currentTab.value = v;
   clearInterval(loopTimer.value);
-  if (currentTab.value === 'qrcodelogin') {
-    handleWechatQrcodeLogin();
-  }
 };
 const focus = ref(false);
 const onFocus = () => {

+ 0 - 57
src/constant.ts

@@ -119,63 +119,6 @@ export const COOKIE_KEY = {
 
 export const lsKeyPrefix = 'billd_live___';
 
-export const MODULE_CONFIG_SWITCH = {
-  logo: true,
-  home: true,
-  area: true,
-  shop: true,
-  pullGiftList: true,
-  pullShowAuth: false,
-  // 后台入口
-  admin: true,
-  // app下载入口
-  appdownload: true,
-  // 文档
-  doc: true,
-  // 生态系统
-  ecosystem: true,
-  // 关于
-  about: true,
-  // 赞助
-  sponsors: true,
-  // 私有化部署
-  privatizationDeployment: true,
-  // github
-  github: true,
-  // 轮播
-  slider: true,
-  // 底部版权提示
-  copyrightNotice: true,
-  // 侧边栏
-  sidebar: true,
-  // 侧边栏排行榜
-  sidebarRank: true,
-  // 侧边栏商店
-  sidebarShop: true,
-  // 侧边栏订单
-  sidebarOrder: true,
-  // 支付
-  pay: true,
-  // 第三方登录
-  thirdLogin: true,
-  // qq登录
-  qqLogin: true,
-  // 微信扫码登录
-  wechatQrcodeLogin: false,
-  // 微信登录
-  wechatLogin: false,
-  // github登录
-  githubLogin: true,
-  // 我要开播按钮
-  startLive: true,
-  // srs开播
-  startLiveSRS: true,
-  // webrtc开播
-  startLiveWebRTC: true,
-  // msr开播
-  startLiveWebMSR: true,
-};
-
 // 全局的localStorage的key
 export const lsKey = {
   lastBuildDate: 'lastBuildDate',

+ 4 - 4
src/directives/loading/index.ts

@@ -1,12 +1,12 @@
 import { App, ComponentPublicInstance, Directive, createApp } from 'vue';
 
-import main from '@/components/FullLoading/main.vue';
+import fullLoading from '@/components/FullLoading/main.vue';
 
 const map = new Map<
   HTMLElement,
   {
     app: App<Element>;
-    instance: ComponentPublicInstance<InstanceType<typeof main>>;
+    instance: ComponentPublicInstance<InstanceType<typeof fullLoading>>;
   }
 >();
 
@@ -20,10 +20,10 @@ export const directiveLoading: Directive = {
   // 及他自己的所有子节点都挂载完成后调用
   mounted(el, binding) {
     const { value } = binding;
-    const app = createApp(main);
+    const app = createApp(fullLoading);
     const container = document.createElement('div');
     // @ts-ignore
-    const instance: ComponentPublicInstance<InstanceType<typeof main>> =
+    const instance: ComponentPublicInstance<InstanceType<typeof fullLoading>> =
       app.mount(container);
     el.appendChild(container);
     instance.loading = value;

+ 0 - 2
src/layout/mobile/head/index.vue

@@ -7,7 +7,6 @@
       ></div>
       <div class="top-right">
         <a
-          v-if="MODULE_CONFIG_SWITCH.github"
           class="github"
           target="_blank"
           href="https://github.com/galaxy-s10/billd-live"
@@ -64,7 +63,6 @@
 import { onMounted, ref } from 'vue';
 import { useRoute } from 'vue-router';
 
-import { MODULE_CONFIG_SWITCH } from '@/constant';
 import router, { mobileRouterName } from '@/router';
 import { AppRootState, useAppStore } from '@/store/app';
 import { useUserStore } from '@/store/user';

+ 8 - 1
src/layout/pc/head/index.vue

@@ -324,7 +324,14 @@
             <div class="list">
               <a
                 class="item"
-                @click.prevent="router.push({ name: routerName.account })"
+                @click.prevent="
+                  router.push({
+                    name: routerName.profile,
+                    params: {
+                      userId: userStore.userInfo.id,
+                    },
+                  })
+                "
               >
                 <div class="txt">{{ t('layout.profile') }}</div>
               </a>

+ 1 - 2
src/layout/pc/index.vue

@@ -5,13 +5,12 @@
     <router-view v-slot="{ Component }">
       <component :is="Component"></component>
     </router-view>
-    <SidebarCpt v-if="MODULE_CONFIG_SWITCH.sidebar"></SidebarCpt>
+    <SidebarCpt></SidebarCpt>
     <LoginModal v-if="appStore.showLoginModal"></LoginModal>
   </div>
 </template>
 
 <script lang="ts" setup>
-import { MODULE_CONFIG_SWITCH } from '@/constant';
 import { useAppStore } from '@/store/app';
 
 import HeadCpt from './head/index.vue';

+ 6 - 15
src/router/index.ts

@@ -1,6 +1,7 @@
 import { isIPad, isMobile } from 'billd-utils';
 import { createRouter, createWebHistory } from 'vue-router';
 
+import { GoodsTypeEnum } from '@/interface';
 import MobileLayout from '@/layout/mobile/index.vue';
 import PcLayout from '@/layout/pc/index.vue';
 
@@ -24,7 +25,6 @@ export const routerName = {
   about: 'about',
   area: 'area',
   areaDetail: 'areaDetail',
-  account: 'account',
   rank: 'rank',
   sponsors: 'sponsors',
   privatizationDeployment: 'privatizationDeployment',
@@ -124,25 +124,21 @@ export const defaultRoutes: RouteRecordRaw[] = [
         path: '/profile/:userId',
         component: () => import('@/views/profile/index.vue'),
       },
-      {
-        name: routerName.account,
-        path: '/account',
-        component: () => import('@/views/account/index.vue'),
-      },
       {
         name: routerName.sponsors,
         path: '/sponsors',
-        component: () => import('@/views/sponsors/index.vue'),
+        component: () => import('@/views/doc/sponsors/index.vue'),
       },
       {
         name: routerName.privatizationDeployment,
         path: '/privatizationDeployment',
-        component: () => import('@/views/privatizationDeployment/index.vue'),
+        component: () =>
+          import('@/views/doc/privatizationDeployment/index.vue'),
       },
       {
         name: routerName.support,
         path: '/support',
-        component: () => import('@/views/support/index.vue'),
+        redirect: `/shop?goodsType=${GoodsTypeEnum.support}`,
       },
       {
         name: routerName.order,
@@ -157,7 +153,7 @@ export const defaultRoutes: RouteRecordRaw[] = [
       {
         name: routerName.ad,
         path: '/ad',
-        component: () => import('@/views/ad/index.vue'),
+        component: () => import('@/views/doc/ad/index.vue'),
       },
 
       {
@@ -204,11 +200,6 @@ export const defaultRoutes: RouteRecordRaw[] = [
     path: '/h5/:roomId',
     component: () => import('@/views/h5/room/index.vue'),
   },
-  {
-    name: commonRouterName.qrcodeLogin,
-    path: '/qrcodeLogin',
-    component: () => import('@/views/qrcodeLogin/index.vue'),
-  },
 ];
 
 const router = createRouter({

+ 6 - 0
src/types/ILiveRoom.ts

@@ -228,6 +228,12 @@ export interface ILiveRoom {
   rtmp_url?: string;
   flv_url?: string;
   hls_url?: string;
+  webrtc_url?: string;
+  push_rtmp_url?: string;
+  push_obs_server?: string;
+  push_obs_stream_key?: string;
+  push_webrtc_url?: string;
+  push_srt_url?: string;
   /** 直播间备注 */
   remark?: string;
 

+ 0 - 169
src/views/account/index.vue

@@ -1,169 +0,0 @@
-<template>
-  <div class="profile-wrap">
-    <div class="uid">用户id:{{ userInfo?.id }}</div>
-    <div class="avatar">
-      <span class="txt">用户头像:</span>
-      <Avatar
-        :avatar="userInfo?.avatar"
-        :size="30"
-      ></Avatar>
-    </div>
-    <div class="username">用户昵称:{{ userInfo?.username }}</div>
-    <br />
-    <div class="pull-url">
-      <span>直播间信息:</span>
-      <span
-        v-if="!userInfo?.live_rooms?.length"
-        class="link"
-        @click="openLiveRoom"
-      >
-        未开通
-      </span>
-      <div v-else>
-        <div>
-          直播间地址:
-          <a
-            :href="getLiveRoomPageUrl(userInfo?.live_rooms?.[0].id!)"
-            class="link"
-            target="_blank"
-          >
-            {{ getLiveRoomPageUrl(userInfo?.live_rooms?.[0].id!) }}
-          </a>
-        </div>
-        <div>直播间名称:{{ userInfo?.live_rooms?.[0].name }}</div>
-        <div>直播间简介:{{ userInfo?.live_rooms?.[0].desc }}</div>
-        <template
-          v-if="
-            userStore.auths?.find(
-              (v) => v.auth_value === DEFAULT_AUTH_INFO.LIVE_PUSH.auth_value
-            )
-          "
-        >
-          <div
-            v-loading="keyLoading"
-            class="rtmp-url"
-          >
-            <span>
-              推流地址:{{
-                newRtmpUrl ||
-                handleUrl({
-                  url: userInfo?.live_rooms?.[0].rtmp_url!,
-                  token: userInfo?.live_rooms?.[0].key!,
-                })
-              }},
-            </span>
-            <span
-              class="link"
-              @click="handleCopy"
-            >
-              复制
-            </span>
-            <span>,</span>
-            <span
-              class="link"
-              @click="handleUpdateKey"
-            >
-              更新
-            </span>
-          </div>
-        </template>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { copyToClipBoard, openToTarget } from 'billd-utils';
-import { onMounted, ref } from 'vue';
-import { useRouter } from 'vue-router';
-
-import { fetchUpdateLiveRoomKey } from '@/api/liveRoom';
-import { fetchUserInfo } from '@/api/user';
-import { DEFAULT_AUTH_INFO, SRS_CB_URL_PARAMS } from '@/constant';
-import { loginTip } from '@/hooks/use-login';
-import { routerName } from '@/router';
-import { useUserStore } from '@/store/user';
-import { LiveRoomTypeEnum } from '@/types/ILiveRoom';
-import { IUser } from '@/types/IUser';
-import { getLiveRoomPageUrl } from '@/utils';
-
-const newRtmpUrl = ref();
-const keyLoading = ref(false);
-const router = useRouter();
-const userStore = useUserStore();
-
-const userInfo = ref<IUser>();
-
-async function handleUserInfo() {
-  const res = await fetchUserInfo();
-  if (res.code === 200) {
-    userInfo.value = res.data;
-  }
-}
-
-function handleCopy() {
-  copyToClipBoard(
-    newRtmpUrl.value ||
-      handleUrl({
-        url: userInfo.value?.live_rooms?.[0].rtmp_url!,
-        token: userInfo.value?.live_rooms?.[0].key!,
-      })
-  );
-  window.$message.success('复制成功!');
-}
-
-function openLiveRoom() {
-  if (!loginTip()) {
-    return;
-  }
-  const url = router.resolve({
-    name: routerName.push,
-    query: { liveType: LiveRoomTypeEnum.srs },
-  });
-  openToTarget(url.href);
-}
-
-function handleUrl(data: { url: string; token: string }) {
-  return `${data.url}?${SRS_CB_URL_PARAMS.publishKey}=${data.token}&${SRS_CB_URL_PARAMS.publishType}=${LiveRoomTypeEnum.obs}`;
-}
-
-async function handleUpdateKey() {
-  try {
-    keyLoading.value = true;
-    const res = await fetchUpdateLiveRoomKey();
-    if (res.code === 200) {
-      const resUrl = handleUrl({ url: res.data.rtmp_url, token: res.data.key });
-      newRtmpUrl.value = resUrl;
-    }
-  } catch (error) {
-    console.log(error);
-  } finally {
-    keyLoading.value = false;
-  }
-}
-
-onMounted(() => {
-  handleUserInfo();
-});
-</script>
-
-<style lang="scss" scoped>
-.profile-wrap {
-  padding: 10px;
-  .link {
-    color: $theme-color-gold;
-    text-decoration: none;
-    cursor: pointer;
-  }
-  .avatar {
-    display: flex;
-    align-items: center;
-    .txt {
-      margin-right: 10px;
-    }
-  }
-  .rtmp-url {
-    position: relative;
-  }
-}
-</style>

+ 0 - 0
src/views/ad/index.vue → src/views/doc/ad/index.vue


+ 0 - 0
src/views/privatizationDeployment/index.vue → src/views/doc/privatizationDeployment/index.vue


+ 0 - 0
src/views/sponsors/index.vue → src/views/doc/sponsors/index.vue


+ 3 - 5
src/views/h5/room/index.vue

@@ -87,7 +87,7 @@
                   <span class="name">
                     <span v-if="item.userInfo">
                       <span>{{ item.userInfo.username }}</span>
-                      <span v-if="MODULE_CONFIG_SWITCH.pullShowAuth">
+                      <span>
                         [{{
                           item.userInfo.roles?.map((v) => v.role_name).join()
                         }}]
@@ -95,9 +95,7 @@
                     </span>
                     <span v-else>
                       <span>{{ item.socket_id }}</span>
-                      <span v-if="MODULE_CONFIG_SWITCH.pullShowAuth">
-                        [游客]
-                      </span>
+                      <span> [游客] </span>
                     </span>
                     <span>:</span>
                   </span>
@@ -221,7 +219,7 @@ import { useRoute } from 'vue-router';
 
 import { fetchFindLiveConfigByKey } from '@/api/liveConfig';
 import { fetchFindLiveRoom } from '@/api/liveRoom';
-import { MODULE_CONFIG_SWITCH, THEME_COLOR } from '@/constant';
+import { THEME_COLOR } from '@/constant';
 import { emojiArray } from '@/emoji';
 import { usePull } from '@/hooks/use-pull';
 import { DanmuMsgTypeEnum, WsMessageMsgIsFileEnum } from '@/interface';

+ 3 - 15
src/views/home/index.vue

@@ -14,10 +14,7 @@
         autoplay
         loop
       ></video>
-      <div
-        v-if="MODULE_CONFIG_SWITCH.slider"
-        class="slider-wrap"
-      >
+      <div class="slider-wrap">
         <div
           v-for="(item, index) in interactionList"
           :key="index"
@@ -32,10 +29,6 @@
           ></Slider>
         </div>
       </div>
-      <div
-        v-else
-        class="slider-wrap"
-      ></div>
 
       <div class="container">
         <div
@@ -206,12 +199,7 @@
       </div>
     </div>
 
-    <div
-      class="foot"
-      v-if="MODULE_CONFIG_SWITCH.copyrightNotice"
-    >
-      *{{ t('home.copyrightTip') }}~
-    </div>
+    <div class="foot">*{{ t('home.copyrightTip') }}~</div>
   </div>
 </template>
 
@@ -222,7 +210,7 @@ import { useRoute, useRouter } from 'vue-router';
 
 import { fetchLiveList } from '@/api/live';
 import { fetchFindLiveConfigByKey } from '@/api/liveConfig';
-import { MODULE_CONFIG_SWITCH, sliderList } from '@/constant';
+import { sliderList } from '@/constant';
 import { usePull } from '@/hooks/use-pull';
 import { ILive, LiveLineEnum } from '@/interface';
 import { routerName } from '@/router';

+ 143 - 33
src/views/profile/index.vue

@@ -1,8 +1,5 @@
 <template>
-  <div
-    v-loading="loading"
-    class="profile-wrap"
-  >
+  <div class="profile-wrap">
     <div class="uid">用户id:{{ userInfo?.id }}</div>
     <div class="avatar">
       <span class="txt">用户头像:</span>
@@ -11,64 +8,174 @@
         :size="30"
       ></Avatar>
     </div>
-    <div>用户昵称:{{ userInfo?.username }}</div>
+    <div class="username">用户昵称:{{ userInfo?.username }}</div>
     <br />
-    <div>直播间信息:</div>
-    <div v-if="userInfo?.live_rooms?.length">
-      <div>
-        直播间地址:
-        <a
-          :href="getLiveRoomPageUrl(userInfo?.live_rooms?.[0].id!)"
-          class="link"
-          target="_blank"
+    <div class="pull-url">
+      <span
+        v-if="!userInfo?.live_rooms?.length"
+        class="link"
+        @click="openLiveRoom"
+      >
+        未开通
+      </span>
+      <div v-else>
+        <div>
+          直播间地址:
+          <a
+            :href="getLiveRoomPageUrl(userInfo?.live_rooms?.[0].id!)"
+            class="link"
+            target="_blank"
+          >
+            {{ getLiveRoomPageUrl(userInfo?.live_rooms?.[0].id!) }}
+          </a>
+        </div>
+        <div>直播间名称:{{ userInfo?.live_rooms?.[0].name }}</div>
+        <div>直播间简介:{{ userInfo?.live_rooms?.[0].desc }}</div>
+        <div>
+          直播间分区:{{ userInfo.live_rooms[0].areas?.[0].name || '暂无分区' }}
+        </div>
+        <div
+          v-if="
+            userStore.userInfo?.id === userInfo.id &&
+            userStore.auths?.find(
+              (v) => v.auth_value === DEFAULT_AUTH_INFO.LIVE_PUSH.auth_value
+            )
+          "
+          class="rtmp-url-wrap"
+          v-loading="keyLoading"
         >
-          {{ getLiveRoomPageUrl(userInfo?.live_rooms?.[0].id!) }}
-        </a>
-      </div>
-      <div>直播间名称:{{ userInfo.live_rooms[0].name }}</div>
-      <div>直播间简介:{{ userInfo.live_rooms[0].desc }}</div>
-      <div>
-        直播间分区:{{ userInfo.live_rooms[0].areas?.[0].name || '暂无分区' }}
+          <div>
+            <span>rtmp推流地址:{{ pushRes?.push_rtmp_url! }}, </span>
+            <span
+              class="link"
+              @click="handleCopy"
+            >
+              复制
+            </span>
+            <span>,</span>
+            <span
+              class="link"
+              @click="handleUpdateKey"
+            >
+              更新
+            </span>
+          </div>
+          <div>
+            <span> OBS服务器:{{ pushRes?.push_obs_server! }}, </span>
+            <span
+              class="link"
+              @click="handleCopy"
+            >
+              复制
+            </span>
+          </div>
+          <div>
+            <span> OBS推流码:{{ pushRes?.push_obs_stream_key! }}, </span>
+            <span
+              class="link"
+              @click="handleCopy"
+            >
+              复制
+            </span>
+          </div>
+        </div>
       </div>
     </div>
-    <span v-else>未开通</span>
   </div>
 </template>
 
 <script lang="ts" setup>
-import { onMounted, ref } from 'vue';
-import { useRoute } from 'vue-router';
+import { copyToClipBoard, openToTarget } from 'billd-utils';
+import { onMounted, ref, watch } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
 
+import { fetchUpdateLiveRoomKey } from '@/api/liveRoom';
 import { fetchFindUser } from '@/api/user';
+import { DEFAULT_AUTH_INFO, SRS_CB_URL_PARAMS } from '@/constant';
+import { loginTip } from '@/hooks/use-login';
+import { routerName } from '@/router';
+import { useUserStore } from '@/store/user';
+import { LiveRoomTypeEnum } from '@/types/ILiveRoom';
 import { IUser } from '@/types/IUser';
 import { getLiveRoomPageUrl } from '@/utils';
 
-const loading = ref(false);
+const newRtmpUrl = ref();
+const keyLoading = ref(false);
+const pushRes = ref();
 const route = useRoute();
+const router = useRouter();
+const userStore = useUserStore();
+
 const userInfo = ref<IUser>();
 
+watch(
+  () => route.params.userId,
+  (newval) => {
+    if (newval) {
+      handleUserInfo();
+    }
+  }
+);
+
+onMounted(() => {
+  handleUserInfo();
+});
+
 async function handleUserInfo() {
+  const userId = Number(route.params.userId as string);
+  const res = await fetchFindUser(userId);
+  if (res.code === 200) {
+    userInfo.value = res.data;
+  }
+  if (userStore.userInfo) {
+    const liveRoom = userStore.userInfo.live_rooms?.[0];
+    pushRes.value = liveRoom;
+  }
+}
+
+function handleCopy() {
+  copyToClipBoard(
+    newRtmpUrl.value ||
+      handleUrl({
+        url: userInfo.value?.live_rooms?.[0].rtmp_url!,
+        token: userInfo.value?.live_rooms?.[0].key!,
+      })
+  );
+  window.$message.success('复制成功!');
+}
+
+function openLiveRoom() {
+  if (!loginTip()) {
+    return;
+  }
+  const url = router.resolve({
+    name: routerName.push,
+    query: { liveType: LiveRoomTypeEnum.srs },
+  });
+  openToTarget(url.href);
+}
+
+function handleUrl(data: { url: string; token: string }) {
+  return `${data.url}?${SRS_CB_URL_PARAMS.publishKey}=${data.token}&${SRS_CB_URL_PARAMS.publishType}=${LiveRoomTypeEnum.obs}`;
+}
+
+async function handleUpdateKey() {
   try {
-    loading.value = true;
-    const res = await fetchFindUser(Number(route.params.userId as string));
+    keyLoading.value = true;
+    const res = await fetchUpdateLiveRoomKey();
     if (res.code === 200) {
-      userInfo.value = res.data;
+      pushRes.value = res.data;
     }
   } catch (error) {
     console.log(error);
   } finally {
-    loading.value = false;
+    keyLoading.value = false;
   }
 }
-
-onMounted(() => {
-  handleUserInfo();
-});
 </script>
 
 <style lang="scss" scoped>
 .profile-wrap {
-  position: relative;
   padding: 10px;
   .link {
     color: $theme-color-gold;
@@ -82,5 +189,8 @@ onMounted(() => {
       margin-right: 10px;
     }
   }
+  .rtmp-url-wrap {
+    position: relative;
+  }
 }
 </style>

+ 4 - 9
src/views/pull/index.vue

@@ -164,7 +164,6 @@
           <div class="price">¥{{ formatMoney(item.price) }}</div>
         </div>
         <div
-          v-if="MODULE_CONFIG_SWITCH.pullGiftList"
           class="item"
           @click="handleRecharge"
         >
@@ -240,7 +239,7 @@
                 "
               >
                 <span>{{ item.userInfo.username }}</span>
-                <span v-if="MODULE_CONFIG_SWITCH.pullShowAuth">
+                <span>
                   [{{ item.userInfo.roles?.map((v) => v.role_name).join() }}]
                 </span>
               </span>
@@ -251,7 +250,7 @@
               >
                 <template #btn>
                   <span>{{ item.userInfo.username }}</span>
-                  <span v-if="MODULE_CONFIG_SWITCH.pullShowAuth">
+                  <span>
                     [{{ item.userInfo.roles?.map((v) => v.role_name).join() }}]
                   </span>
                 </template>
@@ -291,7 +290,7 @@
               </Dropdown>
               <span v-else>
                 <span>{{ item.socket_id }}</span>
-                <span v-if="MODULE_CONFIG_SWITCH.pullShowAuth">[游客]</span>
+                <span>[游客]</span>
               </span>
             </span>
             <span>:</span>
@@ -410,11 +409,7 @@ import {
 } from '@/api/giftRecord';
 import { fetchGoodsList } from '@/api/goods';
 import { fetchGetWsMessageList } from '@/api/wsMessage';
-import {
-  MODULE_CONFIG_SWITCH,
-  QINIU_RESOURCE,
-  liveRoomTypeEnumMap,
-} from '@/constant';
+import { QINIU_RESOURCE, liveRoomTypeEnumMap } from '@/constant';
 import { emojiArray } from '@/emoji';
 import { commentAuthTip, loginTip } from '@/hooks/use-login';
 import { useFullScreen } from '@/hooks/use-play';

+ 0 - 53
src/views/qrcodeLogin/index.vue

@@ -1,53 +0,0 @@
-<template>
-  <div class="qrcodeLogin-wrap">
-    <div
-      class="btn"
-      @click="handleClick"
-    >
-      确认登录
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { useRoute } from 'vue-router';
-
-import { useWechatLogin } from '@/hooks/use-login';
-
-const route = useRoute();
-
-function handleClick() {
-  // eslint-disable-next-line
-  const { platform, loginId, exp } = route.query;
-  if (!platform || !loginId || !exp) {
-    window.$message.error('参数缺失!');
-    return;
-  }
-  if (platform === 'wechat') {
-    useWechatLogin({ platform, exp, loginId });
-  } else {
-    window.$message.error('platform错误!');
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.qrcodeLogin-wrap {
-  .btn {
-    position: fixed;
-    top: 50%;
-    left: 50%;
-    padding: 10px;
-    width: 100px;
-    border-radius: 10px;
-    background-color: $theme-color-gold;
-    color: white;
-    text-align: center;
-    font-size: 16px;
-    cursor: pointer;
-    transform: translate(-50%, -50%);
-
-    user-select: none;
-  }
-}
-</style>

+ 0 - 19
src/views/support/index.vue

@@ -1,19 +0,0 @@
-<template>
-  <div></div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted } from 'vue';
-
-import { GoodsTypeEnum } from '@/interface';
-import router, { routerName } from '@/router';
-
-onMounted(() => {
-  router.push({
-    name: routerName.shop,
-    query: { goodsType: GoodsTypeEnum.support },
-  });
-});
-</script>
-
-<style lang="scss" scoped></style>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio