feat: 🎸 后台课程视频上传对接接口
This commit is contained in:
parent
ee45ac1e90
commit
c4f1b2818b
@ -56,20 +56,21 @@ func (c *cUpload) UploadVideo(ctx context.Context, _ *common.UploadVideoReq) (re
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m3u8UUID := uuid.New().String()
|
||||||
|
|
||||||
// 1. 保存上传视频到本地临时目录
|
// 1. 保存上传视频到本地临时目录
|
||||||
tmpDir := "./tmp/video"
|
tmpDir := "./tmp/video"
|
||||||
_, _ = file.Save(tmpDir)
|
_, _ = file.Save(tmpDir + "/" + m3u8UUID)
|
||||||
tmpFile := tmpDir + "/" + file.Filename
|
tmpFile := tmpDir + "/" + m3u8UUID + "/" + file.Filename
|
||||||
|
|
||||||
// 2. 用ffmpeg切片为m3u8和ts文件
|
// 2. 用ffmpeg切片为m3u8和ts文件
|
||||||
|
|
||||||
m3u8UUID := uuid.New().String()
|
|
||||||
|
|
||||||
hlsDir := "./tmp/hls/" + m3u8UUID
|
hlsDir := "./tmp/hls/" + m3u8UUID
|
||||||
_ = os.MkdirAll(hlsDir, 0755)
|
_ = os.MkdirAll(hlsDir, 0755)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
os.RemoveAll(hlsDir)
|
os.RemoveAll(hlsDir)
|
||||||
|
os.RemoveAll(tmpDir + "/" + m3u8UUID)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
m3u8File := m3u8UUID + ".m3u8"
|
m3u8File := m3u8UUID + ".m3u8"
|
||||||
@ -99,6 +100,8 @@ func (c *cUpload) UploadVideo(ctx context.Context, _ *common.UploadVideoReq) (re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m3u8MinioPath = storager.LastUrl(ctx, m3u8MinioPath, "minio")
|
||||||
|
|
||||||
// 4. 返回m3u8文件的minio路径
|
// 4. 返回m3u8文件的minio路径
|
||||||
return common.UploadVideoRes{
|
return common.UploadVideoRes{
|
||||||
Path: m3u8MinioPath,
|
Path: m3u8MinioPath,
|
||||||
|
@ -1,25 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<n-modal
|
<n-modal v-model:show="showModal" :mask-closable="false" :show-icon="false" preset="dialog"
|
||||||
v-model:show="showModal"
|
transform-origin="center" :title="formValue.id > 0 ? '编辑课程章节 #' + formValue.id : '添加课程章节'" :style="{
|
||||||
:mask-closable="false"
|
|
||||||
:show-icon="false"
|
|
||||||
preset="dialog"
|
|
||||||
transform-origin="center"
|
|
||||||
:title="formValue.id > 0 ? '编辑课程章节 #' + formValue.id : '添加课程章节'"
|
|
||||||
:style="{
|
|
||||||
width: dialogWidth,
|
width: dialogWidth,
|
||||||
}"
|
}">
|
||||||
>
|
|
||||||
<n-scrollbar style="max-height: 87vh" class="pr-5">
|
<n-scrollbar style="max-height: 87vh" class="pr-5">
|
||||||
<n-spin :show="loading" description="请稍候...">
|
<n-spin :show="loading" description="请稍候...">
|
||||||
<n-form
|
<n-form ref="formRef" :model="formValue" :label-placement="settingStore.isMobile ? 'top' : 'left'"
|
||||||
ref="formRef"
|
:label-width="100" class="py-4">
|
||||||
:model="formValue"
|
|
||||||
:label-placement="settingStore.isMobile ? 'top' : 'left'"
|
|
||||||
:label-width="100"
|
|
||||||
class="py-4"
|
|
||||||
>
|
|
||||||
<n-grid cols="1 s:1 m:1 l:1 xl:1 2xl:1" responsive="screen">
|
<n-grid cols="1 s:1 m:1 l:1 xl:1 2xl:1" responsive="screen">
|
||||||
<n-gi span="1">
|
<n-gi span="1">
|
||||||
<n-form-item label="课程id" path="lessonId">
|
<n-form-item label="课程id" path="lessonId">
|
||||||
@ -28,7 +16,16 @@
|
|||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi span="1">
|
<n-gi span="1">
|
||||||
<n-form-item label="视频url" path="videoUrl">
|
<n-form-item label="视频url" path="videoUrl">
|
||||||
<n-input placeholder="请输入视频url" v-model:value="formValue.videoUrl" />
|
<n-upload
|
||||||
|
:action="`${uploadUrl}${urlPrefix}/upload/video`"
|
||||||
|
:max="1"
|
||||||
|
:show-file-list="false"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
@finish="handleVideoUpload"
|
||||||
|
@before-upload="handleVideoUploadStart"
|
||||||
|
>
|
||||||
|
<n-button :loading="uploadingVideo">上传视频</n-button>
|
||||||
|
</n-upload>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi span="1">
|
<n-gi span="1">
|
||||||
@ -70,79 +67,111 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, reactive } from 'vue';
|
||||||
import { useDictStore } from '@/store/modules/dict';
|
import { useDictStore } from '@/store/modules/dict';
|
||||||
import { Edit, View } from '@/api/lessonSection';
|
import { Edit, View } from '@/api/lessonSection';
|
||||||
import { State, newState } from './model';
|
import { State, newState } from './model';
|
||||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||||
import { useMessage } from 'naive-ui';
|
import { useMessage } from 'naive-ui';
|
||||||
import { adaModalWidth } from '@/utils/hotgo';
|
import { adaModalWidth } from '@/utils/hotgo';
|
||||||
|
import { useGlobSetting } from '@/hooks/setting';
|
||||||
|
import { useUserStoreWidthOut } from '@/store/modules/user';
|
||||||
|
|
||||||
const emit = defineEmits(['reloadTable']);
|
const globSetting = useGlobSetting();
|
||||||
const message = useMessage();
|
const urlPrefix = globSetting.urlPrefix || '';
|
||||||
const settingStore = useProjectSettingStore();
|
const { uploadUrl } = globSetting;
|
||||||
const dict = useDictStore();
|
|
||||||
const loading = ref(false);
|
const useUserStore = useUserStoreWidthOut();
|
||||||
const showModal = ref(false);
|
const uploadHeaders = reactive({
|
||||||
const formValue = ref<State>(newState(null));
|
Authorization: useUserStore.token,
|
||||||
const formRef = ref<any>({});
|
uploadType: 'default',
|
||||||
const formBtnLoading = ref(false);
|
|
||||||
const dialogWidth = computed(() => {
|
|
||||||
return adaModalWidth(840);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交表单
|
const emit = defineEmits(['reloadTable']);
|
||||||
function confirmForm(e) {
|
const message = useMessage();
|
||||||
e.preventDefault();
|
const settingStore = useProjectSettingStore();
|
||||||
formRef.value.validate((errors) => {
|
const dict = useDictStore();
|
||||||
if (!errors) {
|
const loading = ref(false);
|
||||||
formBtnLoading.value = true;
|
const showModal = ref(false);
|
||||||
Edit(formValue.value)
|
const formValue = ref<State>(newState(null));
|
||||||
.then((_res) => {
|
const formRef = ref<any>({});
|
||||||
message.success('操作成功');
|
const formBtnLoading = ref(false);
|
||||||
closeForm();
|
const dialogWidth = computed(() => {
|
||||||
emit('reloadTable');
|
return adaModalWidth(840);
|
||||||
})
|
});
|
||||||
.finally(() => {
|
const uploadingVideo = ref(false);
|
||||||
formBtnLoading.value = false;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
message.error('请填写完整信息');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭表单
|
// 提交表单
|
||||||
function closeForm() {
|
function confirmForm(e) {
|
||||||
showModal.value = false;
|
e.preventDefault();
|
||||||
loading.value = false;
|
formRef.value.validate((errors) => {
|
||||||
}
|
if (!errors) {
|
||||||
|
formBtnLoading.value = true;
|
||||||
// 打开模态框
|
Edit(formValue.value)
|
||||||
function openModal(state: State) {
|
.then((_res) => {
|
||||||
showModal.value = true;
|
message.success('操作成功');
|
||||||
|
closeForm();
|
||||||
// 新增
|
emit('reloadTable');
|
||||||
if (!state || state.id < 1) {
|
})
|
||||||
formValue.value = newState(state);
|
.finally(() => {
|
||||||
|
formBtnLoading.value = false;
|
||||||
return;
|
});
|
||||||
|
} else {
|
||||||
|
message.error('请填写完整信息');
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 编辑
|
// 关闭表单
|
||||||
loading.value = true;
|
function closeForm() {
|
||||||
View({ id: state.id })
|
showModal.value = false;
|
||||||
.then((res) => {
|
loading.value = false;
|
||||||
formValue.value = res;
|
}
|
||||||
})
|
|
||||||
.finally(() => {
|
// 打开模态框
|
||||||
loading.value = false;
|
function openModal(state: State) {
|
||||||
});
|
showModal.value = true;
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
if (!state || state.id < 1) {
|
||||||
|
formValue.value = newState(state);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
// 编辑
|
||||||
openModal,
|
loading.value = true;
|
||||||
});
|
View({ id: state.id })
|
||||||
|
.then((res) => {
|
||||||
|
formValue.value = res;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传完成回调
|
||||||
|
function handleVideoUpload({ file, event }) {
|
||||||
|
uploadingVideo.value = false;
|
||||||
|
let res = event?.target?.response
|
||||||
|
? JSON.parse(event.target.response)
|
||||||
|
: {};
|
||||||
|
if (res.code === 0 && res.data?.path) {
|
||||||
|
formValue.value.videoUrl = res.data.path;
|
||||||
|
message.success('视频上传成功');
|
||||||
|
} else {
|
||||||
|
message.error(res.message || '视频上传失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传开始回调
|
||||||
|
function handleVideoUploadStart() {
|
||||||
|
uploadingVideo.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openModal,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less"></style>
|
<style lang="less"></style>
|
Loading…
x
Reference in New Issue
Block a user