update komponen, stores, desain
This commit is contained in:
58
server/api/serverFile/[name].get.ts
Normal file
58
server/api/serverFile/[name].get.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { lookup } from 'mime-types'
|
||||
import { createError, setHeader, sendStream } from 'h3'
|
||||
|
||||
const FOLDER_PATH = '\\\\10.10.150.129\\Shared'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const rawName = event.context.params?.name as string | undefined
|
||||
if (!rawName) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Nama file tidak diberikan' })
|
||||
}
|
||||
|
||||
const name = decodeURIComponent(rawName)
|
||||
const safeName = path.basename(name)
|
||||
if (safeName !== name) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Nama file tidak valid' })
|
||||
}
|
||||
|
||||
const filePath = path.join(FOLDER_PATH, safeName)
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'File tidak ditemukan' })
|
||||
}
|
||||
|
||||
// Ambil ekstensi file (lowercase)
|
||||
const ext = path.extname(safeName).toLowerCase()
|
||||
let mimeType = (lookup(safeName) as string) || 'application/octet-stream'
|
||||
|
||||
// Koreksi MIME type umum
|
||||
switch (ext) {
|
||||
case '.mp4':
|
||||
mimeType = 'video/mp4'
|
||||
break
|
||||
case '.mkv':
|
||||
mimeType = 'video/x-matroska'
|
||||
break
|
||||
case '.avi':
|
||||
mimeType = 'video/x-msvideo'
|
||||
break
|
||||
case '.mov':
|
||||
mimeType = 'video/quicktime'
|
||||
break
|
||||
case '.exe':
|
||||
case '.msi':
|
||||
mimeType = 'application/octet-stream'
|
||||
break
|
||||
case '.gif':
|
||||
mimeType = 'image/gif'
|
||||
break
|
||||
}
|
||||
|
||||
setHeader(event, 'Content-Type', mimeType)
|
||||
setHeader(event, 'Cache-Control', 'no-cache')
|
||||
setHeader(event, 'Content-Disposition', `inline; filename="${safeName}"`)
|
||||
|
||||
const stream = fs.createReadStream(filePath)
|
||||
return sendStream(event, stream)
|
||||
})
|
||||
42
server/api/serverFile/files.get.ts
Normal file
42
server/api/serverFile/files.get.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
// server/api/serverFile/files.get.ts
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { promisify } from "util"
|
||||
|
||||
const readdir = promisify(fs.readdir)
|
||||
const stat = promisify(fs.stat)
|
||||
|
||||
// Lokasi folder network share (pastikan sudah di-mount / accessible dari server)
|
||||
const FOLDER_PATH = "\\\\10.10.150.129\\Shared"
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
|
||||
// Baca semua isi folder
|
||||
const files = await readdir(FOLDER_PATH, { withFileTypes: true })
|
||||
|
||||
// Filter file saja dan ambil metadata
|
||||
const list = await Promise.all(
|
||||
files
|
||||
.filter((f) => f.isFile())
|
||||
.map(async (f) => {
|
||||
const filePath = path.join(FOLDER_PATH, f.name)
|
||||
const info = await stat(filePath)
|
||||
return {
|
||||
name: f.name,
|
||||
size: info.size,
|
||||
modified: info.ctime,
|
||||
ext: path.extname(f.name),
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
return list.sort(
|
||||
(a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime()
|
||||
) // urut terbaru
|
||||
} catch (err: any) {
|
||||
console.error("Gagal sinkronisasi file:", err.message)
|
||||
return { error: err.message }
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user