1. 優化報名頁面:彈出查詢頁面、顯示剛新增資料

2. 新增報名頁面加上取消鍵
3. 優化登入頁面:按下 enter 自動換格/送出
4. 修復新增報名頁面中,不同 search_dialog 中的 page 參數相互連動之異常
5. 修改報名頁面列印格式
6. 修復報名頁面匯出功能
7. 優化報到功能
8. 報名頁面中,無查詢資料時不可點選匯出/列印按鈕
9. 匯出/列印報名管理報表時,若無資料則顯示提示
10. 修復列印管理報表後父視窗 UI 不能點擊的問題
11. 新增報名管理表單匯出 excel 功能
12. 於新增信眾、新增活動頁面加上取消鍵
13. 優化報名管理匯出功能:若篩選條件包含特定活動,自動於「匯出條件」欄位標註活動名稱
14. 優化報名查詢匯出功能:匯出之文件中加上「匯出條件」欄位
15. 修復信眾資料頁面中,使用「生日」作為篩選基準時,後續執行「列印查詢資料」與「匯出查詢資料」會報錯
16. 修復「列印信眾查詢」功能中,電話搜尋欄位未正確帶入查詢條件之異常
17. 解決中文輸入法輸入電話號碼的跳字問題
18. 新增品項管理介面排序功能
This commit is contained in:
2026-04-21 09:03:57 +08:00
parent aa5941a324
commit 7644df57d0
24 changed files with 1505 additions and 542 deletions
+228 -67
View File
@@ -14,17 +14,18 @@
<a @click="print_dialog.show=true" class="btn btn-outline-primary btn-print" target="_blank">
<i class="mdi mdi-printer"></i>列印管理報表
</a>
<div class="dropdown d-inline-block">
<a class="btn btn-outline-primary btn-print dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><i class="mdi mdi-printer"></i>列印報名資料</a>
<ul class="dropdown-menu ps-0 w-100" aria-labelledby="dropdownPrintLink">
<li><a @click="search.hasPrice='Y';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>有金額</a></li>
<li><a @click="search.hasPrice='N';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>無金額</a></li>
</ul>
<div :style="data_table.list.length === 0 ? 'pointer-events: none; opacity: 0.5;' : ''" style="display:inline-block;">
<div class="dropdown d-inline-block">
<a class="btn btn-outline-primary btn-print dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><i class="mdi mdi-printer"></i>列印查詢資料</a>
<ul class="dropdown-menu ps-0 w-100" aria-labelledby="dropdownPrintLink">
<li><a @click="search.hasPrice='Y';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>有金額</a></li>
<li><a @click="search.hasPrice='N';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>無金額</a></li>
</ul>
</div>
</div>
<div :style="data_table.list.length === 0 ? 'pointer-events: none; opacity: 0.5;' : ''" style="display:inline-block;">
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出查詢資料(Excel</asp:LinkButton>
</div>
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
</div>
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
@@ -39,7 +40,8 @@
vuetify: new Vuetify(vuetify_options),
data() {
return {
isFirstLoad: true,
print_error_msg: "",
isSearched: false,
this_act : '<%= Request["act_id"]%>',
options: { multiSort: false },
search_options: { multiSort: false },
@@ -57,6 +59,7 @@
{ text: '報名日期', value: 'up_time' },
{ text: '報名活動', value: 'subject', align: 'start' },
{ text: '單據狀態', value: 'keyin1_txt' },
{ text: '報到狀態', value: 'status' },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
],
footer:{
@@ -204,6 +207,10 @@
}
},
mounted() {
const printResult = document.getElementById('<%= hid_err_msg.ClientID %>').value;
document.getElementById('<%= hid_err_msg.ClientID %>').value = '';
window._printResult = printResult
this.detalKeyinArray();
this.search_dialog.current = this.search_dialog.controls.search1 ///default
if (this.this_act != '')
@@ -212,29 +219,63 @@
this.initActivity();
const navEntries = performance.getEntriesByType("navigation");
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
const isBackForward = navEntries.length > 0 && navEntries[0].type === "back_forward";
if (isReload) {
sessionStorage.removeItem("orderpage");
sessionStorage.removeItem("order_list_cache");
sessionStorage.removeItem("order_query_params");
}
else if (isBackForward) {
this.isFirstLoad = false;
else if ("<%=lastAddedNo%>" !== "") {
const newQuery = { order_no: '<%=lastAddedNo%>' };
sessionStorage.setItem('order_query_params', JSON.stringify(newQuery));
this.search = newQuery;
this.isSearched = true;
}
else {
const savedPage = parseInt(sessionStorage.getItem('orderpage'));
const savedData = sessionStorage.getItem("order_list_cache");
const savedQuery = JSON.parse(sessionStorage.getItem("order_query_params"));
if (savedQuery) {
this.search = savedQuery;
this.isSearched = true;
}
if (savedPage) {
this.options.page = savedPage;
}
}
if (savedData && savedData !== "undefined") {
this.data_table = JSON.parse(savedData);
this.isSearched = true;
}
}
if (printResult === 'nodata' || printResult === 'success') {
this.$nextTick(() => {
this.print_dialog.show = true;
if (printResult === 'nodata') {
this.print_error_msg = "查無資料,請重新選擇區間";
}
});
}
this.$nextTick(() => {
setTimeout(() => {
// 清空 URL
const cleanUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
window.history.replaceState({}, '', cleanUrl);
}, 100);
});
},
watch: {
options: {
handler() {
if (this.isFirstLoad) {
this.isFirstLoad = false;
this.data_table.loading = false;
return;
if (this.isSearched) {
this.getDefault()
}
else {
this.data_table.loading = false;
}
this.getDefault()
},
deep: true,
},
@@ -246,6 +287,57 @@
},
},
methods: {
triggerManagementExport(mode) {
this.print_error_msg = "";
if (this.print_search.year == '') {
msgbox('請輸入年份');
return;
}
if (!this.print_search.chk_noact && !this.print_search.chk_hasact) {
msgbox('活動/非活動至少勾選一項');
return;
}
// 將 Vue 狀態同步至 ASP.NET HiddenField,供後端 PostBack 讀取參數
document.getElementById('<%= hid_print_mode.ClientID %>').value = this.print_conditions;
document.getElementById('<%= hid_print_year.ClientID %>').value = this.print_search.year;
if (this.print_conditions == 'mm')
document.getElementById('<%= hid_print_month.ClientID %>').value = this.print_search.month;
else if (this.print_conditions == 'ss')
document.getElementById('<%= hid_print_season.ClientID %>').value = this.print_search.season;
document.getElementById('<%= hid_select_act.ClientID %>').value = this.print_search.select_act;
document.getElementById('<%= hid_select_actitem.ClientID %>').value = this.print_search.select_actitem;
document.getElementById('<%= hid_chk_hasact.ClientID %>').value = this.print_search.chk_hasact;
document.getElementById('<%= hid_chk_noact.ClientID %>').value = this.print_search.chk_noact;
let qry = "";
Object.keys(this.print_search).forEach(key => {
if (this.print_search[key] != undefined && this.print_search[key] != null && this.print_search[key] != '') {
if (key == 'month' ) {
if (this.print_conditions == 'mm') {
qry += "&month=" + this.print_search.month;
}
} else if ( key == 'season')
{
if (this.print_conditions == 'ss') {
qry += "&season=" + this.print_search.season;
}
}
else {
qry += (qry != '' ? '&' : '?') + (key + '=' + this.print_search[key]);
}
}
});
document.getElementById('<%= hid_qry.ClientID %>').value = qry;
if (mode === 'print') {
document.getElementById('<%= print_management.ClientID %>').click();
}
else if (mode === "excel") {
document.getElementById('<%= excel_management.ClientID %>').click();
}
},
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
@@ -331,19 +423,24 @@
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
const dataToStore = JSON.stringify(this.data_table);
sessionStorage.setItem("order_list_cache", dataToStore);
})
.catch(error => console.log(error))
},
detalKeyinArray() {
var getArray = <%=Newtonsoft.Json.JsonConvert.SerializeObject(_keyin1Item, Newtonsoft.Json.Formatting.Indented) %>;
var keys = Object.keys(getArray);
for (let i = 0; i < keys.length; i++) {
//console.log(`${keys[i]}:${getArray[keys[i]]}`); //value : text
var _tmp = {
text: getArray[keys[i]],
val: parseInt(keys[i]),
if (getArray !== null) {
var keys = Object.keys(getArray);
for (let i = 0; i < keys.length; i++) {
//console.log(`${keys[i]}:${getArray[keys[i]]}`); //value : text
var _tmp = {
text: getArray[keys[i]],
val: parseInt(keys[i]),
}
this.keyin1_items.push(_tmp);
}
this.keyin1_items.push(_tmp);
}
},
@@ -385,16 +482,21 @@
}
},
btn_search() {
this.isSearched = true;
sessionStorage.setItem("order_query_params", JSON.stringify(this.search));
this.this_act = '';
this.search.activity_num = '';
this.getDefault(true)
bootstrap.Offcanvas.getInstance(document.getElementById("offcanvasRight")).hide()
},
btn_all() {
this.isSearched = false;
this.this_act = '';
this.search.activity_num = '';
clearObjProps(this.search);
this.btn_search()
sessionStorage.setItem("order_query_params", JSON.stringify(this.search));
//this.btn_search()
},
checkInMsg(item) {
this.check_data.f_num = item.f_num;
@@ -403,39 +505,59 @@
this.check_data.activity_name = item.subject;
this.check_dialog.show = true;
},
checkIn() {
if (this.check_data.qty > 0 && this.check_data.status.val > 0) {
var chechdata =
{
f_num: this.check_data.f_num,
activity_num: this.check_data.activity_num,
status: this.check_data.status.val,
qty: this.check_data.qty,
}
axios
.post(HTTP_HOST + 'api/activity/OrderCheckIn', chechdata)
.then(response => {
//清空
this.check_data.f_num = 0;
this.check_data.u_name = '';
this.check_data.activity_num = 0;
this.check_data.activity_name = '';
this.check_data.qty = 1;
this.check_data.status.text = '';
this.check_data.status.val = 1;
this.check_dialog.show = false;
msgtop('簽到成功')
})
.catch(
error => {
console.log(error)
msgtop('簽到失敗', 'error')
}
)
} else {
msgbox('報到資訊請填寫完整');
checkIn(item) {
var checkdata =
{
f_num: item.f_num,
activity_num: item.activity_num,
status: 1,
qty: 1,
}
console.log(checkdata)
axios
.post(HTTP_HOST + 'api/activity/OrderCheckIn', checkdata)
.then(response => {
msgtop('簽到成功');
this.getDefault();
})
.catch(
error => {
console.log(error)
msgtop('簽到失敗', 'error')
}
)
//if (this.check_data.qty > 0 && this.check_data.status.val > 0) {
// var chechdata =
// {
// f_num: this.check_data.f_num,
// activity_num: this.check_data.activity_num,
// status: this.check_data.status.val,
// qty: this.check_data.qty,
// }
// axios
// .post(HTTP_HOST + 'api/activity/OrderCheckIn', chechdata)
// .then(response => {
// //清空
// this.check_data.f_num = 0;
// this.check_data.u_name = '';
// this.check_data.activity_num = 0;
// this.check_data.activity_name = '';
// this.check_data.qty = 1;
// this.check_data.status.text = '';
// this.check_data.status.val = 1;
// this.check_dialog.show = false;
// msgtop('簽到成功')
// })
// .catch(
// error => {
// console.log(error)
// msgtop('簽到失敗', 'error')
// }
// )
//} else {
// msgbox('報到資訊請填寫完整');
//}
}, goPrint() {
let _qry = "";
Object.keys(this.search).forEach(key => {
@@ -453,6 +575,7 @@
//列印管理報表
print_close() {
this.print_dialog.show = false;
this.print_error_msg = "";
}
,
initPrintSearch() {
@@ -515,9 +638,9 @@
}
}
});
console.log(_qry);
this.print_dialog.show = false;
window.open("print.aspx" + _qry, '_blank');
//window.open("print.aspx" + _qry, '_blank');
} else {
msgbox('活動/非活動至少勾選一項');
}
@@ -567,10 +690,35 @@
$('#country2').val('');
VueApp.search.country2 = '';
});
$(document).ready(function () {
// 判斷是否彈出 search dialog
let hasSearchResult = sessionStorage.getItem("order_list_cache") !== null;
if (!hasSearchResult && window._printResult === '') {
let $btn = $("a[data-bs-target='#offcanvasRight'][href='#search_panel']");
$btn.click();
let el = document.getElementById('offcanvasRight');
let offcanvas = bootstrap.Offcanvas.getOrCreateInstance(el);
offcanvas.show();
}
});
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<asp:HiddenField ID="hid_err_msg" runat="server" />
<asp:HiddenField ID="hid_print_year" runat="server" />
<asp:HiddenField ID="hid_print_month" runat="server" />
<asp:HiddenField ID="hid_print_season" runat="server" />
<asp:HiddenField ID="hid_print_mode" runat="server" />
<asp:HiddenField ID="hid_chk_hasact" runat="server" />
<asp:HiddenField ID="hid_chk_noact" runat="server" />
<asp:HiddenField ID="hid_select_act" runat="server" />
<asp:HiddenField ID="hid_select_actitem" runat="server" />
<asp:HiddenField ID="hid_qry" runat="server" />
<asp:LinkButton ID="print_management" runat="server" OnClick="export_Click" style="display:none;" />
<asp:LinkButton ID="excel_management" runat="server" OnClick="export_Click" style="display:none;" />
<div id="content" class="container-fluid">
<v-data-table
v-model="data_table.selected"
@@ -591,10 +739,13 @@
<template #item.up_time="{ item }" >
{{ item.up_time|timeString('YYYY/MM/DD') }}
</template>
<template #item.u_name="{ item }" >
<a v-if="item.f_num != null && item.activity_num != null" @click="checkInMsg(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-account-check"></i>報到</a>
<template #item.u_name="{ item }" >
{{ item.u_name }}
</template>
<template #item.status="{ item }" >
<a v-if="item.f_num != null && item.activity_num != null && item.status == 0" @click="checkIn(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-account"></i>報到</a>
<a v-if="item.f_num != null && item.activity_num != null && item.status == 1" class="btn btn-outline-secondary btn-sm opacity-50" style="pointer-events: none" ><i class="mdi mdi-account-check"></i>已報到</a>
</template>
<template #item.slot_btn="{ item }">
<a :href="'reg.aspx?order_no='+item.order_no" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
@@ -703,7 +854,8 @@
item-text="text"
item-value="val"
v-model="print_search.month"
:items="select_items.month"
:items="select_items.month"
eager
></v-select>
</v-col>
<v-col :cols="2" class="pt-5" v-if="print_conditions=='ss' ">
@@ -714,7 +866,8 @@
item-text="text"
item-value="val"
v-model="print_search.season"
:items="select_items.season"
:items="select_items.season"
eager
></v-select>
</v-col>
@@ -775,9 +928,17 @@
</v-row>
</v-col>--%>
</v-row>
<v-row>
<v-col>
<div v-if="print_error_msg" class="red--text mt-2 text-center" style="font-weight: bold;">
{{ print_error_msg }}
</div>
</v-col>
</v-row>
<v-row densee class="pt-3" >
<v-col :cols="12" class="pt-3 text-center" >
<v-btn class="ma-2" color="primary" dark @click="goPrint2" > 列印 </v-btn>
<v-btn class="ma-2" color="primary" dark @click="triggerManagementExport('print')" > 列印 </v-btn>
<v-btn class="ma-2" color="primary" dark @click="triggerManagementExport('excel')"> 匯出 Excel </v-btn>
<v-btn class="ma-2" color="green" dark @click="print_close" > 取消 </v-btn>
</v-col>
</v-row>