Files
17168ERP/web/admin/transfer/verify2.aspx
yiming e6c6b1f43f 更正問題:
入帳必填檢查
修正牌位排版HTML
2025-09-05 08:14:03 +08:00

358 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%@ Page Title="出納核對金額" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="verify2.aspx.cs" Inherits="admin_transfer_verify2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<h5 class="mb-0">出納 - 核對金額階段2</h5>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<div id="verify-app">
<v-app>
<v-container>
<v-card>
<v-card-title class="bg-info white--text text-center">
<h5 class="mb-0">出納核對金額階段2</h5>
<v-spacer></v-spacer>
<v-btn color="primary" @click="submitData">送出</v-btn>
</v-card-title>
<v-card-text>
<v-data-table
:headers="headers"
:items="items"
:loading="loading"
loading-text="載入中..."
class="elevation-1 step2-table"
item-key="id"
>
<template v-slot:item.info="{ item }">
<div>
<div><span class="text-muted">法會:</span>{{ getActivityName(item.activity_num) }}</div>
<div><span class="text-muted">姓名:</span>{{ item.follower ? item.follower.u_name : '' }}</div>
<div><span class="text-muted">電話:</span>{{ item.follower ? (item.follower.phone || item.follower.cellphone) : '' }}</div>
</div>
</template>
<template v-slot:item.note="{ item }">
<div>
{{ item.note }}
<div v-if="item.proof_img">
<a :href="'../../upload/transfer_proof/' + item.proof_img" target="_blank">查看相片</a>
</div>
</div>
</template>
<template v-slot:item.acc_num="{ item }">
<div>
<div class="mb-2">
<span class="badge bg-primary me-1" title="支付方式">{{ payTypeText[item.pay_type] || item.pay_type }}</span>
<span class="badge bg-secondary" title="型態:個人/共同">{{ item.pay_mode }}</span>
<span class="fw-bold text-primary" title="帳號後5碼">{{ item.account_last5 }}</span>
</div>
</div>
<div>
<v-select
:items="bankOptions"
v-model="item.acc_num"
dense
outlined
hide-details
style="max-width: 200px"
></v-select>
</div>
</template>
<template v-slot:item.check_date="{ item }">
<div class="mb-2">
<span class="text-muted small">登記日期:</span>
<span
class="fw-bold text-danger"
style="cursor:pointer"
@click="$set(item, 'check_date', item.create_time ? item.create_time.split('T')[0] : '')"
title="點擊帶入日期"
>
{{ item.create_time | date }}
</span>
</div>
<div class="mb-2">
<v-text-field
v-model="item.check_date"
type="date"
dense
outlined
hide-details
style="max-width: 140px"
></v-text-field>
</div>
</template>
<template v-slot:item.check_amount="{ item }">
<div class="mb-2">
<span
class="text-muted small"
>金額:</span>
<span
class="fw-bold text-danger"
style="cursor:pointer"
@click="$set(item, 'check_amount', item.amount)"
title="點擊帶入金額"
>
{{ item.amount | currency }}
</span>
</div>
<div>
<v-text-field
v-model="item.check_amount"
type="number"
dense
outlined
hide-details
style="max-width: 100px"
></v-text-field>
</div>
</template>
<template v-slot:item.check_memo="{ item }">
<div class="d-flex align-center my-2" style="min-width: 300px">
<v-text-field
v-model="item.check_memo"
dense
outlined
hide-details
class="mr-2"
style="width: 180px"
placeholder="帳簿備註"
></v-text-field>
<v-select
:items="checkStatusOptions"
v-model="item.check_status"
item-text="text"
item-value="value"
dense
outlined
hide-details
style="width: 110px"
:menu-props="{ contentClass: 'mini-dropdown', maxHeight: 200 }"
></v-select>
</div>
<div class="my-2">
<v-text-field
v-model="item.verify_note"
dense
outlined
hide-details
style="max-width: 310px"
placeholder="核對記錄"
></v-text-field>
</div>
</template>
</v-data-table>
</v-card-text>
</v-card>
</v-container>
</v-app>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
<script>
new Vue({
el: '#verify-app',
vuetify: new Vuetify(),
data() {
return {
headers: [
{ text: '匯款人資訊', value: 'info' },
{ text: '匯款備註/相片', value: 'note' },
{ text: '*入帳銀行/帳戶 | 支付資訊/帳號後5碼', value: 'acc_num' },
{ text: '*入帳日期', value: 'check_date' },
{ text: '*入帳金額', value: 'check_amount' },
{ text: '備註/狀態 | 核對記錄', value: 'check_memo' }
],
items: [],
activities: [],
loading: false,
checkStatusOptions: [
{ text: '', value: '' },
{ text: '未核對', value: '1' },
{ text: '核對', value: '2' },
{ text: '金額不符', value: '3' },
{ text: '其他問題', value: '4' },
{ text: '作廢', value: '5' }
],
bankOptions: [],
payTypeText: {
1: '現金',
2: '匯款',
3: '支票'
}
};
},
filters: {
currency(val) {
if (!val) return '';
return Number(val).toLocaleString();
},
date(val) {
if (!val) return '';
return val.split('T')[0];
}
},
methods: {
getActivityName(num) {
const act = this.activities.find(a => a.num === num);
return act ? act.subject : '';
},
async loadData() {
this.loading = true;
// 取得活動清單
const actRes = await axios.get('../../api/activity');
this.activities = actRes.data;
// 取得階段2的待處理資料已通過階段1的資料
const res = await axios.get('../../api/transfer_register/step2_list');
this.items = res.data.map(item => ({
...item,
check_status: item.check_status ? String(item.check_status) : ''
}));
// 取得銀行帳戶清單
const bankRes = await axios.post('../../api/accounting/GetAccountKindList', {}, { params: { page: 1, pageSize: 1000 } });
this.bankOptions = bankRes.data.list.map(x => ({
text: x.kind + (x.bank_name ? ' - ' + x.bank_name : '') + (x.bank_id ? ' (' + x.bank_id + ')' : ''),
value: x.num
}));
this.loading = false;
},
async submitData() {
// 檢查必填欄位 - 入帳銀行/帳戶
const missingAccNum = this.items.filter(item => !item.acc_num);
if (missingAccNum.length > 0) {
alert('請選擇入帳銀行/帳戶!有 ' + missingAccNum.length + ' 筆資料未選擇。');
return;
}
// 檢查必填欄位 - 入帳日期
const missingCheckDate = this.items.filter(item => !item.check_date);
if (missingCheckDate.length > 0) {
alert('請填寫入帳日期!有 ' + missingCheckDate.length + ' 筆資料未填寫。');
return;
}
// 檢查必填欄位 - 入帳金額
const missingCheckAmount = this.items.filter(item => !item.check_amount || item.check_amount <= 0);
if (missingCheckAmount.length > 0) {
alert('請填寫入帳金額!有 ' + missingCheckAmount.length + ' 筆資料未填寫或金額無效。');
return;
}
// 組出要更新的資料
const updateList = this.items.map(item => ({
id: item.id,
f_num: item.f_num,
status: item.status ? String(item.status) : '',
check_status: item.check_status ? String(item.check_status) : '',
verify_note: item.verify_note,
acc_num: item.acc_num,
check_date: item.check_date,
check_amount: item.check_amount,
check_memo: item.check_memo
}));
try {
const res = await axios.post('../../api/transfer_register/batch_update', updateList);
if (res.data && res.data.success) {
alert('送出成功!');
// 重新載入資料
await this.loadData();
} else {
alert('送出失敗,請重試 :' + res.data.message);
}
} catch (e) {
console.error('送出失敗:', e);
alert('送出失敗,請再試一次!');
}
}
},
created() {
this.loadData();
}
});
</script>
<style>
.mini-dropdown {
min-width: 110px !important;
font-size: 0.95rem !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
.mini-dropdown .v-list-item {
min-height: 32px !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
/* 統一所有 dense 輸入元件高度 */
.v-input.v-input--dense {
min-height: 32px !important;
height: 32px !important;
font-size: 0.95rem !important;
}
.v-input.v-input--dense .v-input__slot,
.v-input.v-input--dense .v-select__slot,
.v-input.v-input--dense .v-select__selections,
.v-input.v-input--dense .v-text-field__slot {
min-height: 32px !important;
height: 32px !important;
line-height: 32px !important;
font-size: 0.95rem !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
/* 強制覆蓋所有 Vuetify 權重,讓下拉箭頭垂直置中 */
.v-input.v-input--dense .v-input__append-inner,
.v-text-field.v-input--dense .v-input__append-inner,
.v-input__append-inner[style] {
margin-top: 0 !important;
margin-bottom: 0 !important;
align-items: center !important;
display: flex !important;
height: 32px !important;
}
.v-input.v-input--dense .v-icon {
line-height: 32px !important;
font-size: 20px !important;
}
/* 讓 v-text-field 內的 input 也置中 */
.v-input.v-input--dense input {
height: 32px !important;
line-height: 32px !important;
font-size: 0.95rem !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
/* ===== 新增step2第一欄寬度加大 ===== */
.v-data-table td:first-child, .v-data-table th:first-child {
min-width: 220px !important;
width: 220px !important;
max-width: 300px !important;
white-space: normal !important;
}
/* ===== 新增:隱藏 number 欄位上下箭頭 ===== */
.v-input input[type=number]::-webkit-inner-spin-button,
.v-input input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.v-input input[type=number] {
-moz-appearance: textfield;
}
.step2-table tbody td{
height:90px !important;
min-height:90px !important;
}
/* 針對所有 v-select 內容垂直置中 */
.v-select__selection {
align-items: center !important;
display: flex !important;
height: 32px !important; /* 跟 input 高度一致 */
line-height: 32px !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
margin-top: 0 !important;
}
</style>
</asp:Content>