Files
17168ERP/web/admin/follower/reg.aspx
2025-09-11 00:47:51 +08:00

2158 lines
117 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" CodeFile="reg.aspx.cs" Inherits="admin_follower_reg" ValidateRequest="false" %>
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="footer_script" runat="Server">
<script>
function validatePhoneOrCellphone(sender, args) {
var phone = document.getElementById('<%= phone.ClientID %>').value.trim();
var cellphone = document.getElementById('<%= cellphone.ClientID %>').value.trim();
args.IsValid = (phone !== '' || cellphone !== '');
}
function formatCellphone(input) {
const selectionStart = input.selectionStart;
const selectionEnd = input.selectionEnd;
const rawValue = input.value.replace(/\D/g, '').substring(0, 10);
let formatted = '';
if (rawValue.length > 0) {
formatted += rawValue.substring(0, 4);
}
if (rawValue.length >= 5) {
formatted += '-' + rawValue.substring(4, 7);
}
if (rawValue.length >= 8) {
formatted += '-' + rawValue.substring(7);
}
if (input.value !== formatted) {
input.value = formatted;
const newPos = selectionStart + (formatted.length - rawValue.length);
input.setSelectionRange(newPos, newPos);
}
}
function formatPhone(input) {
const selectionStart = input.selectionStart;
const selectionEnd = input.selectionEnd;
const rawValue = input.value.replace(/\D/g, '').substring(0, 10);
let formatted = '';
if (rawValue.length > 0) {
formatted += rawValue.substring(0, 2);
}
if (rawValue.length >= 3) {
formatted += '-' + rawValue.substring(2, 6);
}
if (rawValue.length >= 6) {
formatted += '-' + rawValue.substring(6);
}
if (input.value !== formatted) {
input.value = formatted;
const newPos = selectionStart + (formatted.length - rawValue.length);
input.setSelectionRange(newPos, newPos);
}
}
function chagenDate(btn) {
var _date = $(btn).val();
if (_date != "") {
$.ajax({
method: "POST",
url: "reg.aspx",
data: {
type: 'getTxt',
date: _date
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText
//alert('Error - ' + errorMessage);
console.log('Error - ' + errorMessage);
}
}).done(function (data) {
if (data.isOk) {
$('#L1').text(data.cDate)
$('#L2').text(data.sign)
} else {
console.log(data.msg);
}
});
}
console.log(_date);
}
function checkNumber(btn) {
$('#errormsg').hide();
var _txt = $(btn).val();
$.ajax({
method: "POST",
url: "reg.aspx",
data: {
type: 'chkNo',
txt: _txt,
id: '<%= Request["num"]%>'
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText
//alert('Error - ' + errorMessage);
console.log('Error - ' + errorMessage);
}
}).done(function (data) {
if (data.isOk) {
} else {
console.log(data.msg);
$('#errormsg').text(data.msg);
$('#errormsg').show();
}
});
}
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
// 模組化工作: 結合: UC, MIXIN...
let tabtmp = <%=Newtonsoft.Json.JsonConvert.SerializeObject(_tmp, Newtonsoft.Json.Formatting.Indented) %>;
let VueApp = new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
tabArray: tabtmp,
tabArray2: "",
follower_id: '<%= Request["num"] %>',
options: {},
optionsDetail: {
multiSort: false,
//itemsPerPage: -1,
},
search_dialog: {
controls: {
search1: {
id: 'search1',
title: '介紹人',
text_prop: 'u_name',
value_prop: 'num',
keys: [
{ id: 'f_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'address', title: '地址' },
],
api_url: HTTP_HOST + 'api/follower/GetList',
columns: [
{ id: 'f_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'address', title: '地址' },
],
selected: {},
select(item, index, t) {
console.log("select search1", t);
}
},
search2: {
id: 'search2',
title: '姓名',
text_prop: 'u_name',
value_prop: 'num',
keys: [
{ id: 'f_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'address', title: '地址' },
],
api_url: HTTP_HOST + 'api/follower/GetList',
columns: [
{ id: 'f_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'address', title: '地址' },
],
selected: {},
select(item, index, t) {
console.log("select search2", t);
//item.f_num_selected_tmp.text = item.f_num_selected.text //暫存用
//item.val = item.f_num_selected.val //暫存用
//edit item
item.f_num_selected.text = t.u_name //=====?
item.f_num_selected.val = t.num //=====?
item.birthday = t.birthday
item.identity_type_desc = t.identity_type_desc
item.phoneDes = t.phoneDes
item.demo = t.demo
//list
index.birthday = t.birthday
index.identity_type_desc = t.identity_type_desc
index.phoneDes = t.phoneDes
index.demo = t.demo
}
},
search3: {
id: 'search3',
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, index, t) {
console.log("select search3", t);
}
},
search4: {
id: 'search4',
title: '稱謂',
text_prop: 'title',
value_prop: 'num',
keys: [
],
api_url: HTTP_HOST + 'api/appellation/GetList',
columns: [
{ id: 'title', title: '稱謂' },
],
selected: {},
select(item, index, t) {
console.log("select search4", t);
//edit item
item.appellation_id_selected.text = t.title //=====?
item.appellation_id_selected.val = t.num //=====?
}
}, search5: {
id: 'search5',
title: '姓名',
text_prop: 'u_name',
value_prop: 'num',
keys: [
{ id: 'f_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'address', title: '地址' },
{ id: 'onlyfamily', title: '只查親屬'},
],
api_url: HTTP_HOST + 'api/follower/GetList',
columns: [
{ id: 'f_number', title: '編號' },
{ id: 'u_name', title: '姓名' },
{ id: 'address', title: '地址' },
],
selected: {},
select(item, index, t) {
console.log("select search5", t);
}
},
},
show: false,
current: {},
list: [],
count: 0,
page: 1,
loading: false,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
},
},
snackbar: {
show: false,
text: "",
},
//家人資訊//親友名單
disableButton: true,
searchDetail: '',
headersDetail: [
{ text: '* 姓名', value: 'f_num_selected.text', sortable: false },
{ text: '* 稱謂', value: 'appellation_id_selected.text', sortable: false },
{ text: '身分別', value: 'identity_type_desc', sortable: false },
{ text: '生日', value: 'birthday', sortable: false },
{ text: '聯絡電話', value: 'phoneDes', sortable: false },
{ text: '備註', value: 'demo', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "100px" },
],
footersDetail: {
showFirstLastPage: false,
disableItemsPerPage: false,
itemsPerPageAllText: '',
itemsPerPageText: '',
'prev-icon': null,
'next-icon': null,
'disable-pagination': true,
'items-per-page-options': []
},
//rules: {
// required: value => !!value || 'Required.',
//},
dessertsLoading: true,
desserts: [],
desserts_count: 0,
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
//data_tmp: {
// f_num_selected: {
// text: '',
// val: 0
// },
// identity_type_desc: '',
// birthday: '',
// phoneDes: '',
// demo: '',
//},
f_num_selected: {
text: '',
val: 0
},
address: '',
identity_type_desc: '',
birthday: '',
phoneDes: '',
demo: '',
appellation_id_selected :
{
text : '',
val : 0,
},
},
defaultItem: {
id: 0,
num: 0,
//data_tmp: {
// f_num_selected: {
// text: '',
// val: 0
// },
// identity_type_desc: '',
// birthday: '',
// phoneDes: '',
// demo: '',
//},
f_num_selected: {
text: '',
val: 0
},
address: '',
identity_type_desc: '',
birthday: '',
phoneDes: '',
demo: '',
appellation_id_selected:
{
text: '',
val: 0,
},
},
//未付款紀錄
recordsDetail: { multiSort: false },
topDetail: [
{ text: '訂單編號', value: 'orderno', sortable: false },
{ text: '訂單日期', value: 'up_time', sortable: false },
{ text: '姓名/名稱', value: 'u_name', sortable: false },
{ text: '訂單金額', value: 'totalprice', sortable: false, align: 'end', },
{ text: '已收金額', value: 'payprice', sortable: false, align: 'end', },
{ text: '未收金額', value: 'notpay', sortable: false, align: 'end', },
],
lists: [],
order_total_price: 0,
order_payprice_price: 0,
order_notpay_price: 0,
//牌位標題
selectedTabletType: "超渡",
listTabletType: [
{ label: '超渡', value: '超渡' },
{ label: '陽上', value: '陽上' },
{ label: '(無)', value: '' },
],
tabletsDetail: { multiSort: false },
tabletTable: {
Loading:true,
disableButton: true,
searchDetail: '',
headersDetail: [
{ text: '超渡/陽上', value: 'type', sortable: false, width: "100px" },
{ text: '* 牌位標題', value: 'title', sortable: true },
{ text: '', value: 'actions', sortable: false, width: "100px" },
],
desserts: [],
desserts_count: 0,
editedIndex: -1,
editedItem: {
id: 0,
num: 0,
f_num: 0,
title: '',
},
defaultItem: {
id: 0,
num: 0,
f_num: 0,
type: this.selectedTabletType,
title:'',
},
},
//新:家人
family:{
dialog: false,
isEditing: false,
is_tw: true,
loading: false,
////members from api follower_members
members: [],
members_count: 0,
editedIndex: -1,
edItem: {
num: 0,
follower_num: 0, // 當前 follower 的 ID
fam_name: "",
fam_gender: "",
fam_title: "",
deceased: false,
birthdate: null,
lunar_birthday: "",
age: "",
chinese_year: "",
zodiac: "",
birth_time: "",
city:"",
area:"",
address: "",
phone: "",
mobile: "",
},
tempItem: {}, // 用於存儲編輯前的原始數據
defaultItem: {
num: 0,
follower_num: 0, // 當前 follower 的 ID
fam_name: "",
fam_gender: "",
fam_title: "",
deceased: false,
birthdate: null,
lunar_birthday: "",
age: "",
chinese_year: "",
zodiac: "",
birth_time: "",
city:"",
area:"",
address: "",
phone: "",
mobile: "",
},
headersDetail: [
{ text: '* 姓名', value: 'fam_name', sortable: false },
{ text: '性別', value: 'fam_gender', sortable: false },
{ text: '關係(稱謂)', value: 'fam_title', sortable: false },
{ text: '歿', value: 'deceased', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "100px" },
],
},
cityOptions: [], // 城市選項
areaOptions: {}, // 區域選項
//天干地支:甲子, 乙丑...
chineseYears: [
'甲子', '乙丑', '丙寅', '丁卯', '戊辰', '己巳', '庚午', '辛未', '壬申', '癸酉',
'甲戌', '乙亥', '丙子', '丁丑', '戊寅', '己卯', '庚辰', '辛巳', '壬午', '癸未',
'甲申', '乙酉', '丙戌', '丁亥', '戊子', '己丑', '庚寅', '辛卯', '壬辰', '癸巳',
'甲午', '乙未', '丙申', '丁酉', '戊戌', '己亥', '庚子', '辛丑', '壬寅', '癸卯',
'甲辰', '乙巳', '丙午', '丁未', '戊申', '己酉', '庚戌', '辛亥', '壬子', '癸丑',
'甲寅', '乙卯', '丙辰', '丁巳', '戊午', '己未', '庚申', '辛酉', '壬戌', '癸亥'
],
//生肖
zodiac: ['鼠', '牛', '虎', '兔', '龍', '蛇', '馬', '羊', '猴', '雞', '狗', '豬'],
//生辰
birth_time: [
{ text: '吉時', value: '吉時' },
{ text: '子時 (23:00~01:00)', value: '子時' },
{ text: '丑時 (01:00~03:00)', value: '丑時' },
{ text: '寅時 (03:00~05:00)', value: '寅時' },
{ text: '卯時 (05:00~07:00)', value: '卯時' },
{ text: '辰時 (07:00~09:00)', value: '辰時' },
{ text: '巳時 (09:00~11:00)', value: '巳時' },
{ text: '午時 (11:00~13:00)', value: '午時' },
{ text: '未時 (13:00~15:00)', value: '未時' },
{ text: '申時 (15:00~17:00)', value: '申時' },
{ text: '酉時 (17:00~19:00)', value: '酉時' },
{ text: '戌時 (19:00~21:00)', value: '戌時' },
{ text: '亥時 (21:00~23:00)', value: '亥時' }
]
}
},
mounted() {//一開始就載入
this.search_dialog.current = this.search_dialog.controls.search1 ///default
//console.log("mounted");
//this.initialize();
//取得家人列表
this.getFamilyMembers();
this.getCityOptions();
this.onCityChange();
},
watch: {
options: {
handler() {
//console.log("watch1", this.search_dialog, this.search_dialog.page);
this.search_get()
console.log("watch2", this.search_dialog, this.search_dialog.page);
},
deep: true,
},
optionsDetail: {
handler() {
this.initialize();
},
deep: true,
},
recordsDetail: {
handler() {
this.initCollection();
},
deep: true,
},
tabletsDetail: {
handler() {
this.initTablet();
},
deep: true,
},
//'family.edItem.birthdate': function(newVal, oldVal) {
// //this.calculateLunarBirthday();
// if (newVal !== oldVal) {
// //this.calculateLunarBirthday();
// }
//}
// 提示訊息
snackbar: {
show: false,
message: '',
color: 'error'
}
},
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) =>
{
if (t.id == 'onlyfamily') {
t.value = true;
} else
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.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===
// if (this.search_dialog.current.id == 'search1' && this.follower_id !='') {
if (this.follower_id != "") {
search['num'] = this.follower_id;
search['ept_self'] = true;
}
if (this.search_dialog.current.id == "search5" && search['onlyfamily']) {
api_url = HTTP_HOST + 'api/follower/GetFamilyList';
}
// }
console.log("search_get", api_url, search, params, this.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;
//牌位
if (curr.id == 'search5') {
const textarea = this.$refs.textarea.$refs.input
const sentence = textarea.value
const len = sentence.length
let pos = textarea.selectionStart
if (pos === undefined) {
pos = 0
}
const before = sentence.substr(0, pos)
const after = sentence.substr(pos, len)
const _value = before + curr.selected[curr.text_prop] + after
this.tabletTable.editedItem.title = _value;
this.$nextTick().then(() => {
textarea.selectionStart = pos + (curr.selected[curr.text_prop]).length
})
} else {
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(this.editedItem, this.desserts[this.editedIndex], row);
}
this.search_dialog.show = false;
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
},
//家人資訊
initialize() {
if (this.follower_id != '') {
this.dessertsLoading = true;
const { sortBy, sortDesc, page, itemsPerPage } = this.optionsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page, pageSize: itemsPerPage,
};
var searchItemDetail = {
num: this.follower_id,
ept_self: true,
}
//舊:家人
<%-- axios
.post(HTTP_HOST + 'api/follower/GetFamilyList', searchItemDetail, { params: params })
.then(response => {
this.desserts = response.data.list
this.desserts_count = response.data.count
this.disableButton = false;
this.dessertsLoading = false;
})
.catch(
error => console.log(error)
) --%>
}
},
editItem(item) {
this.disableButton = true;
this.editedIndex = this.desserts.indexOf(item);
this.editedItem = $.extend(true, {}, item);
},
deleteItem(item) {
//confirm('確定要刪除此筆資料嗎?') && this.desserts.splice(index, 1);
if (confirm('確定要刪除此筆資料嗎?')) {
const index = this.desserts.indexOf(item);
if (item.num > 0) {
if (index != -1) {
//clear leader
var pro_order_detail =
{
num: item.num,//原先載入時的家人num
leader: this.follower_id,
}
axios
.post(HTTP_HOST + 'api/follower/familyDelete', pro_order_detail)
.then(response => {
console.log("del", item);
this.desserts.splice(index, 1)
this.desserts_count = this.desserts_count - 1;
})
.catch(
error => console.log(error)
)
}
} else {
this.desserts.splice(index, 1)
}
}
},
cancel() {
this.disableButton = false;
//data-search-control need to return to the original value
//this.desserts[this.editedIndex].identity_type_desc = this.editedItem.data_tmp.identity_type_desc;
//this.desserts[this.editedIndex].birthday = this.editedItem.data_tmp.birthday;
//this.desserts[this.editedIndex].phoneDes = this.editedItem.data_tmp.phoneDes;
//this.desserts[this.editedIndex].demo = this.editedItem.data_tmp.demo;
this.spliceNullData();
this.close();
},
spliceNullData() {
//if new data ,then splice it
if (this.editedItem.num == 0) {
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
if (this.desserts[i].id == this.editedItem.id) {
this.desserts.splice(i, 1); break;
}
}
}
},
close() {
setTimeout(() => {
//this.editedItem = Object.assign({}, this.defaultItem);
this.editedItem = $.extend(true, {}, this.defaultItem);
this.editedIndex = -1;
}, 300)
},
addNew() {
this.disableButton = true;
this.spliceNullData();
var keysArr = [];
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
//const addObj = Object.assign({}, this.defaultItem);
const addObj = $.extend(true, {}, this.defaultItem);
//addObj.id = this.desserts.length + 1;
addObj.id = (isFinite(_c) ? _c : 0) + 1;
this.desserts.unshift(addObj);
this.editItem(addObj);
},
save() {
this.disableButton = false;
if (this.editedIndex > -1) {
if (this.follower_id != '') {
//chcck necessary params
if (this.editedItem.f_num_selected.val != 0 && this.editedItem.appellation_id_selected.val != 0) {
// update data
var pro_order_detail =
{
num: this.editedItem.num,//原先載入時的家人num
f_num: this.editedItem.f_num_selected.val, //儲存時的家人num
leader: this.follower_id,
appellation_id: this.editedItem.appellation_id_selected.val, //儲存時的稱謂
}
axios
.post(HTTP_HOST + 'api/follower/familySave', pro_order_detail)
.then(response => {
this.editedItem.num = response.data;
this.desserts[this.editedIndex].identity_type_desc = this.editedItem.identity_type_desc;
this.desserts[this.editedIndex].birthday = this.editedItem.birthday;
this.desserts[this.editedIndex].phoneDes = this.editedItem.phoneDes;
this.desserts[this.editedIndex].demo = this.editedItem.demo;
Object.assign(this.desserts[this.editedIndex], this.editedItem)
this.close()
})
.catch(
error => console.log(error)
)
} else {
this.snackbar.text = "必填項目未填寫完整";
this.snackbar.show = true
}
} else {
this.snackbar.text = "信眾資料錯誤";
this.snackbar.show = true
}
}
},
//自訂標籤 v-chip
addTab() {
if (this.tabArray2 != "") {
this.tabArray.push(this.tabArray2);
$('#<%= tab.ClientID %>').val(this.tabArray)
} else {
this.snackbar.text = "請輸入自訂標籤";
this.snackbar.show = true
alert("請輸入自訂標籤");
}
},
remove() {
$('#<%= tab.ClientID %>').val(this.tabArray);
},
//未付款資訊
initCollection() {
if (this.follower_id != '') {
const { sortBy, sortDesc, page, itemsPerPage } = this.recordsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page, pageSize: itemsPerPage,
order_no: '',
};
var searchItemDetail = {
num: this.follower_id,
}
axios
.post(HTTP_HOST + 'api/order/GetUnpayList', searchItemDetail, { params: params })
.then(response => {
this.lists = response.data.list;
for (var i = 0; i < this.lists.map(x => x.id).length; i++) {
this.order_total_price += parseInt(this.lists[i].totalPrice);
this.order_payprice_price += parseInt(this.lists[i].payPrice);
this.order_notpay_price += parseInt(this.lists[i].totalPrice) - parseInt(this.lists[i].payPrice);
}
})
.catch(
error => console.log(error)
)
}
}, addNewFollowerData() {
if (this.follower_id !='')
window.location = 'reg.aspx?leader=' + this.follower_id;
},
titleword() {
const _f_number = $('#<%= f_number.ClientID%>').val();
const _u_name= $('#<%= u_name.ClientID%>').val()
const _sex = $('#<%= sex.ClientID%>').val();
return _f_number + " " + _u_name + "" + _sex + "";
}, thisName() {
return "將前往新增一筆信眾資料,並成為" + $('#<%= u_name.ClientID%>').val() +"的家人";
},
//牌位標題
initTablet() {
if (this.follower_id != '') {
this.tabletTable.Loading = true;
const { sortBy, sortDesc, page, itemsPerPage } = this.tabletsDetail
const params = {
sortBy: sortBy[0], sortDesc: sortDesc[0],
page: page, pageSize: itemsPerPage,
};
var searchItemDetail = {
num: this.follower_id,
}
axios
.post(HTTP_HOST + 'api/follower/GetTabletList', searchItemDetail, { params: params })
.then(response => {
this.tabletTable.desserts = response.data.list
this.tabletTable.desserts_count = response.data.count
this.tabletTable.disableButton = false;
this.tabletTable.Loading = false;
})
.catch(
error => console.log(error)
)
}
},
spliceNullTabletData() {
//if new data ,then splice it
if (this.tabletTable.editedItem.num == 0) {
for (var i = 0; i < this.tabletTable.desserts.map(x => x.id).length; i++) {
if (this.tabletTable.desserts[i].id == this.tabletTable.editedItem.id) {
this.tabletTable.desserts.splice(i, 1); break;
}
}
}
},
cancelTablet() {
this.tabletTable.disableButton = false;
this.spliceNullTabletData();
this.closeTablet();
},
closeTablet() {
setTimeout(() => {
//this.editedItem = Object.assign({}, this.defaultItem);
this.tabletTable.editedItem = $.extend(true, {}, this.tabletTable.defaultItem);
this.tabletTable.editedIndex = -1;
}, 300)
},
addNewTablet() {
this.tabletTable.disableButton = true;
this.spliceNullTabletData();
var keysArr = [];
for (var i = 0; i < this.tabletTable.desserts.map(x => x.id).length; i++) {
//console.log(this.desserts[i].id)
keysArr.push(parseInt(this.tabletTable.desserts[i].id));
}
var _c = Math.max.apply(null, keysArr);
//const addObj = Object.assign({}, this.defaultItem);
const addObj = $.extend(true, {}, this.tabletTable.defaultItem);
//addObj.id = this.desserts.length + 1;
addObj.id = (isFinite(_c) ? _c : 0) + 1;
addObj.type = this.selectedTabletType;
//debugger;
this.tabletTable.desserts.unshift(addObj);
this.editTabletItem(addObj);
},
editTabletItem(item) {
this.tabletTable.disableButton = true;
this.tabletTable.editedIndex = this.tabletTable.desserts.indexOf(item);
this.tabletTable.editedItem = $.extend(true, {}, item);
}, saveTablet() {
this.tabletTable.disableButton = false;
if (this.tabletTable.editedIndex > -1) {
if (this.follower_id != '') {
//chcck necessary params
if (this.tabletTable.editedItem.title !='') {
// update data
var pro_order_detail =
{
num: this.tabletTable.editedItem.num,
f_num: this.follower_id,
type: this.tabletTable.editedItem.type,
title: this.tabletTable.editedItem.title,
}
axios
.post(HTTP_HOST + 'api/follower/tabletSave', pro_order_detail)
.then(response => {
this.tabletTable.editedItem.num = response.data;
Object.assign(this.tabletTable.desserts[this.tabletTable.editedIndex], this.tabletTable.editedItem)
this.closeTablet()
})
.catch(
error => console.log(error)
)
} else {
this.snackbar.text = "必填項目未填寫完整";
this.snackbar.show = true
}
} else {
this.snackbar.text = "信眾資料錯誤";
this.snackbar.show = true
}
}
}, deleteTabletItem(item) {
if (confirm('確定要刪除此筆資料嗎?')) {
const index = this.tabletTable.desserts.indexOf(item);
if (item.num > 0) {
if (index != -1) {
axios
.delete(HTTP_HOST + 'api/follower/tabletDelete/' + item.num)
.then(response => {
console.log("del", item);
this.tabletTable.desserts.splice(index, 1)
this.tabletTable.desserts_count = this.tabletTable.desserts_count - 1;
})
.catch(
error => console.log(error)
)
}
} else {
this.tabletTable.desserts.splice(index, 1)
}
}
}, execInsertText() {
//const insertText = this.insertText
if (!insertText.length) return
const textarea = this.$refs.textarea.$refs.input
const sentence = textarea.value
const len = sentence.length
let pos = textarea.selectionStart
if (pos === undefined) {
pos = 0
}
const before = sentence.substr(0, pos)
const after = sentence.substr(pos, len)
this.value = before + insertText + after
this.$nextTick().then(() => {
textarea.selectionStart = pos + insertText.length
})
},
getFamilyMembers() {
console.log("getFamilyMembers", this.follower_id);
if (this.follower_id) {
this.family.loading = true;
// 假設您有一個 API 端點來獲取特定 follower 的 family members
//api_url: HTTP_HOST + 'api/follower/GetList',
axios.get(HTTP_HOST + `api/familymembers/follower/${this.follower_id}`)
.then(response => {
this.family.members = response.data.map(member => ({
...member,
birthdate: member.birthdate ? member.birthdate.split('T')[0] : null
}));
this.family.members_count = response.data.length;
console.log("family.members", this.family.members);
})
.catch(error => {
console.error("Error fetching family members:", error);
// 可能的錯誤處理,例如顯示錯誤消息
})
.finally(() => {
this.family.loading = false;
});
}
},
toggleCityAreaVisibility() {
if (!this.family.is_tw) {
this.family.edItem.city = '';
this.family.edItem.area = '';
}
},
//新:家人
fam_add(){
this.family.isEditing = false;
this.family.edItem = { ...this.family.defaultItem }; // 使用默認值
this.family.tempItem = {}; // 清空臨時存儲
this.family.dialog = true;
this.family.is_tw = true; // 新增時預設為境內
},
fam_close(item){
if (this.family.isEditing) {
Object.assign(this.family.edItem, this.family.tempItem);
} else {
this.family.edItem = { ...this.family.defaultItem };
}
this.family.dialog = false;
//this.editedItem = $.extend(true, {}, this.defaultItem);
},
fam_save(item) {
console.log("fam_save 1:", this.family.edItem);
// 驗證必填欄位 - 只有姓名必填
if (!this.family.edItem.fam_name || this.family.edItem.fam_name.trim() === '') {
this.snackbar.message = '請填寫姓名';
this.snackbar.color = 'error';
this.snackbar.show = true;
return;
}
if (!this.family.is_tw) {
this.family.edItem.city = '';
this.family.edItem.area = '';
}
const fam_item = JSON.parse(JSON.stringify(this.family.edItem)); // 深拷貝
fam_item.follower_num = this.follower_id;
const savePromise = this.family.isEditing
? axios.put(HTTP_HOST + `api/familymembers/${fam_item.num}`, fam_item)
: axios.post(HTTP_HOST + 'api/familymembers', fam_item);
savePromise
.then(response => {
console.log("fam_save 2: Server response", response);
//const updatedMember = fam_item;
const updatedMember = { ...fam_item, num: response.data.num };
if (this.family.isEditing) {
const index = this.family.members.findIndex(m => m.num === updatedMember.num);
if (index !== -1) {
this.$set(this.family.members, index, updatedMember);
}
} else {
this.family.members.push(updatedMember);
}
this.family.dialog = false;
this.family.edItem = JSON.parse(JSON.stringify(this.family.defaultItem));
this.$forceUpdate();
console.log("fam_save 3: Updated family members", JSON.parse(JSON.stringify(this.family.members)));
})
.catch(error => {
console.error("Error saving family member:", error);
// 處理錯誤,例如顯示錯誤消息
});
},
async fam_edit(item) {
this.family.dialog = false;
this.family.isEditing = true;
// 確保城市選項已加載
if (this.cityOptions.length === 0) {
await this.getCityOptions();
}
// 如果有城市,確保該城市的地區選項已加載
if (item.city) {
await this.getAreaOptions(item.city);
}
// 在所有數據加載完成後,設置 edItem
this.family.edItem = JSON.parse(JSON.stringify(item));
this.family.tempItem = JSON.parse(JSON.stringify(item));
this.family.is_tw = !!(item.city || item.area); // 根據 city 或 area 是否有值來設置 is_tw
console.log("family.edItem",this.family.edItem, this.family.tempItem);
this.$nextTick(() => {
this.family.dialog = true;
// 確保在對話框打開後更新城市和地區選項
if (item.city) {
this.onCityChange(item.city);
}
});
},
fam_del(item){
if (confirm('確定要刪除此筆資料嗎?')) {
axios.delete(HTTP_HOST + `api/familymembers/${item.num}`)
.then(response => {
// 如果 API 調用成功,從本地數組中移除該項
const index = this.family.members.indexOf(item);
if (index !== -1) {
this.family.members.splice(index, 1);
}
// 可能的成功消息
this.$toast.success('資料已成功刪除');
})
.catch(error => {
console.error("Error deleting family member:", error);
// 錯誤處理
this.$toast.error('刪除資料時發生錯誤');
});
}
},
calculateLunarBirthday(item) {
console.log("calculateLunarBirthday:",item, this.family.edItem);
const birthdate = this.family.edItem.birthdate;
if (birthdate) {
// 發送AJAX請求到伺服器
$.ajax({
method: "POST",
url: "reg.aspx",
data: {
type: 'getTxt',
date: birthdate
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText
console.log('Error - ' + errorMessage);
}
}).done((data) => {
var cYear = '';
if (data.isOk) {
// 更新農曆生日
this.family.edItem.lunarBirthday = data.cDate;
// 更新生肖
this.family.edItem.zodiac = data.sign;
cYear = function(birthdate){
var year = new Date(birthdate).getFullYear();
var index = (year - 1924) % 60;
var y = VueApp.chineseYears[index];
return y;
}(birthdate);
// 更新歲次(天干地支)
// birthdate get year, get index of chineseYears while 1984, 1924 :index is 0
this.family.edItem.age = cYear;
this.family.edItem = {
...this.family.edItem,
lunarBirthday: data.cDate,
zodiac: data.sign,
age: cYear
};
this.$forceUpdate();
console.log("fam editem",this.family.editItem);
} else {
console.error('獲取農曆信息失敗:', data.msg);
}
console.log(data, cYear);
});
} else {
// 如果沒有選擇日期,清空相關欄位
//this.family.edItem.lunarBirthday = '';
//this.family.edItem.zodiac = '';
//this.family.edItem.age = '';
}
},
async getCityOptions() {
try {
const response = await axios.get(HTTP_HOST + 'api/location/cities');
console.log("getCityOptions",response.data);
this.cityOptions = response.data;
} catch (error) {
console.error("Error fetching cities:", error);
}
},
async getAreaOptions(city) {
try {
const response = await axios.get(HTTP_HOST + `api/location/areas/${encodeURIComponent(city)}`);
console.log("getAreaOptions",city,response.data);
//this.areaOptions = response.data;
// 使用 Vue.set 來確保響應性
this.$set(this.areaOptions, city, response.data);
} catch (error) {
console.error("Error fetching areas:", error);
}
},
async onCityChange() {
// 保存原來的地區值
const originalArea = this.family.edItem.area;
// 暫時重置區域選擇
this.family.edItem.area = '';
if (this.family.edItem.city) {
try {
await this.getAreaOptions(this.family.edItem.city);
// 檢查原來的地區是否在新的選項中
if (this.areaOptions[this.family.edItem.city].includes(originalArea)) {
// 如果在,恢復原來的選擇
this.family.edItem.area = originalArea;
}
} catch (error) {
console.error("Error fetching area options:", error);
// 可以在這裡添加錯誤處理,比如顯示錯誤消息給用戶
}
} else {
// 如果沒有選擇城市,清空地區選項
this.areaOptions = {};
}
},
},
computed: {
filteredTabletItems() {
// Filter items based on selected city
return this.tabletTable.desserts.filter(item => {
if (this.selectedTabletType === "") {
return item.type === this.selectedTabletType || item.type === "";
} else {
return item.type === this.selectedTabletType;
}
});
},
filteredFamilyMembers() {
if (!this.family.members || !this.family.searchQuery) {
return this.family.members || [];
}
const searchTerm = this.family.searchQuery.toLowerCase();
return this.family.members.filter(member => {
// 檢查 member 和 fam_name 是否存在
if (!member || !member.fam_name) {
return false;
}
return member.fam_name.toLowerCase().includes(searchTerm);
});
},
},
filters: {
currency: function (value) {
return value == null || value === "" ? "" :
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
},
}
})
</script>
<script>
$(document).ready(function () {
return;//取消
console.log("ready", $('.noedit'));
// 檢查 URL 是否包含 num 參數
var urlParams = new URLSearchParams(window.location.search);
var hasNum = urlParams.has('num');
if (hasNum) {
// 頁面加載時,為 .tab-pane 添加 pe-none 類
$('.noedit').addClass('pe-none');
// 監聽複選框的點擊事件
$('#editCheckbox').on('change', function() {
if ($(this).is(':checked')) {
// 如果複選框被選中,移除 pe-none 類
$('.noedit').removeClass('pe-none');
} else {
// 如果複選框未被選中,添加 pe-none 類
$('.noedit').addClass('pe-none');
}
});
$('#myTabContent').on('click', function(e) {
if ($(".noedit").hasClass("pe-none")) {
e.preventDefault();
alert('請先勾選"編輯模式"以啟用編輯。');
}
});
}else{
// 如果 URL 不包含 num 參數
$('#editCheckboxContainer').hide(); // 隱藏編輯複選框
$('.tab-pane,.edit_Click').removeClass('pe-none'); // 移除 pe-none 類,允許編輯
}
});
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
<template v-if="follower_id !='' "> {{titleword()}} </template>
</div>
<div class="d-flex align-items-center">
<div class="form-check me-3 d-none" id="editCheckboxContainer">
<input class="form-check-input" type="checkbox" id="editCheckbox">
<label class="form-check-label" for="editCheckbox">
編輯模式
</label>
</div>
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary edit_Click noedit" />
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary edit_Click noedit" />
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
</div>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:alert runat="server" ID="L_msg" Text="" />
<div class="ms-2">
<asp:CustomValidator ID="PhoneOrCellphoneValidator" runat="server"
ErrorMessage="聯絡電話與手機號碼請至少填寫一項"
ClientValidationFunction="validatePhoneOrCellphone"
Display="Dynamic" SetFocusOnError="true" />
</div>
<div id="content" class="container-fluid">
<div class="card shadow-sm my-2" id="sec2">
<div class="card-header py-0">
<nav class="navbar py-0">
<div class="nav nav-tabs">
<button class="nav-link active" id="sec2-tab1" data-bs-toggle="tab" data-bs-target="#sec2-page1"
type="button" role="tab" aria-controls="home" aria-selected="true">
基本資料</button>
<button class="nav-link" id="sec2-tab2" data-bs-toggle="tab" data-bs-target="#sec2-page2b"
type="button" role="tab" aria-controls="profile" aria-selected="false">
親友名單 </button>
<button 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" v-if="lists.length > 0">
未付款紀錄 </button>
<button 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">
牌位標題 </button>
</div>
</nav>
</div>
<asp:Panel ID="cardBodyPanel" runat="server" CssClass="card-body">
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active noedit" id="sec2-page1" role="tabpanel" aria-labelledby="sec2-tab1">
<div>
<div class="form-text text-muted">以下 * 欄位為必填欄位</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">信眾編號<asp:Literal ID="f_numberReqStar" runat="server" Text=" *"></asp:Literal></label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="f_number" MaxLength="20" runat="server" CssClass="form-control" ReadOnly="true" onchange="checkNumber(this)" placeholder="請輸入信眾編號"></asp:TextBox>
<span id="errormsg" class="text-danger" style="display: none;"></span>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">信眾姓名 *</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="u_name" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入信眾姓名"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" ControlToValidate="u_name" runat="server"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">性別 *</label>
<div class="col-sm-10 col-lg-3">
<asp:DropDownList ID="sex" CssClass="form-select" runat="server">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
<asp:ListItem Value="男眾" Text="男眾"></asp:ListItem>
<asp:ListItem Value="女眾" Text="女眾"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="sex" runat="server"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">身分別 *</label>
<div class="col-sm-10 col-lg-3">
<asp:DropDownList ID="identity_type" CssClass="form-select" runat="server" data-int="Y">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" ControlToValidate="identity_type" runat="server"
ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">聯絡電話<asp:Literal ID="phoneReqStar" runat="server" Text=" *"></asp:Literal></label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="phone" MaxLength="15" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="聯絡電話與手機號碼請至少填寫一項"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="phone" ErrorMessage="格式有誤" ID="RegularExpressionValidator11" runat="server" ValidationExpression="^[+-]?\d+([+-]?\d*)*$" Display="Dynamic" SetFocusOnError="true" />
</div>
<label class="col-sm-2 col-lg-1 col-form-label">手機號碼<asp:Literal ID="cellphoneReqStar" runat="server" Text=" *"></asp:Literal></label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="cellphone" MaxLength="12" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="聯絡電話與手機號碼請至少填寫一項" oninput="formatCellphone(this)"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="cellphone" Display="Dynamic" ErrorMessage="格式有誤" ID="RegularExpressionValidator2" runat="server" SetFocusOnError="true" ValidationExpression="^09\d{2}-?\d{3}-?\d{3}$" />
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">身分證字號</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="id_code" MaxLength="25" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="請輸入身分證字號,如: A123456789"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">旅行證件編號</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="passport" MaxLength="25" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="請輸入旅行證件編號"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">電子信箱</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="email" MaxLength="200" runat="server" CssClass="form-control" placeholder="請輸入E-mail如: taichung@gmail.com"></asp:TextBox>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="email" Display="Dynamic" SetFocusOnError="true"
ErrorMessage="格式有誤!" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">生日</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="birthday" runat="server" CssClass="form-control " TextMode="Date" onchange="chagenDate(this)"
autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">農曆生日</label>
<div class="col-sm-10 col-lg-3 pt-2">
<span id="L1">
<asp:Literal ID="Literal1" runat="server"></asp:Literal></span>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">生肖</label>
<div class="col-sm-10 col-lg-3 pt-2">
<span id="L2">
<asp:Literal ID="Literal2" runat="server"></asp:Literal></span>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">皈依日期</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="refugedate" runat="server" CssClass="form-control " TextMode="Date" autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">皈依法名</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="refuge_name" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入皈依法名"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">皈依道場</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="refuge_area" MaxLength="25" runat="server" CssClass="form-control" placeholder="請輸入皈依道場"></asp:TextBox>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">加入日期</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="join_date" runat="server" CssClass="form-control " TextMode="Date"
autocomplete="off" data-date-format="yyyy-mm-dd"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">國家/地區 *</label>
<div class="col-sm-10 col-lg-3">
<div class="input-group mb-3" data-search-control="search3" @click="search_show(search_dialog.controls.search3)">
<input class="form-control search-text" type="text" readonly
id="country_txt" runat="server" placeholder="請選擇國家/地區" value="">
<asp:HiddenField ID="country" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" ControlToValidate="country_txt" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">收件地址<asp:Literal ID="addrReqStar" runat="server" Text=" *"></asp:Literal></label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="address" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入收件地址"></asp:TextBox>
<asp:RequiredFieldValidator ID="addressRFV" ControlToValidate="address" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">LINE帳號</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="socialid1" MaxLength="50" runat="server" CssClass="form-control" placeholder="請輸入LINE帳號" ToolTip="Line ID"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">其它社群帳號</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="socialid2" MaxLength="50" runat="server" CssClass="form-control" placeholder="請輸入其它社群帳號" ToolTip="FaceBook、Instagram..等等"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">介紹人</label>
<div class="col-sm-10 col-lg-3">
<%-- <asp:DropDownList ID="leader" CssClass="form-select" runat="server" data-int="Y">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>--%>
<div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)" >
<input class="form-control search-text" type="text" readonly
id="leader_txt" runat="server" placeholder="介紹人" value="">
<asp:HiddenField ID="leader" runat="server" Value="" />
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
</div>
<div class="d-none">
<label class="col-sm-2 col-lg-1 col-form-label">介紹人</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="introducer" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入介紹人"></asp:TextBox>
</div>
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">血型</label>
<div class="col-sm-10 col-lg-3">
<asp:DropDownList ID="blood" CssClass="form-select" runat="server">
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
<asp:ListItem Value="A" Text="A型"></asp:ListItem>
<asp:ListItem Value="B" Text="B型"></asp:ListItem>
<asp:ListItem Value="AB" Text="AB型"></asp:ListItem>
<asp:ListItem Value="O" Text="O型"></asp:ListItem>
</asp:DropDownList>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">緊急連絡人</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="contactor" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入緊急連絡人"></asp:TextBox>
</div>
<label class="col-sm-2 col-lg-1 col-form-label">緊急連絡人電話</label>
<div class="col-sm-10 col-lg-3">
<asp:TextBox ID="contactor_phone" MaxLength="15" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="請輸入緊急連絡人電話"></asp:TextBox>
<asp:RegularExpressionValidator ControlToValidate="contactor_phone" ErrorMessage="格式有誤" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^[+-]?\d+([+-]?\d*)*$" Display="Dynamic" SetFocusOnError="true" />
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-lg-1 col-form-label">自訂標籤</label>
<div class="col-sm-10 col-lg-3">
<div class="input-group">
<input type="text" class="form-control" v-model="tabArray2" v-on:keyup.enter="addTab" title="可自由輸入標籤名稱輸入完成請按「或「Enter」" placeholder="自訂標籤名稱">
<asp:HiddenField ID="tab" runat="server" />
<a class="btn btn-default" @click="addTab" ><i class="mdi mdi-plus"></i></a>
</div>
</div>
<div class="col-sm-12 col-lg-7">
<template>
<div class="">
<v-chip v-for="item,index in tabArray"
v-if="item != ''"
class="ma-2"
close
@click:close="tabArray.splice(index, 1);remove(item)"
>
{{item}}
</v-chip>
</div>
</template>
</div>
</div>
<div class="row mb-1">
<label class="col-form-label">備註</label>
<div class="">
<asp:TextBox ID="demo" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入備註"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
<label class="col-form-label">自定義欄位預設值</label>
<div class="">
<asp:TextBox ID="customize_data" runat="server" Rows="3" TextMode="MultiLine" CssClass="form-control" placeholder="一行輸入一個定義欄位預設值,如:&#10;$姓名:王OO&#10;$聯絡電話:0987654321" ToolTip="一行輸入一個定義欄位預設值,格式: $變數名稱:值"></asp:TextBox>
</div>
</div>
<div class="row mb-1">
<asp:Panel ID="timePanel1" runat="server" CssClass="col-12 text-right text-primary" Visible="false">建檔時間:<asp:Literal ID="reg_time" runat="server"></asp:Literal></asp:Panel>
<asp:Panel ID="timePanel2" runat="server" CssClass="col-12 text-right text-primary" Visible="false">最後修改時間:<asp:Literal ID="modify_time" runat="server"></asp:Literal></asp:Panel>
</div>
</div>
<div class="tab-pane fade" id="sec2-page2" role="tabpanel" aria-labelledby="sec2-tab2">
<%-- 原家長 --%>
<v-card class="mx-auto" outlined v-if="follower_id!=''">
<v-data-table
:headers="headersDetail"
:items="desserts"
<%--:footer-props="footersDetail"--%>
:search="searchDetail"
:loading="dessertsLoading"
:options.sync="optionsDetail" class="elevation-1" fixed-header height="350px"
<%-- :server-items-length="desserts_count"--%>
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="white">
<div class="d-flex w-100">
<v-text-field v-model="searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details></v-text-field>
<v-btn
color="primary"
class="ml-2 white--text "
:disabled="disableButton"
@click="addNew"
title="從下方列表新增家人">
<v-icon dark>mdi-plus</v-icon>新增家人
</v-btn>
<v-btn
color="primary"
class="ml-2 white--text "
:disabled="disableButton"
@click="addNewFollowerData"
:title="thisName()">
<v-icon dark>mdi-plus</v-icon>從信眾新增
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.f_num_selected.text="{ item }">
<div class="input-group mb-3" data-search-control="search2" @click="search_show(search_dialog.controls.search2)" v-if="item.id === editedItem.id">
<input class="form-control search-text" type="text" readonly
placeholder="姓名" v-model="editedItem.f_num_selected.text">
<input type="hidden" v-model="editedItem.f_num_selected.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.f_num_selected.text}}</span>
</template>
<template v-slot:item.appellation_id_selected.text="{ item }">
<div class="input-group mb-3" data-search-control="search4" @click="search_show(search_dialog.controls.search4)" v-if="item.id === editedItem.id">
<input class="form-control search-text" type="text" readonly
placeholder="稱謂" v-model="editedItem.appellation_id_selected.text">
<input type="hidden" v-model="editedItem.appellation_id_selected.val">
<button class="btn btn-outline-secondary" type="button">
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
<span v-else>{{item.appellation_id_selected.text}}</span>
</template>
<template v-slot:item.address="{ item }">
<span >{{item.address}}</span>
</template>
<template v-slot:item.birthday="{ item }">
<span >{{item.birthday|timeString('YYYY/MM/DD')}}</span>
</template>
<template v-slot:item.actions="{ item }">
<div v-if="item.id === editedItem.id">
<v-icon color="red" class="mr-3" @click="cancel">
mdi-window-close
</v-icon>
<v-icon color="green" @click="save">
mdi-content-save
</v-icon>
</div>
<div v-else>
<v-icon color="green" class="mr-3" @click="editItem(item);">
mdi-pencil
</v-icon>
<v-icon color="red" @click="deleteItem(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
<%-- <asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">家人</label>
<div class="col-sm-9">
<asp:DropDownList ID="familyDL" CssClass="form-select" runat="server" >
<asp:ListItem Value="" Text="請選擇"></asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" ControlToValidate="familyDL" runat="server"
ErrorMessage="必填!" ValidationGroup="addReq" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
<asp:Label ID="family_log" runat="server" ForeColor="Red"></asp:Label>
</div>
<div class="col-sm-1">
<asp:LinkButton ID="addFamily" runat="server" CssClass="btn btn-outline-secondary" ValidationGroup="addReq" OnClick="addFamily_Click" >
<i class='mdi mdi-plus'></i></asp:LinkButton>
</div>
</div>
<div class="row mb-1 label-sm-right">
<div class="col-sm-12">
<table class="table table-hover">
<thead>
<tr>
<th><span class="w-1">序</span></th>
<th><span class="w-2">姓名</span></th>
<th><span class="w-2">身分別</span></th>
<th><span class="w-2">生日</span></th>
<th><span class="w-2">聯絡電話</span></th>
<th><span class="w-2">備註</span></th>
<th><span class="w-1">移除</span></th>
</tr>
</thead>
<tbody>
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<tr>
<td><%# Container.ItemIndex+1 %></td>
<td><asp:Literal ID="rpt_u_name" runat="server" Text='<%# Eval("u_name") %>'></asp:Literal></td>
<td><asp:Literal ID="rpt_identity_type" runat="server" Text='<%# Eval("identity_type") %>'></asp:Literal></td>
<td><asp:Literal ID="rpt_birthday" runat="server" Text='<%# Eval("birthday") %>'></asp:Literal></td>
<td><asp:Literal ID="rpt_phone" runat="server" Text='<%# Eval("phone") %>'></asp:Literal></td>
<td><asp:Literal ID="rpt_demo" runat="server" Text='<%# br(ValString(Eval("demo"))) %>'></asp:Literal></td>
<td>
<asp:HiddenField ID="num" runat="server" Value='<%# Eval("num") %>' />
<asp:HiddenField ID="family_num" runat="server" Value='<%# Eval("family_num") %>' />
<asp:LinkButton ID="deleteF" runat="server" CssClass="btn btn-outline-secondary" CausesValidation="false" OnClick="deleteF_Click">
<i class='mdi mdi-minus'></i></asp:LinkButton>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
</div>
</div>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="500">
<ProgressTemplate>
<div style="padding: 10px; background-color: white; text-align: center">
<img src="../images/loading.gif" />請稍候…
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</ContentTemplate>
</asp:UpdatePanel>--%>
</div>
<div class="tab-pane fade" id="sec2-page2b" role="tabpanel" aria-labelledby="sec2-tab2">
<!--
:items="family.members"
:search="searchDetail"
-->
<v-card class="mx-auto" outlined v-if="follower_id!=''">
<v-data-table class="elevation-1" fixed-header height="350px"
:headers="family.headersDetail"
:items="filteredFamilyMembers"
:search="family.searchQuery"
:loading="family.loading"
:options.sync="optionsDetail"
:items-per-page="-1"
class="elevation-1"
fixed-header
height="350px"
>
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="transparent" class="row ms-0">
<div class="col-12 col-md-10 d-flex">
<v-text-field
v-model="family.searchQuery"
append-icon="mdi-magnify"
label="查詢"
dense
outlined
single-line
hide-details>
<template v-slot:append-outer>
<v-btn
icon
small
@click="family.searchQuery = ''"
v-if="family.searchQuery"
>
<v-icon>mdi-close</v-icon>
</v-btn>
</template>
</v-text-field>
<v-btn
color="primary"
class="ml-2 white--text "
title="新增親友"
@click="fam_add">
<v-icon dark>mdi-plus</v-icon>新增親友
</v-btn>
</div>
</v-toolbar>
</template>
<!-- Template for fam_name -->
<template v-slot:item.fam_name="{ item }">
{{item.fam_name}}
<%-- <v-text-field v-model="item.fam_name" label="姓名" dense outlined single-line hide-details></v-text-field> --%>
</template>
<!-- Template for fam_gender -->
<template v-slot:item.fam_gender="{ item }">
{{item.fam_gender}}
<%-- <v-text-field v-model="item.fam_gender" label="性別" dense outlined single-line hide-details></v-text-field> --%>
</template>
<!-- Template for fam_title -->
<template v-slot:item.fam_title="{ item }">
{{item.fam_title}}
<%-- <v-text-field v-model="item.fam_title" label="稱謂" dense outlined single-line hide-details></v-text-field> --%>
</template>
<!-- Template for deceased -->
<template v-slot:item.deceased="{ item }">
<v-checkbox
v-model="item.deceased"
:readonly="true"
:input-value="item.deceased"
:label="item.deceased ? '是' : '否'"
hide-details>
</v-checkbox>
</template>
<!-- Template for actions -->
<template v-slot:item.actions="{ item }">
<div>
<v-icon color="green" class="mr-3" @click="fam_edit(item)">
mdi-pencil
</v-icon>
<v-icon color="red" @click="fam_del(item)">
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
</v-card>
</div>
<div class="tab-pane fade" id="sec2-page3" role="tabpanel" aria-labelledby="sec2-tab3" >
<v-card class="mx-auto mt-10" outlined v-if="follower_id!=''">
<v-data-table
:headers="topDetail"
:items="lists"
:options.sync="recordsDetail" class="elevation-1" fixed-header height="350px">
<v-divider inset></v-divider>
<template v-slot:item.orderno="{ item }">
<a :href="'../order/reg.aspx?order_no='+item.order_no" target="_blank" >{{item.order_no}}</a>
</template>
<template v-slot:item.up_time="{ item }">
<span >{{item.up_time|timeString('YYYY/MM/DD')}}</span>
</template>
<template v-slot:item.totalprice="{ item }">
{{item.totalPrice | currency }}
</template>
<template v-slot:item.payprice="{ item }">
{{item.payPrice | currency }}
</template>
<template v-slot:item.notpay="{ item }">
<span >{{item.totalPrice - item.payPrice | currency}}</span>
</template>
<template v-slot:body.append>
<tr>
<td colspan="3" class="text-right">合計</td>
<td class="text-right"> {{order_total_price | currency }}</td>
<td class="text-right"> {{order_payprice_price | currency }}</td>
<td class="text-right"> {{order_notpay_price | currency }}</td>
</tr>
</template>
</v-data-table>
</v-card>
</div>
<div class="tab-pane fade" id="sec2-page4" role="tabpanel" aria-labelledby="sec2-tab4" >
<v-card class="mx-auto" outlined v-if="follower_id!=''">
<v-data-table
:headers="tabletTable.headersDetail"
:items="filteredTabletItems"
<%--:footer-props="footersDetail"--%>
<%--
:items="tabletTable.desserts"
--%>
:search="tabletTable.searchDetail"
:loading="tabletTable.Loading"
:options.sync="tabletsDetail" class="elevation-1" fixed-header height="350px">
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="transparent" class="row ms-0">
<v-radio-group class="col-12 col-md-3" v-model="selectedTabletType" row>
<v-radio v-for="item in listTabletType" :key="item.value" :label="item.label" :value="item.value"></v-radio>
</v-radio-group>
<div class="col-12 col-md-9 d-flex">
<v-text-field v-model="tabletTable.searchDetail" append-icon="mdi-magnify" label="查詢" dense outlined single-line hide-details></v-text-field>
<v-btn
color="primary"
class="ml-2 white--text "
:disabled="tabletTable.disableButton"
@click="addNewTablet"
title="從下方列表新增牌位標題">
<v-icon dark>mdi-plus</v-icon>新增牌位標題
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.type="{item}">
<td class="text-start align-top pt-2" v-if="item.id === tabletTable.editedItem.id">
<v-select
label="類型"
v-model="tabletTable.editedItem.type"
:items="listTabletType"
item-text="label"
item-value="value"
></v-select>
</td>
<td v-else>
{{item.type}}
</td>
</template>
<template v-slot:item.title="{ item }">
<td class="text-start align-top pt-2" v-if="item.id === tabletTable.editedItem.id">
<div class="input-group mb-3">
<v-textarea
ref="textarea"
label="牌位標題"
v-model="tabletTable.editedItem.title"
></v-textarea>
<div >
<button class="btn btn-outline-secondary " type="button"
data-search-control="search5" @click="search_show(search_dialog.controls.search5)" >
<i class="mdi mdi-view-list-outline"></i>
</button>
</div>
</div>
</td>
<td class="text-white-space-pre" v-else>{{item.title}}</td>
</template>
<template v-slot:item.actions="{ item }">
<td class="text-start align-top pt-2" v-if="item.id === tabletTable.editedItem.id">
<v-icon color="red" class="mr-3" @click="cancelTablet">
mdi-window-close
</v-icon>
<v-icon color="green" @click="saveTablet">
mdi-content-save
</v-icon>
</td>
<td v-else>
<v-icon color="green" class="mr-3" @click="editTabletItem(item);">
mdi-pencil
</v-icon>
<v-icon color="red" @click="deleteTabletItem(item)">
mdi-delete
</v-icon>
</td>
</template>
</v-data-table>
</v-card>
</div>
</div>
</asp:Panel>
</div>
<!-- Family Member Dialog -->
<v-dialog v-model="family.dialog" max-width="600px">
<v-card>
<v-card-title class="sticky-card-title">
<span class="headline">{{ family.isEditing ? '編輯親友' : '新增親友' }}</span>
</v-card-title>
<v-card-text>
<v-form ref="familyForm">
<v-text-field
v-model="family.edItem.fam_name"
label="姓名 * "
required
></v-text-field>
<v-row>
<v-col cols="4">
<v-select
v-model="family.edItem.fam_gender"
:items="['男', '女', '其他']"
label="性別"
required
dense
></v-select>
</v-col>
<v-col cols="4">
<v-text-field
v-model="family.edItem.fam_title"
label="稱謂"
required
dense
></v-text-field>
</v-col>
<v-col cols="4">
<v-checkbox
v-model="family.edItem.deceased"
label="歿"
dense
></v-checkbox>
</v-col>
</v-row>
<v-row>
<v-col cols="6">
<v-text-field
v-model="family.edItem.birthdate"
label="出生年月日"
type="date"
dense
@input="calculateLunarBirthday(family.edItem)"
></v-text-field>
</v-col>
<v-col cols="6">
農曆生日: {{ family.edItem.lunarBirthday || '--' }}
</v-col>
<v-col cols="4">
<v-select
v-model="family.edItem.age"
:items="chineseYears"
label="歲次"
dense
></v-select>
</v-col>
<v-col cols="3">
<v-select
v-model="family.edItem.zodiac"
:items="zodiac"
label="生肖"
dense
></v-select>
</v-col>
<v-col cols="5">
<v-select
v-model="family.edItem.birth_time"
:items="birth_time"
item-text="text"
item-value="value"
label="生辰"
dense
></v-select>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<v-switch
v-model="family.is_tw"
:label="family.is_tw ? '境內' : '境外'"
@change="toggleCityAreaVisibility"
></v-switch>
</v-col>
<v-col cols="4">
<v-select
v-if="family.is_tw"
v-model="family.edItem.city"
:items="cityOptions"
label="縣市"
@change="onCityChange"
></v-select>
</v-col>
<v-col cols="4">
<v-select
v-if="family.is_tw"
v-model="family.edItem.area"
:items="areaOptions[family.edItem.city]"
label="鄉鎮市區"
:disabled="!family.edItem.city"
></v-select>
</v-col>
</v-row>
<v-text-field
v-model="family.edItem.address"
label="地址"
></v-text-field>
<v-text-field
v-model="family.edItem.phone"
label="電話"
type="tel"
></v-text-field>
<v-text-field
v-model="family.edItem.mobile"
label="行動電話"
type="tel"
></v-text-field>
<!-- Hidden field for num -->
<input type="hidden" v-model="family.edItem.num">
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="fam_close">取消</v-btn>
<v-btn color="blue darken-1" text @click="fam_save">儲存</v-btn>
</v-card-actions>
</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-checkbox v-if="item.id=='onlyfamily' "
v-model="item.value"
label="只查親屬"
></v-checkbox>
<v-text-field v-model="item.value" :label="item.title" v-else ></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="options"
:loading.sync="search_dialog.loading"
@click:row="search_select"
></v-data-table>
</v-card-text>
<v-card-actions>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
:color="snackbar.color"
timeout="3000"
>
{{ snackbar.message }}
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snackbar.show = false"
>
關閉
</v-btn>
</template>
</v-snackbar>
</div>
</asp:Content>