提交 57ef886b authored 作者: 王鹏飞's avatar 王鹏飞

Merge branch 'ip' into gdrtvu

VITE_LOGIN_URL=https://login.segedu.cn/auth/login/index
VITE_LOGIN_URL=http://172.16.3.201:1001/auth/login/index
VITE_SAAS_LAB_URL=http://172.16.3.201:1008
VITE_SAAS_DML_URL=http://172.16.3.201:1006
VITE_STATIC_URL=https://saas-lab-api
VITE_LOGIN_URL=https://login.ezijing.com/auth/login/index
VITE_LOGIN_URL=https://login.zijing.chat/auth/login/index
VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index
VITE_LOGIN_URL=https://login2.zijing.chat/auth/login/index
......@@ -4,7 +4,7 @@
"type": "module",
"scripts": {
"dev": "vite --mode dev",
"build": "vue-tsc --noEmit && vite build --mode prod && npm run deploy",
"build": "vue-tsc --noEmit && vite build --mode prod",
"build:test": "vue-tsc --noEmit && vite build --mode test",
"build:pre": "vue-tsc --noEmit && vite build --mode pre",
"preview": "vite preview --port 4173",
......
......@@ -85,3 +85,22 @@ export function getCourseList() {
export function getCourseChapterList(params: { course_id: string }) {
return httpRequest.get('/api/learn/api/v1/chapter/all', { params })
}
// 获取分片大小和唯一文件名
export function getLocalFileChunk(params: { file_size: number; file_name: string }) {
return httpRequest.get('/api/lab/v1/common/file/chunk', { params })
}
// 上传每个分片前请求接口来获取当前文件是否超时,之前的分片是否被清理,如果被请求则拒绝处理。返回客户端错误码,让客户端户端不再续传剩余分片
// 1文件被清理 0文件未被清理
export function checkLocalFile(params: { file_name: string }) {
return httpRequest.get('/api/lab/v1/common/file/check', { params })
}
// 上传文件
export function uploadLocalFile(data: { file: File; file_name: string; is_continuingly?: number; now_package_num: number; total_package_num: number }) {
return httpRequest.post('/api/lab/v1/common/file/upload', data, {
withCredentials: false,
headers: { 'Content-Type': 'multipart/form-data' }
})
}
<script setup lang="ts">
import Editor from '@tinymce/tinymce-vue'
import md5 from 'blueimp-md5'
import { getSignature, uploadFile } from '@/api/base'
import { getLocalFileChunk, uploadLocalFile } from '@/api/base'
const props = defineProps({
height: {
......@@ -13,31 +12,24 @@ const props = defineProps({
const ImageUploadHandler = (blobInfo: any) =>
new Promise((resolve, reject) => {
const file = blobInfo.blob()
getSignature()
getLocalFileChunk({ file_name: file.name, file_size: file.size })
.then((response: any) => {
const prefix = 'upload/admin/'
const key = prefix + md5(file.name + new Date().getTime()) + file.name.substr(file.name.lastIndexOf('.'))
const { accessid, policy, signature, host } = response
const params = {
key,
host,
OSSAccessKeyId: accessid,
policy,
signature,
success_action_status: '200',
file,
url: `${host}/${key}`
file_name: response.data.detail.file_name,
now_package_num: 1,
total_package_num: 1
}
uploadFile(params)
uploadLocalFile(params)
.then((res: any) => {
resolve(res.url)
resolve(res.data.detail.uri)
})
.catch(() => {
reject('上传失败')
})
})
.catch(() => {
reject('获取Signature失败')
reject('上传失败')
})
})
......
......@@ -2,9 +2,9 @@
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { UploadProps, UploadUserFile, UploadFile, UploadFiles, UploadInstance } from 'element-plus'
import md5 from 'blueimp-md5'
// import md5 from 'blueimp-md5'
import axios from 'axios'
import { getSignature } from '@/api/base'
import { getLocalFileChunk } from '@/api/base'
interface Props {
modelValue: string | { name: string; url: string }[]
......@@ -37,29 +37,23 @@ const showFileList = computed(() => {
// 自定义上传
const handleHttpRequest: UploadProps['httpRequest'] = async xhr => {
const name = xhr.file.name
const key = `${props.prefix}${md5(name + Date.now())}.${name.split('.').pop()}`
const signature: Record<string, any> = await getSignature()
const signature: Record<string, any> = await getLocalFileChunk({ file_name: xhr.file.name, file_size: xhr.file.size })
const params = {
key,
host: signature.host,
OSSAccessKeyId: signature.accessid,
policy: signature.policy,
signature: signature.signature,
success_action_status: '200',
url: `${signature.host}/${key}`,
file_name: signature.data.detail.file_name,
now_package_num: 1,
total_package_num: 1,
file: xhr.file
}
return axios
.post(params.host || 'https://webapp-pub.ezijing.com', Object.assign(params, xhr.data), {
.post('/api/lab/v1/common/file/upload', Object.assign(params, xhr.data), {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress(progress: any) {
progress.percent = progress.total > 0 ? (progress.loaded / progress.total) * 100 : 0
xhr.onProgress(progress)
}
})
.then(() => {
return params
.then(res => {
return { ...params, url: res.data.data.detail.uri }
})
}
......
......@@ -11,22 +11,22 @@ const logout = async () => {
await userStore.logout()
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.origin)}`
}
const SAAS_LAB_URL = import.meta.env.VITE_SAAS_LAB_URL
const SAAS_DML_URL = import.meta.env.VITE_SAAS_DML_URL
</script>
<template>
<header class="app-header">
<div class="app-header-left">
<div class="logo">
<router-link to="/"
><img src="https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/base/ezijing-logo-white.svg"
/></router-link>
<router-link to="/"><img src="https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/base/ezijing-logo-white.svg" /></router-link>
</div>
<h1 class="app-name">数字技能实训中心</h1>
</div>
<div class="app-header-center">
<a href="/" class="is-active">理论课程</a>
<!-- <a href="https://saas-lab.ezijing.com" target="_blank">商业数据分析</a> -->
<a href="https://saas-dml-web.ezijing.com" target="_blank">数字营销</a>
<!-- <a :href="SAAS_LAB_URL" target="_blank">商业数据分析</a> -->
<a :href="SAAS_DML_URL" target="_blank">数字营销</a>
</div>
<div class="app-header-right">
<el-dropdown v-if="userInfo">
......
......@@ -117,7 +117,10 @@ const progress = reactive<VideoRecordType>({
})
let playList = $ref<PlayItemType[]>([])
const currentPlayList = $computed<PlayItemType[]>(() => {
const currentPlayList = $computed<any>(() => {
if (resource?.info.video_type === 2) {
return [{ PlayURL: resource?.info.video_play_address }]
}
return playList
.filter(item => item.StreamType === 'video' && item.Format === 'mp4')
.map(item => {
......@@ -156,7 +159,11 @@ async function fetchVideoRecords() {
watchEffect(async () => {
if (!resource) return
await fetchVideoRecords()
await fetchInfo()
try {
await fetchInfo()
} catch (error) {
console.log(error)
}
console.log('watch', progress.current_playing_time)
changeSrc(currentPlayList[0])
})
......
......@@ -88,6 +88,8 @@ export interface FileType {
source_id: string
ppt_arr?: PptType[]
can_download: number
video_type?: 1 | 2
video_play_address?: string
}
export interface PptType {
......
......@@ -62,6 +62,16 @@ httpRequest.interceptors.response.use(
ElMessage.error(data.message || data.msg)
return Promise.reject(data)
}
if (import.meta.env.VITE_STATIC_URL) {
try {
const regex = /(http|https):\/\/(.*?)saas-lab-api/gi
return JSON.parse(JSON.stringify(data).replaceAll(regex, import.meta.env.VITE_STATIC_URL))
} catch (error) {
console.log(error)
}
}
return data
},
function (error) {
......
......@@ -7,8 +7,8 @@ import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/saas-learn/' : '/',
export default defineConfig(() => ({
// base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/saas-learn/' : '/',
plugins: [
vue({ reactivityTransform: true }),
AutoImport({
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论