使用Laravel9、惯性、Vue3上传视频



我尝试制作课程表,课程图像表,课程视频表,我成功上传了图片,但没有上传视频这是我的模型课程。php关于视频:

public function video(): HasOne
{
return $this->hasOne(CourseVideo::class);
}

这里是我的模型coursevideo。php

<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentRelationsBelongsTo;
class CourseVideo extends Model
{
use HasFactory;
protected $fillable = ['filename'];
protected $appends = ['src'];
public function course(): BelongsTo
{
return $this->belongsTo(Course::class);
}
public function getSrcAttribute()
{
return asset("storage/{$this->filename}");
}
}
这是我的视频控制器:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppModelsCourse;
use AppModelsCourseVideo;
class RealtorCourseVideoController extends Controller
{
public function create(Course $course)
{
$course->load(['video']);
return inertia(
'Realtor/CourseVideo/Create',
['course' => $course]
);
}
public function store(Course $course, Request $request)
{
if ($request->hasFile('video')) {
$request->validate([
'video.*' => 'mimes:mp4,ogx,oga,ogv,ogg,webm'
], [
'video.*.mimes' => 'The file should be in one of the formats: mp4'
]);
foreach ($request->file('video') as $file) {
$path = $file->store('video', 'public');
$course->images()->save(new CourseVideo([
'filename' => $path
]));
}
}
}
}

这是我的视频迁移:

<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('course_videos', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('filename');
$table->foreignIdFor(
AppModelsCourse::class
)->constrained('courses');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('course_videos');
}
};

这里是我的Create.vue:

<template>
<div>
<div>Upload New Videos</div>
<form @submit.prevent="upload">
<section class="flex items-center gap-2 my-4">
<input
class="border rounded-md file:px-4 file:py-2 border-gray-200 dark:border-gray-700 file:text-gray-700 file:dark:text-gray-400 file:border-0 file:bg-gray-100 file:dark:bg-gray-800 file:font-medium file:hover:bg-gray-200 file:dark:hover:bg-gray-700 file:hover:cursor-pointer file:mr-4"
type="file" multiple @input="addFiles"
/>
<button
type="submit"
class="btn-outline disabled:opacity-25 disabled:cursor-not-allowed"
>
Upload
</button>
<button
type="reset" class="btn-outline"
@click="reset"
>
Reset
</button>
</section>
</form>
</div>
</template>


<script setup>
import { useForm, Link } from '@inertiajs/inertia-vue3'
import { Inertia } from '@inertiajs/inertia'
import NProgress from 'nprogress'
const props = defineProps({ course: Object })
Inertia.on('progress', (event) => {
if (event.detail.progress.percentage) {
NProgress.set((event.detail.progress.percentage / 100) * 0.9)
}
})
const form = useForm({
video: null,
})
const upload = () => {
form.post(
route('realtor.course.video.store', { course: props.course.id }),
)
}
const reset = () => form.reset('video')
</script>

这是我的web.php关于视频路由:


Route::prefix('realtor')
->name('realtor.')
->middleware('auth')
->group(function () {
Route::resource('course', RealtorCourseController::class)
->only(['index', 'destroy', 'edit', 'update', 'create', 'store', 'show']);
Route::resource('course.image', RealtorCourseImageController::class)
->only(['create', 'store', 'destroy']);
Route::resource('course.video', RealtorCourseVideoController::class)
->only(['create', 'store', 'destroy']);
});

我期待在我的数据库中收到视频,但没有到达!!!!!!

$request不能从反应作为uploadedFile即hasFile接收

作为base64图像/视频发送,所以只能使用has函数获取

获取并保存它。

在模型类中添加uploadImage函数

public function uploadImage($request,$fileNameColumn,$deleteOldFile = false)
{

if ($request->has($fileNameColumn)  && (preg_match('/^data:image/(w+);base64,/', $request->{$fileNameColumn}, $type) || preg_match('/^data:video/(w+);base64,/', $request->{$fileNameColumn}, $type))) {
$dir = '/uploads/videos_'.$this->id.'/'.$fileNameColumn;
$fileName = Str::kebab ($this->id.uniqid('vid_').time());

$details  = UploadsService::uploadBase64($request->{$fileNameColumn},$dir,$fileName,true,true);
$this->{$fileNameColumn} = $details['url'];
$this->save();
}
}
public static function uploadBase64($image_64,$directory,$filename,$replace_file_name_if_matched = false,$delete_if_name_is_matched = false)
{
$decodedImage = self::base64ToImage($image_64);
$file = self::decodedImageToUploadedFile($decodedImage);
$extension = explode('/', explode(':', substr($image_64, 0, strpos($image_64, ';')))[1])[1];
$filename = $filename.'.'.$extension;

$data =  self::uploadAccordingToStorageDisk($file,$directory,$filename,$replace_file_name_if_matched,$delete_if_name_is_matched);
unset($file);
return $data;
}
public static function base64ToImage($image_64)
{
$replace = substr($image_64, 0, strpos($image_64, ',')+1);
$image = str_replace($replace, '', $image_64);
$image = str_replace(' ', '+', $image);
$decodedImage = base64_decode($image);
return $decodedImage;
}
public static function decodedImageToUploadedFile($decodedImage)
{
//save in temp dir
$tmpFilePath = sys_get_temp_dir() . '/' . Str::uuid()->toString();
file_put_contents($tmpFilePath, $decodedImage);
// this just to help us get file info.
$tmpFile = new File($tmpFilePath);
$file = new UploadedFile(
$tmpFile->getPathname(),
$tmpFile->getFilename(),
$tmpFile->getMimeType(),
0,
true // Mark it as test, since the file isn't from real HTTP POST.
);
unset($tmpFile);
return $file;
}

public static function uploadAccordingToStorageDisk($file,$directory,$filename,$replace_file_name_if_matched = false,$delete_if_name_is_matched = false)
{

$filename = str_replace(['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '<', '>', '\', '/', '//', ' '], '', $filename);
checkIfDirectoryIsAvailable($directory);
if($delete_if_name_is_matched){
checkIfFileIsUploadedThenDelete(asset($directory.'/'.$filename));
}
if($replace_file_name_if_matched){
$isUploadedWithSameName = checkIfUploadedFileHasSameName(asset($directory .'/'. $filename));
$filename = $isUploadedWithSameName ? time() . '_' . $filename : $filename;
}
$filename = time() .'_'.$filename;
$uploaded = $file->move(
public_path($directory) //directory from public path becomes location of the file in uploads
,$filename);
if($uploaded){
return ['url' => $directory .'/'. $filename, 'name' => $filename];
}
throw new Exception('File could not be uploaded');
}

创建记录后调用imageUpload文件

$course->uploadImage($request,'video',true);

最新更新