193 lines
9.8 KiB
Vue
193 lines
9.8 KiB
Vue
<template>
|
||
|
||
<div class="row justify-content-center">
|
||
<div class="col-12 col-md-8 col-lg-6">
|
||
<div class="card shadow">
|
||
<div class="card-header bg-primary text-white text-center">
|
||
<h4 class="mb-0">登錄匯款資料</h4>
|
||
</div>
|
||
<div class="card-body">
|
||
<form id="transferForm" @submit.prevent="submitForm" enctype="multipart/form-data" autocomplete="off">
|
||
<!-- 法會名稱 -->
|
||
<div class="mb-3">
|
||
<label for="activity_num" class="form-label">法會名稱 <span class="text-danger">*</span></label>
|
||
<select class="form-select" id="activity_num" v-model="formData.activity_num" required>
|
||
<option value="">請選擇</option>
|
||
<option v-for="activity in activities" :key="activity.num" :value="activity.num">
|
||
{{activity.subject}}
|
||
</option>
|
||
</select>
|
||
</div>
|
||
<!-- 姓名 -->
|
||
<div class="mb-3">
|
||
<label for="name" class="form-label">姓名 <span class="text-danger">*</span></label>
|
||
<input type="text" class="form-control" id="name" v-model="formData.name" required maxlength="50" placeholder="請輸入姓名" @blur="onNameBlur">
|
||
</div>
|
||
<!-- 電話 -->
|
||
<div class="mb-3">
|
||
<label for="phone" class="form-label">電話 <span class="text-danger">*</span></label>
|
||
<input type="tel" class="form-control" id="phone" v-model="formData.phone" required maxlength="30" placeholder="請輸入聯絡電話">
|
||
</div>
|
||
<!-- 支付方式 -->
|
||
<div class="mb-3">
|
||
<label for="pay_type" class="form-label">支付方式 <span class="text-danger">*</span></label>
|
||
<select class="form-select" id="pay_type" v-model="formData.pay_type" required>
|
||
<option value="">請選擇</option>
|
||
<option v-for="(desc, value) in payTypes" :key="value" :value="value">
|
||
{{desc}}
|
||
</option>
|
||
</select>
|
||
</div>
|
||
<!-- 帳號後五碼 -->
|
||
<div class="mb-3">
|
||
<label for="account_last5" class="form-label">帳號後五碼(若無免填)</label>
|
||
<input type="text" class="form-control" id="account_last5" v-model="formData.account_last5" maxlength="10" placeholder="如有匯款請填寫">
|
||
</div>
|
||
<!-- 支付金額 -->
|
||
<div class="mb-3">
|
||
<label for="amount" class="form-label">支付金額 <span class="text-danger">*</span></label>
|
||
<input type="number" class="form-control" id="amount" v-model="formData.amount" required min="1" step="1" placeholder="請輸入金額">
|
||
</div>
|
||
<!-- 支付型態 -->
|
||
<div class="mb-3">
|
||
<label class="form-label">支付型態 <span class="text-danger">*</span></label>
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="radio" name="pay_mode" id="pay_mode1" value="個人" v-model="formData.pay_mode" checked>
|
||
<label class="form-check-label" for="pay_mode1">個人支付</label>
|
||
</div>
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="radio" name="pay_mode" id="pay_mode2" value="共同" v-model="formData.pay_mode">
|
||
<label class="form-check-label" for="pay_mode2">共同支付</label>
|
||
</div>
|
||
</div>
|
||
<!-- 備註 -->
|
||
<div class="mb-3">
|
||
<label for="note" class="form-label">備註</label>
|
||
<textarea class="form-control" id="note" v-model="formData.note" rows="2" maxlength="200" placeholder="如有分攤人名、金額、項目等請說明"></textarea>
|
||
</div>
|
||
<!-- 憑證上傳 -->
|
||
<div class="mb-3">
|
||
<label for="proof_img" class="form-label">上傳匯款憑證(可拍照)</label>
|
||
<input class="form-control" type="file" id="proof_img" @change="handleFileUpload" accept="image/*" capture="environment">
|
||
</div>
|
||
<!-- 送出/關閉 -->
|
||
<div class="d-grid gap-2">
|
||
<button type="submit" class="btn btn-primary btn-lg" :disabled="isSubmitting || !canSubmit">
|
||
{{ isSubmitting ? '處理中...' : '送出資料' }}
|
||
</button>
|
||
<button type="button" class="btn btn-outline-secondary" @click="closeWindow">離開</button>
|
||
</div>
|
||
</form>
|
||
<div class="mt-3 text-muted small">
|
||
<ul>
|
||
<li>如一位組頭幫多人匯款,請在備註欄分拆明細(人名、金額、項目等)。</li>
|
||
<li>送出後直接新增記錄,不顯示查核。</li>
|
||
<li>如無姓名/電話資料,系統會提示。</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
|
||
<script>
|
||
module.exports = {
|
||
// 1. 移除 el: '#register'
|
||
// 2. data 必須改成 function 形式
|
||
data() {
|
||
return {
|
||
activities: [],
|
||
formData: {
|
||
activity_num: '',
|
||
name: '',
|
||
phone: '',
|
||
pay_type: '',
|
||
account_last5: '',
|
||
amount: '',
|
||
pay_mode: '個人',
|
||
note: '',
|
||
proof_img: null
|
||
},
|
||
payTypes: {
|
||
'1': '現金',
|
||
'2': '匯款',
|
||
'3': '支票'
|
||
},
|
||
isSubmitting: false,
|
||
canSubmit: true
|
||
};
|
||
},
|
||
created() {
|
||
this.loadActivities();
|
||
},
|
||
methods: {
|
||
loadActivities() {
|
||
const today = new Date().toISOString().split('T')[0];
|
||
axios.get(`../../api/activity?endDate=${today}`)
|
||
.then(response => {
|
||
this.activities = response.data;
|
||
})
|
||
.catch(error => {
|
||
console.error('載入活動列表失敗:', error);
|
||
alert('載入活動列表失敗,請重新整理頁面');
|
||
});
|
||
},
|
||
handleFileUpload(event) {
|
||
this.formData.proof_img = event.target.files[0];
|
||
},
|
||
submitForm() {
|
||
if (this.isSubmitting || !this.canSubmit) return;
|
||
this.isSubmitting = true;
|
||
|
||
const formData = new FormData();
|
||
Object.keys(this.formData).forEach(key => {
|
||
if (this.formData[key] !== null) {
|
||
formData.append(key, this.formData[key]);
|
||
}
|
||
});
|
||
|
||
axios.post('../../api/transfer_register', formData, {
|
||
headers: {
|
||
'Content-Type': 'multipart/form-data'
|
||
}
|
||
})
|
||
.then(response => {
|
||
alert('資料已成功送出!');
|
||
this.formData = {
|
||
activity_num: '',
|
||
name: '',
|
||
phone: '',
|
||
pay_type: '',
|
||
account_last5: '',
|
||
amount: '',
|
||
pay_mode: '個人',
|
||
note: '',
|
||
proof_img: null
|
||
};
|
||
this.canSubmit = false;
|
||
})
|
||
.catch(error => {
|
||
console.error('送出失敗:', error);
|
||
// 增加錯誤保護,避免 response.data.message 不存在時報錯
|
||
const errorMsg = error.response && error.response.data && error.response.data.message
|
||
? error.response.data.message
|
||
: '請檢查網路連線或系統狀態';
|
||
alert('送出失敗 :' + errorMsg);
|
||
})
|
||
.finally(() => {
|
||
this.isSubmitting = false;
|
||
});
|
||
},
|
||
closeWindow() {
|
||
// 3. 修正關閉邏輯:因為現在是開在 Dialog 裡,window.close() 關不掉
|
||
// 改為觸發一個事件,通知父層 (index.aspx) 把彈跳視窗關掉
|
||
this.$emit('close-dialog');
|
||
},
|
||
onNameBlur() {
|
||
this.canSubmit = !!this.formData.name.trim();
|
||
}
|
||
}
|
||
};
|
||
</script> |