migrate to new git

This commit is contained in:
2025-08-29 01:27:25 +08:00
parent 946eb9961e
commit af2c152ef6
8623 changed files with 1000453 additions and 1 deletions

View File

@@ -0,0 +1,337 @@
<%@ 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 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>