initial project

This commit is contained in:
2026-06-25 22:39:06 +08:00
commit 5a5ac2fcde
110 changed files with 8693 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
<script setup>
import { ref, reactive } from "vue";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue";
import api from "@/axios";
const form = reactive({
file: null,
});
const flashMessage = ref("");
const errorMessage = ref("");
const processing = ref(false);
const submit = async () => {
if (!form.file) return;
processing.value = true;
flashMessage.value = "";
errorMessage.value = "";
// 💡 因為有二進位檔案,必須使用標準 FormData 封裝
const formData = new FormData();
formData.append('file', form.file);
try {
const response = await api.post("/api/expenses/import", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
console.log("上傳成功", response.data);
flashMessage.value = "🎉 財政部發票資料同步成功!已排重並寫入帳本。";
form.file = null; // 清空選取
} catch (error) {
console.error("上傳失敗", error.response?.data);
errorMessage.value = error.response?.data?.message || "匯入失敗,請確認 CSV 格式是否正確。";
} finally {
processing.value = false;
}
};
</script>
<template>
<AuthenticatedLayout>
<template #header>
<h2 class="text-xl font-semibold text-gray-800">匯入發票</h2>
</template>
<div class="py-8 max-w-xl mx-auto px-4">
<div class="bg-white rounded-lg shadow p-6">
<div v-if="flashMessage" class="mb-4 p-4 bg-green-50 text-green-700 rounded border border-green-200 text-sm">
{{ flashMessage }}
</div>
<div v-if="errorMessage" class="mb-4 p-4 bg-red-50 text-red-700 rounded border border-red-200 text-sm">
{{ errorMessage }}
</div>
<h3 class="text-lg font-medium text-gray-700 mb-2">📥 上傳財政部發票明細 CSV</h3>
<p class="text-sm text-gray-500 mb-6 leading-relaxed">
請上傳從財政部電子發票整合服務平台載具下載的消費明細 CSV 檔案
系統會自動比對發票號碼**重複的發票會自動略過**免擔心重複記帳
</p>
<form @submit.prevent="submit" class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-600 mb-1">選擇 CSV 檔案</label>
<input
type="file"
accept=".csv"
@change="form.file = $event.target.files[0]"
class="w-full border rounded px-3 py-2 text-sm bg-gray-50 file:mr-4 file:py-1 file:px-3 file:rounded file:border-0 file:text-xs file:font-semibold file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100"
/>
</div>
<div class="flex gap-3 pt-2">
<router-link to="/expenses" class="flex-1 text-center py-2 border rounded-md text-sm text-gray-600 hover:bg-gray-50">
返回帳本
</router-link>
<button
type="submit"
:disabled="!form.file || processing"
class="flex-[2] bg-indigo-600 text-white py-2 rounded-md text-sm font-medium hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed shadow-sm transition-all"
>
{{ processing ? "⚙️ 正在解析並套用自動分類規則..." : "確認開始匯入" }}
</button>
</div>
</form>
</div>
</div>
</AuthenticatedLayout>
</template>