將全年報名移至獨立頁籤,並新增未報名品項名單列印功能

This commit is contained in:
2026-05-11 09:11:22 +08:00
parent 9a7c30bd21
commit 46494547db
12 changed files with 1508 additions and 646 deletions
+160
View File
@@ -277,10 +277,25 @@
order_dialog: {
show: false,
},
unfilled_list: {
loading: false,
search: '',
headers: [
{ text: '訂單編號', value: 'order_no' },
{ text: '信眾編號', value: 'f_number' },
{ text: '信眾姓名', value: 'u_name' },
{ text: '聯絡電話', value: 'phone' },
{ text: '建立日期', value: 'order_date' },
],
items: [
{ order_no: "D", member_name: "S", order_date:"2025-12-07"}
],
},
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
this.loadUnfilledList();
//console.log("mounted");
},
watch: {
@@ -821,6 +836,113 @@
const _date = $('#<%= startDate_solar.ClientID%>').val();
return _subject + " " + _date;
},
loadUnfilledList() {
if (!this.this_id) return;
this.unfilled_list.loading = true;
axios.get(HTTP_HOST + 'api/activity/GetUnfilledOrdersByActivity/' + this.this_id)
.then(response => {
this.unfilled_list.items = response.data.list || [];
})
.catch(error => {
console.log(error);
this.snackbar.text = "名單載入失敗:" + error;
this.snackbar.show = true;
})
.finally(() => {
this.unfilled_list.loading = false;
});
},
async printUnfilledList() {
if (!this.this_id) return;
try {
const response = await axios.get(
HTTP_HOST + `api/activity/GetUnfilledOrdersByActivity/${this.this_id}`,
{ params: { page: 1, pageSize: 99999 } }
);
const allItems = response.data.list || [];
if (allItems.length === 0) {
this.snackbar.text = "目前沒有未填寫品項的資料可供列印!";
this.snackbar.show = true;
return;
}
const activityTitle = this.titleword();
const rows = allItems.map(item => `
<tr>
<td>${item.order_no}</td>
<td>${item.f_number || ''}</td>
<td>${item.u_name}</td>
<td>${item.phone}</td>
<td>${item.order_date}</td>
</tr>
`).join('');
const win = window.open('', '_blank');
win.document.write(`
<html>
<head>
<title>未填寫品項名單 - ${activityTitle}</title>
<style>
body { font-family: "Microsoft JhengHei", Arial, sans-serif; padding: 20px; color: #000; }
.header-container { text-align: center; margin-bottom: 30px; }
h2 { margin-bottom: 5px; font-size: 24px; }
h4 { margin-top: 0; color: #333; font-weight: normal; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #000; padding: 10px 8px; text-align: left; font-size: 14px; }
th { background-color: #eee; font-weight: bold; }
.text-center { text-align: center; }
@media print {
@page { margin: 1.5cm; }
button { display: none; }
}
</style>
</head>
<body>
<div class="header-container">
<h2>尚未報名品項之信眾清單</h2>
<h4>活動名稱:${activityTitle}</h4>
</div>
<table>
<thead>
<tr>
<th width="18%">訂單編號</th>
<th width="15%">信眾編號</th>
<th width="20%">信眾姓名</th>
<th width="20%">聯絡電話</th>
<th width="27%">建單日期</th>
</tr>
</thead>
<tbody>${rows}</tbody>
</table>
<div style="margin-top: 20px; text-align: right; font-size: 12px;">
列印時間:${new Date().toLocaleString()}
</div>
</body>
</html>
`);
win.document.close();
// 確保內容載入完成後再呼叫列印
setTimeout(() => {
win.print();
win.close();
}, 300);
} catch (error) {
console.error("列印出錯:", error);
this.snackbar.text = "讀取列印資料失敗:" + error;
this.snackbar.show = true;
}
}
},
computed: {
},
@@ -860,6 +982,10 @@
<button v-if="this_id!=''" class="nav-link" id="sec2-tab3" data-bs-toggle="tab" data-bs-target="#sec2-page3"
type="button" role="tab" aria-controls="profile" aria-selected="false">
備品項目</button>
<button v-if="this_id!=''" class="nav-link" id="sec2-tab4" data-bs-toggle="tab" data-bs-target="#sec2-page4"
type="button" role="tab" aria-controls="profile" aria-selected="false" @click="loadUnfilledList">
未填寫名單
</button>
</div>
</nav>
</div>
@@ -1189,6 +1315,40 @@
</div>
<div class="tab-pane fade" id="sec2-page4" role="tabpanel" aria-labelledby="sec2-tab4" v-if="this_id!=''">
<v-card class="mx-auto" outlined id="print-unfilled-area">
<v-data-table
:headers="unfilled_list.headers"
:items="unfilled_list.items"
:loading="unfilled_list.loading"
:search="unfilled_list.search"
class="elevation-1"
fixed-header
height="350px">
<template v-slot:top>
<v-toolbar flat color="white" class="d-print-none">
<div class="d-flex w-100">
<v-text-field
v-model="unfilled_list.search"
append-icon="mdi-magnify"
label="搜尋姓名或訂單號"
dense outlined single-line hide-details>
</v-text-field>
<v-btn color="primary" class="ml-2 white--text" @click="printUnfilledList">
<v-icon left>mdi-printer</v-icon>列印所有名單
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.status="{ item }">
<v-chip small color="error">未選品項</v-chip>
</template>
</v-data-table>
</v-card>
</div>
</div>
</asp:Panel>
</div>
+83 -57
View File
@@ -320,63 +320,10 @@ public partial class admin_activity_reg : MyWeb.config
int _id = activity.num;
if (_id > 0)
{
RunAutoEnroll(_id);
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Insert, subject.Text);
// 自動報名的信眾報名
var qry = _db.followers.Where(f => f.is_auto_enroll == true).AsQueryable();
var followers = qry.ToList();
if (followers != null)
{
try
{
foreach (var follower in followers)
{
Model.pro_order pro_order = new Model.pro_order(); //新增
pro_order.order_no = createOrderNumber();
pro_order.up_time = DateTime.Now;
pro_order.reg_time = DateTime.Now;
pro_order.keyin1 = "A01";
pro_order.f_num = follower.num;
if (!isStrNull(follower.phone)) { pro_order.phone = follower.phone; }
if (!isStrNull(follower.cellphone)) { pro_order.phone = follower.cellphone; }
if (IsNumeric(activity.num)) { pro_order.activity_num = activity.num; }
pro_order.address = isStrNull(follower.auto_enroll_receipt_address) ? "" : follower.auto_enroll_receipt_address;
pro_order.receipt_title = isStrNull(follower.auto_enroll_receipt_title) ? "" : follower.auto_enroll_receipt_title;
pro_order.send_receipt = isStrNull(follower.auto_enroll_is_receipt) ? false : follower.auto_enroll_is_receipt;
pro_order.demo = "";
pro_order.customize_data = "";
try
{
if (!isStrNull(pro_order.order_no))
{
bool isRegistered = _db.pro_order.Any(x => x.f_num == pro_order.f_num && x.activity_num == pro_order.activity_num);
if (isRegistered) // 重複報名
{
continue;
}
else
{
_db.pro_order.Add(pro_order);
_db.SaveChanges();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Order, (int)Model.admin_log.Status.Insert, pro_order.order_no);
}
}
}
catch (Exception ex)
{
}
}
}
catch (Exception ex)
{
}
}
Response.Redirect("index.aspx");
}
else
@@ -451,6 +398,8 @@ public partial class admin_activity_reg : MyWeb.config
activity.category_kind = Val(category_kind.Value);
_db.SaveChanges();
RunAutoEnroll(activity.num);
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Update, subject.Text);
}
@@ -470,8 +419,85 @@ public partial class admin_activity_reg : MyWeb.config
}
}
private void RunAutoEnroll(int activityNum)
{
var activity = _db.activities.FirstOrDefault(a => a.num == activityNum);
if (activity == null || !activity.startDate_solar.HasValue) return;
DateTime actDate = activity.startDate_solar.Value;
var validConfigs = _db.auto_enroll
.Where(ae => actDate >= ae.start_date && actDate <= ae.end_date)
.ToList();
foreach (var config in validConfigs)
{
if (_db.pro_order.Any(o => o.activity_num == activity.num && o.f_num == config.f_num))
continue;
var follower = _db.followers.FirstOrDefault(f => f.num == config.f_num);
if (follower == null) continue;
string newOrderNo = AutoOrderService.CreateAutoOrderNumber(_db);
Model.pro_order proOrder = new Model.pro_order
{
order_no = newOrderNo,
up_time = DateTime.Now,
reg_time = DateTime.Now,
keyin1 = "A01",
f_num = follower.num,
au_num = config.num,
phone = !string.IsNullOrEmpty(follower.cellphone) ? follower.cellphone : (follower.phone ?? ""),
activity_num = activity.num,
address = config.receipt_address ?? "",
receipt_title = config.receipt_title ?? "",
demo = "",
customize_data = ""
};
_db.pro_order.Add(proOrder);
CopyLatestOrderDetails(newOrderNo, config.f_num, (int)activity.kind);
}
_db.SaveChanges();
}
private void CopyLatestOrderDetails(string newOrderNo, int f_num, int activityKind)
{
var latestOrder = _db.pro_order
.Where(o => o.f_num == f_num && o.activity.kind == activityKind && _db.pro_order_detail.Any(d => d.order_no == o.order_no))
.OrderByDescending(o => o.order_no)
.FirstOrDefault();
if (latestOrder != null)
{
var prevDetails = _db.pro_order_detail.Where(d => d.order_no == latestOrder.order_no).ToList();
foreach (var detail in prevDetails)
{
Model.pro_order_detail newDetail = new Model.pro_order_detail
{
order_no = newOrderNo,
actItem_num = detail.actItem_num,
parent_num = detail.parent_num,
print_id = detail.print_id,
f_num = detail.f_num,
f_num_tablet = detail.f_num_tablet,
address = detail.address,
from_id = detail.from_id,
from_id_tablet = detail.from_id_tablet,
qty = detail.qty,
price = detail.price,
start_date = DateTime.Today,
pay = 0,
UpdateTime = DateTime.Now
};
_db.pro_order_detail.Add(newDetail);
}
}
}
#endregion
}