Ver Fonte

update:视频上传线路配置

ct há 1 semana atrás
pai
commit
5bd5663153
6 ficheiros alterados com 108 adições e 65 exclusões
  1. 0 39
      src/main.js
  2. 2 0
      src/permission.js
  3. 78 0
      src/utils/adminUiConfig.js
  4. 6 1
      src/utils/hsy.js
  5. 19 0
      src/utils/runtimeConfig.js
  6. 3 25
      src/views/login.vue

+ 0 - 39
src/main.js

@@ -30,7 +30,6 @@ import DictTag from '@/components/DictTag'
 // 头部标签组件
 import VueMeta from 'vue-meta'
 import * as echarts from "echarts";
-import { getConfigByKey } from '@/api/system/config'
 import moment from 'moment'
 Vue.prototype.$moment = moment
 Vue.prototype.$runtimeConfig = {}
@@ -95,45 +94,7 @@ Vue.use(Element, {
 })
 
 Vue.config.productionTip = false
-async function initRuntimeConfig() {
-  try {
-    const res = await getConfigByKey('his.adminUi.config')
-
-    const configValue = res?.data?.configValue
-    if (!configValue) return
-
-    // 后端配置 JSON
-    const form = JSON.parse(configValue)
-
-    // 字段映射表(核心优化点)
-    const mapping = {
-      VUE_APP_OBS_ACCESS_KEY_ID: 'obsAccessKeyId',
-      VUE_APP_OBS_SECRET_ACCESS_KEY: 'obsSecretAccessKey',
-      VUE_APP_OBS_SERVER: 'obsServer',
-      VUE_APP_OBS_BUCKET: 'obsBucket',
-      VUE_APP_VIDEO_LINE_1: 'videoLinePrimary',
-      VUE_APP_VIDEO_LINE_2: 'videoLineSecondary',
-      VUE_APP_VIDEO_URL: 'volcanoVideoDomain',
-      VUE_APP_HSY_SPACE: 'volcanoVodSpace',
-      VUE_APP_LIVE_PATH: 'livePath',
-      VUE_APP_COS_BUCKET: 'cosBucket',
-      VUE_APP_LIVE_WS_URL: 'liveWebSocketUrl',
-      VUE_APP_COURSE_DEFAULT: 'courseDefaultType',
-      VUE_APP_COS_REGION: 'cosRegion'
-    }
-
-    // 写入运行时配置
-    Object.keys(mapping).forEach(key => {
-      Vue.prototype.$runtimeConfig[key] = form[mapping[key]] ?? null
-    })
-  } catch (e) {
-    console.error('初始化运行时配置失败', e)
-  }
-}
-
-
 async function bootstrap() {
-  // await initRuntimeConfig()
   new Vue({
     el: '#app',
     router,

+ 2 - 0
src/permission.js

@@ -4,6 +4,7 @@ import { Message } from 'element-ui'
 import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 import { getToken } from '@/utils/auth'
+import { loadRuntimeConfig } from '@/utils/runtimeConfig'
 
 NProgress.configure({ showSpinner: false })
 
@@ -22,6 +23,7 @@ router.beforeEach((to, from, next) => {
       if (store.getters.roles.length === 0) {
         // 判断当前用户是否已拉取完user_info信息
         store.dispatch('GetInfo').then(() => {
+          loadRuntimeConfig()
           store.dispatch('GenerateRoutes').then(accessRoutes => {
             // 根据roles权限生成可访问的路由表
             router.addRoutes(accessRoutes) // 动态添加可访问路由表

+ 78 - 0
src/utils/adminUiConfig.js

@@ -0,0 +1,78 @@
+/** 云存储单项配置(与 projectConfig tencent_cloud_config / tmp_secret_config 一致) */
+export function defaultCloudConfig() {
+  return {
+    secret_id: '',
+    secret_key: '',
+    bucket: '',
+    app_id: '',
+    region: '',
+    proxy: ''
+  }
+}
+
+export function defaultAdminUiForm() {
+  return {
+    tencent_cloud_config: defaultCloudConfig(),
+    tmp_secret_config: defaultCloudConfig(),
+    videoLinePrimary: '',
+    videoLineSecondary: '',
+    livePath: '',
+    volcanoVideoDomain: '',
+    volcanoVodSpace: '',
+    liveWebSocketUrl: '',
+    courseDefaultType: '1'
+  }
+}
+
+/** 加载配置:兼容旧版平铺字段(obsAccessKeyId、cosBucket 等) */
+export function normalizeAdminUiConfig(raw) {
+  if (!raw || typeof raw !== 'object') {
+    return defaultAdminUiForm()
+  }
+  const form = defaultAdminUiForm()
+  Object.keys(form).forEach(key => {
+    if (key === 'tencent_cloud_config' || key === 'tmp_secret_config') {
+      return
+    }
+    if (raw[key] !== undefined && raw[key] !== null) {
+      form[key] = raw[key]
+    }
+  })
+  if (raw.tencent_cloud_config && typeof raw.tencent_cloud_config === 'object') {
+    form.tencent_cloud_config = { ...defaultCloudConfig(), ...raw.tencent_cloud_config }
+  }
+  if (raw.tmp_secret_config && typeof raw.tmp_secret_config === 'object') {
+    form.tmp_secret_config = { ...defaultCloudConfig(), ...raw.tmp_secret_config }
+  }
+  const tc = form.tencent_cloud_config
+  if (raw.cosBucket && !tc.bucket) tc.bucket = raw.cosBucket
+  if (raw.cosRegion && !tc.region) tc.region = raw.cosRegion
+  const hw = form.tmp_secret_config
+  if (raw.obsAccessKeyId && !hw.secret_id) hw.secret_id = raw.obsAccessKeyId
+  if (raw.obsSecretAccessKey && !hw.secret_key) hw.secret_key = raw.obsSecretAccessKey
+  if (raw.obsBucket && !hw.bucket) hw.bucket = raw.obsBucket
+  if (raw.obsServer && !hw.proxy) hw.proxy = raw.obsServer.replace(/^https?:\/\//, '')
+  return form
+}
+
+/** 供 main.js / login.vue 写入 $runtimeConfig */
+export function buildRuntimeConfigFromAdminUi(form) {
+  const normalized = normalizeAdminUiConfig(form)
+  const tc = normalized.tencent_cloud_config || defaultCloudConfig()
+  const hw = normalized.tmp_secret_config || defaultCloudConfig()
+  return {
+    VUE_APP_OBS_ACCESS_KEY_ID: hw.secret_id || '',
+    VUE_APP_OBS_SECRET_ACCESS_KEY: hw.secret_key || '',
+    VUE_APP_OBS_SERVER: hw.proxy || '',
+    VUE_APP_OBS_BUCKET: hw.bucket || '',
+    VUE_APP_VIDEO_LINE_1: normalized.videoLinePrimary || '',
+    VUE_APP_VIDEO_LINE_2: normalized.videoLineSecondary || '',
+    VUE_APP_VIDEO_URL: normalized.volcanoVideoDomain || '',
+    VUE_APP_HSY_SPACE: normalized.volcanoVodSpace || '',
+    VUE_APP_LIVE_PATH: normalized.livePath || '/live',
+    VUE_APP_COS_BUCKET: tc.bucket || '',
+    VUE_APP_LIVE_WS_URL: normalized.liveWebSocketUrl || '',
+    VUE_APP_COURSE_DEFAULT: normalized.courseDefaultType || '1',
+    VUE_APP_COS_REGION: tc.region || ''
+  }
+}

+ 6 - 1
src/utils/hsy.js

@@ -1,9 +1,14 @@
 import TTUploader from 'tt-uploader'
 import Vue from "vue";
 import { HsyAssumeRoleService } from '@/api/course/userVideo'
-const  spaceName = Vue.prototype.$runtimeConfig.VUE_APP_HSY_SPACE
+
 export const uploadToHSY = async (file, onProgress, type, callBackUp) => {
   try {
+    const spaceName = Vue.prototype.$runtimeConfig.VUE_APP_HSY_SPACE
+    if (!spaceName) {
+      throw new Error('未配置火山云点播空间名称,请在「系统参数 → 前端配置」中填写「点播空间名称」')
+    }
+
     const res = await HsyAssumeRoleService()
     //console.log('火山云 STS 凭证:', res)
     const credentials = res.data.result.credentials

+ 19 - 0
src/utils/runtimeConfig.js

@@ -0,0 +1,19 @@
+import Vue from 'vue'
+import { getConfigByKey } from '@/api/system/config'
+import { buildRuntimeConfigFromAdminUi } from '@/utils/adminUiConfig'
+
+/** 从租户库 his.adminUi.config 加载运行时配置到 $runtimeConfig */
+export async function loadRuntimeConfig() {
+  try {
+    const res = await getConfigByKey('his.adminUi.config')
+    const configValue = res?.data?.configValue
+    if (!configValue) {
+      console.warn('his.adminUi.config 为空,火山云上传等能力可能不可用')
+      return
+    }
+    const form = JSON.parse(configValue)
+    Vue.prototype.$runtimeConfig = buildRuntimeConfigFromAdminUi(form)
+  } catch (error) {
+    console.error('加载运行时配置失败', error)
+  }
+}

+ 3 - 25
src/views/login.vue

@@ -96,8 +96,7 @@ import { encrypt, decrypt } from '@/utils/jsencrypt'
 import { getFirstLogin } from "@/api/login";
 // import WechatLoginDialog from "@/views/WechatLoginDialog";
 import { setToken } from "@/utils/auth";
-import {getConfigByKey} from "@/api/system/config";
-import Vue from 'vue'
+import { loadRuntimeConfig } from '@/utils/runtimeConfig'
 
 export default {
   name: "Login",
@@ -155,29 +154,8 @@ export default {
     this.getCookie();
   },
   methods: {
-    // 重新加载运行时配置
-    async reloadRuntimeConfig() {
-
-      try {
-        const res = await getConfigByKey('his.adminUi.config')
-
-        const configValue = res?.data?.configValue
-        if (!configValue) return
-
-        // 后端配置 JSON
-        const form = JSON.parse(configValue)
-
-        // 直接更新全局配置
-        const config = {
-          VUE_APP_LIVE_WS_URL: form.liveWebSocketUrl || '',
-          VUE_APP_COURSE_DEFAULT: form.courseDefaultType || '1',
-        }
-        // 更新到全局
-        Vue.prototype.$runtimeConfig = config
-
-      } catch (error) {
-        console.error('重新加载运行时配置异常:', error)
-      }
+    reloadRuntimeConfig() {
+      return loadRuntimeConfig()
     },
     checkFirstLogin() {
       getFirstLogin().then(res => {