The Best Fluffy Pancakes recipe you will fall in love with. Full of tips and tricks to help you make the best pancakes.
今天做了一個職缺精選的圖片區塊,圖片原本是從後端請求而來,但是後來想到如果這個圖片都沒變動過,他能不能直接取得nuxt上面快取的圖片就好,不要都要跟後端要資料呢?
所以設計了一個機制,資料中帶有一個image_uuid的欄位,用它來當作資料的比對碼,當我後端更新圖片時,就同時更新這個uuid碼。到前端時用image_uuid做為圖片的檔案名稱,並到指定的位子取得圖片,如果現在還沒有快取的圖片,或是因為圖片更新導致image_uuid比對不上,就會觸發@error事件,這時候再去跟後端要一次資料,儲存圖片之後重新再render一次圖片,這樣就完成了~
const defaultImageUrl = '/web/_nuxt/assets/images/maintain.png';
const onImageError = async (index) => {
const row = featuredJobs.value[index]
row.imageUrl = defaultImageUrl;
try {
await fetchAndStoreImage(row)
row.imageUrl = getImageUrl(row);
}
catch (error) {
row.imageUrl = defaultImageUrl;
}
};
const getImageUrl = (row, isDefault) => {
let url = defaultImageUrl
try {
if (row?.image_uuid && row?.image && row.image.split('.')[1]) {
url = cacheImgUrl + row.id + '/' + row.image_uuid + '.' + row.image.split('.')[1]
}
}
catch (error) { }
return url
}
const fetchAndStoreImage = async (job) => {
try {
const response = await axios.get(`${backendImageUrl}${job.id}`, { responseType: 'blob' });
if (response.status !== 200) {
throw new Error(`Failed to fetch image: ${response.statusText}`);
}
const imageBlob = response.data;
const imageType = imageBlob.type.split('/')[1]
const imageFileName = `${job.image_uuid}.${imageType}`;
const formData = new FormData();
formData.append('file', imageBlob, imageFileName);
formData.append('job_id', job.id);
const uploadResponse = await $fetch('/api/upload_featured_job_image', {
method: 'POST',
body: formData,
});
if (!uploadResponse.status == 200) {
throw new Error('Failed to upload image');
}
} catch (error) {
console.error('Error in fetchAndStoreImage:', error);
throw error; // 將錯誤傳遞回上層
}
};
</script>
// 前端程式碼擷取,其中包含一些錯誤處裡的邏輯
// server/api/upload.ts
import path from 'path';
import fs from 'fs';
export default defineEventHandler(async (event) => {
const params = await readMultipartFormData(event);
const data = {};
let file = null;
params?.forEach((item) => {
if (item.type) {
file = item;
} else {
data[item.name] = item.data
}
});
if (!data?.job_id && !file) {
throw new Error('Missing job_id field');
}
const jobId = data.job_id;
const directory = path.join(process.cwd(), `/assets/images/featured_job/${jobId}/`);
const filePath = path.join(directory, file.filename);
if (fs.existsSync(directory)) {
fs.readdirSync(directory).forEach((file) => {
const filePath = path.join(directory, file);
if (fs.statSync(filePath).isFile()) {
fs.unlinkSync(filePath);
}
});
} else {
fs.mkdirSync(directory, { recursive: true })
}
fs.writeFileSync(filePath, file.data);
return {
status: 200,
message: 'Upload successful',
data,
};
});
// 接收圖片上傳nuxt server檔案