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,341 @@
<%@ 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>