Files
17168ERP/web/admin/transfer/verify1.aspx
2025-08-29 01:27:25 +08:00

341 lines
12 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="verify1.aspx.cs" Inherits="admin_transfer_verify1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<h5 class="mb-0">出納 - 核對匯款人階段1</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-success white--text text-center">
<h5 class="mb-0">出納核對匯款人階段1</h5>
<v-spacer></v-spacer>
<v-btn color="primary" @click="saveData">確認送出</v-btn>
</v-card-title>
<v-card-text>
<v-data-table
:headers="headers"
:items="items"
:loading="loading"
loading-text="載入中..."
class="elevation-1"
item-key="id"
>
<template v-slot:item.info="{ item }">
<div>
<div><span class="text-muted">姓名:</span>{{ item.name }}</div>
<div><span class="text-muted">電話:</span>{{ item.phone }}</div>
<div><span class="text-muted">法會:</span>{{ getActivityName(item.activity_num) }}</div>
</div>
</template>
<template v-slot:item.f_num="{ item }">
<span v-if="item.f_num && item.follower">
<a
:href="'/admin/follower/reg.aspx?num=' + item.follower.num"
class="text-success"
target="_blank"
>
{{ item.follower.u_name }}F{{ item.f_num }}
</a>
<div class="small text-muted">
電話:{{ item.follower.phone }}<br>
手機:{{ item.follower.cellphone }}
</div>
</span>
<span v-else class="text-danger">未自動比對</span>
</template>
<template v-slot:item.actions="{ item }">
<v-btn small outlined color="primary" @click="openFollowerDialog(item)">選擇信眾</v-btn>
</template>
<template v-slot:item.status="{ item }">
<div class="d-flex align-center">
<v-select
:items="statusOptions"
v-model="item.status"
item-text="text"
item-value="value"
dense
outlined
hide-details
class="mr-2"
style="width: 110px;max-width: 110px;"
:menu-props="{ contentClass: 'mini-dropdown', maxHeight: 200 }"
></v-select>
<v-text-field
v-model="item.verify_note"
dense
outlined
hide-details
style="width: 200px"
placeholder="核對記錄"
></v-text-field>
</div>
</template>
</v-data-table>
</v-card-text>
</v-card>
</v-container>
<!-- 信眾選擇對話框 -->
<v-dialog v-model="follower_dialog.show" max-width="800px">
<v-card>
<v-card-title class="grey lighten-2">
選擇信眾
<v-spacer></v-spacer>
<v-btn icon @click="follower_dialog.show = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="12">
<v-text-field
v-model="follower_dialog.search"
label="搜尋信眾"
prepend-icon="mdi-magnify"
@keyup.enter="searchFollowers"
clearable
></v-text-field>
</v-col>
</v-row>
<v-data-table
:headers="follower_dialog.headers"
:items="follower_dialog.items"
:loading="follower_dialog.loading"
:search="follower_dialog.search"
item-key="num"
class="elevation-1"
@click:row="selectFollower"
>
<template v-slot:item.actions="{ item }">
<v-btn small color="primary" @click="selectFollower(item)">
選擇
</v-btn>
</template>
</v-data-table>
</v-card-text>
</v-card>
</v-dialog>
</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: 'f_num' },
{ text: '選擇信眾', value: 'actions', sortable: false },
{ text: '狀態 | 核對記錄', value: 'status' },
],
items: [],
activities: [],
loading: false,
statusOptions: [
{ text: '', value: '' },
{ text: '待確認', value: '1' },
{ text: '確認', value: '2' },
{ text: '作廢', value: '3' }
],
follower_dialog: {
show: false,
loading: false,
search: '',
headers: [
{ text: '編號', value: 'num' },
{ text: '姓名', value: 'u_name' },
{ text: '地址', value: 'address' }
],
items: [],
selected: null,
current_item: null
}
};
},
methods: {
getActivityName(num) {
const act = this.activities.find(a => a.num === num);
return act ? act.subject : '';
},
openFollowerDialog(item) {
this.follower_dialog.current_item = item;
this.follower_dialog.show = true;
this.searchFollowers();
},
async searchFollowers() {
this.follower_dialog.loading = true;
try {
const response = await axios.post(HTTP_HOST + 'api/follower/GetList', {
f_number: this.follower_dialog.search,
u_name: this.follower_dialog.search
}, {
params: {
page: 1,
pageSize: 10
}
});
this.follower_dialog.items = response.data.list;
} catch (error) {
console.error('Error fetching followers:', error);
this.snackbar.text = "查詢信眾失敗";
this.snackbar.show = true;
} finally {
this.follower_dialog.loading = false;
}
},
async selectFollower(follower) {
if (this.follower_dialog.current_item) {
try {
// 先關閉對話框,避免重複點擊
this.follower_dialog.show = false;
// 直接使用點選的信眾資料,因為已經包含了解密後的電話和手機
// 從 follower_dialog.items 中找到對應的信眾資料
const selectedFollower = this.follower_dialog.items.find(item => item.num === follower.num);
if (selectedFollower) {
// 更新當前項目的 f_num
this.follower_dialog.current_item.f_num = follower.num;
// 更新 follower 物件,包含解碼後的電話和手機資訊
this.follower_dialog.current_item.follower = {
num: selectedFollower.num,
u_name: selectedFollower.u_name,
address: selectedFollower.address || '',
phone: selectedFollower.phoneDes || '', // 使用解密後的電話
cellphone: selectedFollower.cellphoneDes || '' // 使用解密後的手機
};
} else {
throw new Error('找不到信眾詳細資料');
}
} catch (error) {
console.error('取得信眾詳細資料失敗:', error);
alert('取得信眾詳細資料失敗,請重試');
// 如果發生錯誤,至少更新基本資訊
this.follower_dialog.current_item.f_num = follower.num;
this.follower_dialog.current_item.follower = {
num: follower.num,
u_name: follower.u_name,
address: follower.address || '',
phone: '',
cellphone: ''
};
}
}
},
async loadData() {
this.loading = true;
// 取得活動清單
const actRes = await axios.get('../../api/activity');
this.activities = actRes.data;
// 取得階段1的待處理資料
const res = await axios.get('../../api/transfer_register/pending');
this.items = res.data.map(item => ({
...item,
status: item.status ? String(item.status) : ''
}));
this.loading = false;
},
async saveData() {
// 組出要更新的資料
const updateList = this.items.map(item => ({
id: item.id,
f_num: item.f_num,
status: item.status ? String(item.status) : '',
verify_note: item.verify_note
}));
try {
const res = await axios.post('../../api/transfer_register/batch_update', updateList);
// 檢查回傳格式
if (res.data && res.data.success) {
alert('儲存成功!');
// 重新載入資料
await this.loadData();
} else {
alert('儲存失敗,請重試!!');
}
} catch (e) {
alert('儲存失敗,請重試:' + e.message);
}
}
},
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;
}
/* 針對所有 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>