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

599 lines
29 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. 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="index.aspx.cs" Inherits="admin_follower_index" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="mb-2 mb-sm-0">
<a href="reg.aspx" class="btn btn-primary">
<i class="mdi mdi-plus"></i>新增
</a>
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
</div>
<div class="">
<a @click="print_dialog.show=true" class="btn btn-outline-primary btn-print" target="_blank">
<i class="mdi mdi-printer"></i>列印管理報表
</a>
<a @click="goPrint" class="btn btn-outline-primary btn-print" target="_blank">
<i class="mdi mdi-printer"></i>列印查詢資料
</a>
<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">
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
let VueApp=new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
options: { multiSort: false },
search_options: { multiSort: false },
data_table: {
loading: true,
list: [],
selected: [],
singleSelect: false,
count: 0,
page: 1,
pageSize: 10,
header: [
{ text: '信眾編號', value: 'f_number', align: 'start' },
{ text: '信眾姓名', value: 'u_name'},
{ text: '身分別', value: 'identity_type_desc' },
{ text: '性別', value: 'sex' },
{ text: '生日', value: 'birthday' },
{ text: '生肖/干支', value: 'sign', sortable: false },
{ text: '報名記錄', value: 'order_record' },
{ text: '', value: 'slot', sortable: false },
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
],
footer:{
showFirstLastPage: true,
pageSizeOptions:[5,10,20,30],
},
},
search: {
f_number: '',
u_name: '',
sex: '',
//birthday: new Date().toISOString().split('T')[0],
//birthday2: new Date().toISOString().split('T')[0]
birthday:'',
birthday2: '',
address: '',
country: '',
country2: '',
/*注意這邊的參數不能跟下方print_search重複*/
},
//列印管理報表
print_conditions:'yy',
print_search: {
year: '',
month: '',
season: '',
},
select_items: {
month: [{
text: "請選擇",
val: 0
},],
season: [{
text: "請選擇",
val: 0
},],
},
print_dialog: {
show: false,
},
//國籍
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '國籍',
text_prop: 'name_zh',
value_prop: 'id',
keys: [
{ id: 'keyword', title: '關鍵字' },
],
api_url: HTTP_HOST + 'api/country/GetList',
columns: [
{ id: 'id', title: '代碼' },
{ id: 'name_en', title: '英文短名稱' },
{ id: 'name_zh', title: '中文名稱' },
],
selected: {},
select(item, t) {
//console.log("select search1", t);
t.search.country = item.id;
t.search.country2 = '';
}
},
}, show: false,
current: {},
list: [],
count: 0,
page: 1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
},
},
}
},
watch: {
options: {
handler() {
this.getList()
},
deep: true,
},
search_options: {
handler() {
this.search_get()
},
deep: true,
},
}, mounted() {
this.search_dialog.current = this.search_dialog.controls.search1 ///default
this.initPrintSearch();
const navEntries = performance.getEntriesByType("navigation");
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
if (isReload) {
sessionStorage.removeItem("followerpage");
}
else {
const savedPage = parseInt(sessionStorage.getItem('followerpage'));
if (savedPage) {
this.options.page = savedPage;
}
}
},
methods: {
search_show(curr) {
//console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
this.search_clear()
//this.search_get()//清除完自動會重抓, 故取消
this.search_dialog.show = true;
},
search_clear() {
if (!this.search_dialog.current.keys) return;
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
this.search_get()
},
search_get() {
if (!this.search_dialog.current.keys) return;
let api_url = this.search_dialog.current.api_url;
let keys = this.search_dialog.current.keys;
//const { page, itemsPerPage } = this.options
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
this.search_dialog.page = this.search_options.page ?? 1
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
var search = {};//post body
keys.forEach((t, i) => {
search[t.id] = t.value;
});
//necessary parameter===
console.log("search_get", api_url, search, params, this.search_options);
this.search_dialog.loading = true
axios.post(api_url, search, { params: params })
.then(response => {
this.search_dialog.list = response.data.list
this.search_dialog.count = response.data.count
this.search_dialog.loading = false
})
.catch(error => {
console.log(error)
this.search_dialog.list = []
this.search_dialog.count = 0
this.search_dialog.loading = false
this.snackbar.text = "錯誤:" + error
this.snackbar.show = true
})
},
search_headers() {
if (!this.search_dialog.current.columns) return;
r = [];
this.search_dialog.current.columns.forEach((t, i) => {
r.push({
text: t.title,
align: 'start',
sortable: false,
value: t.id,
})
})
return r
},
search_select(row) {
let curr = this.search_dialog.current;
let target = $(`[data-search-control=${curr.id}]`);
curr.selected = row;
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
if (curr.select instanceof Function) {
curr.select(row, this);
}
this.search_dialog.show = false;
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
},
getList(clearpage = false) {
const { sortBy, sortDesc, page, itemsPerPage } = this.options
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: clearpage ? '1' : page, pageSize: itemsPerPage
};
sessionStorage.setItem('followerpage', page);
this.data_table.loading = true
axios
.post(HTTP_HOST + 'api/follower/GetList', this.search, { params: params })
.then(response => {
this.data_table.list = response.data.list
this.data_table.count = response.data.count;
this.data_table.loading = false
})
.catch(
error => console.log(error)
)
},
getDataFromApi() {
},
editItem(item) {
console.log("edit", item);
//this.editedIndex = this.desserts.indexOf(item)
//this.editedItem = Object.assign({}, item)
//this.dialog = true
},
deleteItem(item) {
//this.editedIndex = this.list.indexOf(item)
//this.editedItem = Object.assign({}, item)
//this.dialogDelete = true
if (confirm('是否確定刪除此筆資料?')) {
const index = this.data_table.list.indexOf(item)
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/follower/' + item.num)
.then(response => {
this.getList();
})
.catch(error => console.log(error))
}
}
},
deleteAll() {
if (confirm('是否確定刪除已勾選的資料?')) {
axios
.delete(HTTP_HOST + 'api/follower/Delete/' + this.data_table.selected.map(x => x.num))
.then(response => {
//console.log("delAll");
//for (var i = 0; i < this.data_table.selected.length; i++) {
// const index = this.data_table.list.indexOf(this.data_table.selected[i]);
// this.data_table.list.splice(index, 1);
//}
//this.data_table.selected = [];
//this.data_table.count = this.data_table.list.length
location.reload();
})
.catch(error => console.log(error))
}
},
btn_search() {
this.getList(true)
bootstrap.Offcanvas.getInstance(document.getElementById("offcanvasRight")).hide()
},
btn_all() {
clearObjProps(this.search);
this.btn_search()
},
goPrint() {
//debugger;
let _qry = "";
Object.keys(this.search).forEach(key => {
//console.log(`${key}: ${this.search[key]}`);
if (this.search[key] != undefined && this.search[key] != null && this.search[key] != '') {
_qry += (_qry != '' ? '&' : '?') + (key + '=' + this.search[key]);
}
});
window.open("print.aspx" + _qry, '_blank');
},
//列印管理報表
print_close() {
this.print_dialog.show = false;
}
,
initPrintSearch() {
//下拉選單
for (let i = 1; i <= 12; i++) {
var _tmp = {
text: i,
val:i,
}
this.select_items.month.push(_tmp);
}
for (let i = 1; i <= 4; i++) {
var _tmp = {
text: i,
val: i,
}
this.select_items.season.push(_tmp);
}
//預設值
const Today = new Date();//現在日期時間
const first_date = new Date(Today.getFullYear(), Today.getMonth(), 1); //本月第一天
const last_month_date = new Date(first_date - 1); //上個月最後一天
this.print_search.year = last_month_date.getFullYear();
this.print_search.month = last_month_date.getMonth() + 1 //預設上個月的年份
let _season = 1;
const _month = first_date.getMonth() + 1; //本月
if (_month >= 1 && _month <= 3) {
_season = 4;
} else if (_month >= 4 && _month <= 6) {
_season = 1;
} else if (_month >= 7 && _month <= 9) {
_season = 2;
} else if (_month >= 10 && _month <= 12) {
_season = 3;
}
this.print_search.season = _season; //預設上一季
//this.print_search.season = 0;
},
goPrint2() {
if (this.print_search.year != '') {
//let _qry = "";
//Object.keys(this.print_search).forEach(key => {
// if (this.print_search[key] != undefined && this.print_search[key] != null && this.print_search[key] != '') {
// _qry += (_qry != '' ? '&' : '?') + (key + '=' + this.print_search[key]);
// }
//});
let _qry = "?year=" + this.print_search.year;
if (this.print_conditions == 'mm') {
_qry += "&month=" + this.print_search.month;
} else if (this.print_conditions == 'ss') {
_qry += "&season=" + this.print_search.season;
}
this.print_dialog.show = false;
window.open("print.aspx" + _qry, '_blank');
}else{
msgbox('請輸入年份');
}
},
//
countryChange() {
this.search.country = '';
$('#country_txt').val('')
},
},
computed: {
pageCount() {
return Math.ceil(this.data_table.count / this.data_table.pageSize)
},
},
})
document.getElementById("<%= s_country.ClientID %>").addEventListener("click", function () {
$('#country2').val('');
VueApp.search.country2 = '';
});
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div id="content" class="container-fluid">
<v-data-table
v-model="data_table.selected"
:items="data_table.list"
:search-props="search"
item-key="num"
:options.sync="options"
:headers="data_table.header"
:footer-props="data_table.footer"
:server-items-length="data_table.count"
:loading="data_table.loading"
:single-select="data_table.singleSelect"
show-select
hide-default-footer
:page.sync="data_table.page"
:items-per-page.sync="data_table.pageSize"
class="elevation-1">
<template #item.birthday="{ item }" >
<div><span class="badge bg-secondary">西元</span> {{ item.birthday|timeString('YYYY/MM/DD') }} </div>
<div><span class="badge bg-secondary">農曆</span> {{ item.birthday2 }} </div>
</template>
<template #item.sign="{ item }" >
{{ item.sign }}/{{ item.sexagenary }}
</template>
<template #item.slot_btn="{ item }">
<a :href="'reg.aspx?num='+item.num" 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>
</template>
<template #item.order_record="{item}">
<a :href="'order_record.aspx?userid='+item.num" class="btn btn-outline-secondary btn-sm">報名記錄</a>
</template>
</v-data-table>
<v-container>
<v-row class="align-baseline" wrap>
<v-col cols="12" md="9">
<v-pagination
v-model="data_table.page"
:length="pageCount">
</v-pagination>
</v-col>
<v-col class="text-truncate text-right" cols="12" md="2">
共 {{ data_table.count }} 筆, 頁數:
</v-col>
<v-col cols="6" md="1">
<v-text-field
v-model="data_table.page"
type="number"
hide-details
dense
min="1"
:max="pageCount"
@input="data_table.page = parseInt($event, 10)"
></v-text-field>
</v-col>
</v-row>
</v-container>
</div>
<div id="print_data">
</div>
<v-dialog v-model="print_dialog.show" max-width="400px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
信眾加入日期管理報表​
<v-btn icon @click="print_close"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row densee class="pt-3" >
<v-col :cols="4" >
<span class="fs-6 text text-dark">查詢條件</span>
</v-col>
<v-col :cols="8" >
<select class="form-select" v-model="print_conditions" >
<option value="yy">年</option>
<option value="mm">月</option>
<option value="ss">季</option>
</select>
</v-col>
<v-col :cols="2" class="pt-5" >
<span class="fs-6 text text-dark">年 *</span>
</v-col>
<v-col :cols="10" >
<v-text-field v-model.number="print_search.year" min="1911" type="number" placeholder="年份必填" />
</v-col>
<v-col :cols="2" class="pt-5" v-if="print_conditions=='mm' ">
<span class="fs-6 text text-dark">月</span>
</v-col>
<v-col :cols="10" v-if="print_conditions=='mm' ">
<v-select
item-text="text"
item-value="val"
v-model="print_search.month"
:items="select_items.month"
></v-select>
</v-col>
<v-col :cols="2" class="pt-5" v-if="print_conditions=='ss' ">
<span class="fs-6 text text-dark">季</span>
</v-col>
<v-col :cols="10" v-if="print_conditions=='ss' ">
<v-select
item-text="text"
item-value="val"
v-model="print_search.season"
:items="select_items.season"
></v-select>
</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="green" dark @click="print_close" > 取消 </v-btn>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-dialog>
<v-dialog v-model="search_dialog.show" max-width="500px">
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
<v-col v-for="item in search_dialog.current.keys"
:cols="search_dialog.current.keys.length>1?6:12" >
<v-text-field v-model="item.value" :label="item.title" v-if="item.visible===undefined || item.visible==true "></v-text-field>
</v-col>
<v-col cols="12" class="text-end">
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
</v-col>
</v-row>
<v-data-table
:headers="search_headers()"
:items="search_dialog.list"
:footer-props="search_dialog.footer"
:items-per-page="10"
:server-items-length="search_dialog.count"
:page.sync="search_dialog.page"
:options.sync="search_options"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
<div id="search_panel" alt="查詢公告資料">
<div class="mb-3">
<label class="form-label">信眾編號 </label>
<input type="text" v-model="search.f_number" class="form-control" placeholder="可輸入關鍵字查詢" id="s_f_number" runat="server">
</div>
<div class="mb-3">
<label class="form-label">信眾姓名 </label>
<input type="text" v-model="search.u_name" class="form-control" placeholder="可輸入關鍵字查詢" id="s_u_name" runat="server">
</div>
<div class="mb-3">
<label class="form-label">地址 </label>
<input type="text" v-model="search.address" class="form-control" placeholder="可輸入關鍵字查詢" id="s_address" runat="server">
</div>
<div class="mb-3">
<label class="form-label">生日</label>
<div class="input-group">
<input type="date" v-model="search.birthday" class="form-control" id="s_birthday" runat="server">
<span class="input-group-text">~</span>
<input type="date" v-model="search.birthday2" class="form-control" id="s_birthday2" runat="server" >
</div>
</div>
<div class="mb-3">
<label class="form-label">國籍</label>
<div class="input-group mb-3 d-none" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
<input class="form-control search-text" type="text" readonly
placeholder="請選擇國籍" value="" id="country_txt">
<input type="hidden" v-model="search.country" >
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:DropDownList ID="s_country" runat="server" CssClass="form-select" v-model="search.country" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
<select class="form-select" v-model="search.country2" @change="countryChange" id="country2">
<option value="">請選擇</option>
<option value="0">全部</option>
<option value="1">台灣</option>
<option value="2">境外(非台灣)</option>
</select>
</div>
<div class="mb-3 p-2 border-top">
<a @click="btn_search" class="btn btn-outline-primary"><i class="mdi mdi-filter"></i> 搜尋</a>
<a class="btn btn-outline-secondary" @click="btn_all"><i class="mdi mdi-filter-remove"></i> 所有資料</a>
</div>
</div>
</asp:Content>