新增: 牌位自訂名稱
This commit is contained in:
@@ -88,6 +88,14 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
/* num=0 刪除按鈕警示樣式 */
|
||||||
|
.btn-delete-warning:hover {
|
||||||
|
background-color: #fff3cd !important;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.btn-delete-warning:hover .v-icon {
|
||||||
|
color: #856404 !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="print.css">
|
<link rel="stylesheet" href="print.css">
|
||||||
</head>
|
</head>
|
||||||
@@ -127,16 +135,30 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="4" md="4" id="type_edit_B" v-if="item_type==='B'" class="d-flex flex-column">
|
<v-col cols="4" md="4" id="type_edit_B" v-if="item_type==='B'" class="d-flex flex-column">
|
||||||
<v-card elevation="2" class="mb-2 equal-card">
|
<v-card elevation="2" class="mb-2 equal-card">
|
||||||
|
<v-card-text class="py-2 px-2">
|
||||||
|
<v-row no-gutters align="center">
|
||||||
|
<v-col cols="auto">
|
||||||
<v-checkbox v-model="isAllSelected"
|
<v-checkbox v-model="isAllSelected"
|
||||||
@change="toggleSelectAll"
|
@change="toggleSelectAll"
|
||||||
color="primary"
|
color="primary"
|
||||||
hide-details
|
hide-details
|
||||||
class="checkbox-narrow d-inline-flex"></v-checkbox>
|
label="疏文代表"
|
||||||
<v-card-subtitle class="d-inline-flex ">疏文代表</v-card-subtitle>
|
class="ma-0"></v-checkbox>
|
||||||
<v-card-subtitle class="d-inline-flex ml-2">超渡-已選</v-card-subtitle>
|
</v-col>
|
||||||
|
<v-col cols="auto" class="ml-4">
|
||||||
|
<span class="subtitle-2 grey--text text--darken-1">超渡-已選</span>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-col cols="auto">
|
||||||
|
<v-btn color="primary" icon small @click="openAddDialog('Y')">
|
||||||
|
<v-icon>mdi-plus</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
<v-list class="scrollable-list">
|
<v-list class="scrollable-list">
|
||||||
<v-list-item-group>
|
<v-list-item-group>
|
||||||
<v-list-item v-for="(member, index) in family_deceased_Y_selected" :key="member.num" class="hover-item">
|
<v-list-item v-for="(member, index) in family_deceased_Y_selected" :key="index" class="hover-item">
|
||||||
<v-list-item-action>
|
<v-list-item-action>
|
||||||
<v-checkbox v-model="member.IsShuWen"
|
<v-checkbox v-model="member.IsShuWen"
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -152,13 +174,16 @@
|
|||||||
</v-chip>
|
</v-chip>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<v-list-item-subtitle class="d-flex justify-end">
|
<v-list-item-subtitle class="d-flex justify-end">
|
||||||
|
<v-btn v-if="member.num === 0" icon @click="toggleNoSpace(member)" :title="'不加空格'">
|
||||||
|
<v-icon :color="member.nospace ? 'green' : 'grey lighten-1'">mdi-backspace</v-icon>
|
||||||
|
</v-btn>
|
||||||
<v-btn icon @click="moveUp(member, 'Y', index)" :disabled="index === 0">
|
<v-btn icon @click="moveUp(member, 'Y', index)" :disabled="index === 0">
|
||||||
<v-icon color="grey lighten-1">mdi-arrow-up</v-icon>
|
<v-icon color="grey lighten-1">mdi-arrow-up</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon @click="moveDown(member, 'Y', index)" :disabled="index === family_deceased_Y_selected.length - 1">
|
<v-btn icon @click="moveDown(member, 'Y', index)" :disabled="index === family_deceased_Y_selected.length - 1">
|
||||||
<v-icon color="grey lighten-1">mdi-arrow-down</v-icon>
|
<v-icon color="grey lighten-1">mdi-arrow-down</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon @click="removeFromSelected(member, 'Y')">
|
<v-btn icon @click="confirmRemove(member, index, 'Y')" :class="{'btn-delete-warning': member.num === 0}">
|
||||||
<v-icon color="grey lighten-1">mdi-minus</v-icon>
|
<v-icon color="grey lighten-1">mdi-minus</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-list-item-subtitle>
|
</v-list-item-subtitle>
|
||||||
@@ -200,16 +225,30 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="4" md="4" id="type_edit_AB" class="d-flex flex-column">
|
<v-col cols="4" md="4" id="type_edit_AB" class="d-flex flex-column">
|
||||||
<v-card elevation="2" class="mb-2 equal-card">
|
<v-card elevation="2" class="mb-2 equal-card">
|
||||||
|
<v-card-text class="py-2 px-2">
|
||||||
|
<v-row no-gutters align="center">
|
||||||
|
<v-col cols="auto" v-if="item_type==='A'">
|
||||||
<v-checkbox v-model="isAllSelected"
|
<v-checkbox v-model="isAllSelected"
|
||||||
@change="toggleSelectAll"
|
@change="toggleSelectAll"
|
||||||
color="primary"
|
color="primary"
|
||||||
hide-details
|
hide-details
|
||||||
class="checkbox-narrow d-inline-flex align-center" v-if="item_type==='A'"></v-checkbox>
|
label="疏文代表"
|
||||||
<v-card-subtitle class="d-inline-flex align-center" v-if="item_type==='A'">疏文代表</v-card-subtitle>
|
class="ma-0"></v-checkbox>
|
||||||
<v-card-subtitle class="d-inline-flex align-center ml-2">陽上/祈福-已選</v-card-subtitle>
|
</v-col>
|
||||||
|
<v-col cols="auto" :class="{'ml-4': item_type==='A'}">
|
||||||
|
<span class="subtitle-2 grey--text text--darken-1">陽上/祈福-已選</span>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-col cols="auto">
|
||||||
|
<v-btn color="primary" icon small @click="openAddDialog('N')">
|
||||||
|
<v-icon>mdi-plus</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
<v-list class="scrollable-list">
|
<v-list class="scrollable-list">
|
||||||
<v-list-item-group>
|
<v-list-item-group>
|
||||||
<v-list-item v-for="(member, index) in family_deceased_N_selected" :key="member.num" class="hover-item">
|
<v-list-item v-for="(member, index) in family_deceased_N_selected" :key="index" class="hover-item">
|
||||||
<v-list-item-action v-if="item_type==='A'">
|
<v-list-item-action v-if="item_type==='A'">
|
||||||
<v-checkbox v-model="member.IsShuWen"
|
<v-checkbox v-model="member.IsShuWen"
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -225,13 +264,16 @@
|
|||||||
</v-chip>
|
</v-chip>
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
<v-list-item-subtitle class="d-flex justify-end">
|
<v-list-item-subtitle class="d-flex justify-end">
|
||||||
|
<v-btn v-if="member.num === 0" icon @click="toggleNoSpace(member)" :title="'不加空格'">
|
||||||
|
<v-icon :color="member.nospace ? 'green' : 'grey lighten-1'">mdi-backspace</v-icon>
|
||||||
|
</v-btn>
|
||||||
<v-btn icon @click="moveUp(member, 'N', index)" :disabled="index === 0">
|
<v-btn icon @click="moveUp(member, 'N', index)" :disabled="index === 0">
|
||||||
<v-icon color="grey lighten-1">mdi-arrow-up</v-icon>
|
<v-icon color="grey lighten-1">mdi-arrow-up</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon @click="moveDown(member, 'N', index)" :disabled="index === family_deceased_N_selected.length - 1">
|
<v-btn icon @click="moveDown(member, 'N', index)" :disabled="index === family_deceased_N_selected.length - 1">
|
||||||
<v-icon color="grey lighten-1">mdi-arrow-down</v-icon>
|
<v-icon color="grey lighten-1">mdi-arrow-down</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon @click="removeFromSelected(member, 'N')">
|
<v-btn icon @click="confirmRemove(member, index, 'N')" :class="{'btn-delete-warning': member.num === 0}">
|
||||||
<v-icon color="grey lighten-1">mdi-minus</v-icon>
|
<v-icon color="grey lighten-1">mdi-minus</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-list-item-subtitle>
|
</v-list-item-subtitle>
|
||||||
@@ -276,6 +318,66 @@
|
|||||||
<div style="display:block;">
|
<div style="display:block;">
|
||||||
<textarea id="desc_iframe" style="width: 900px; height: 100px;">{{tabletItem}}</textarea>
|
<textarea id="desc_iframe" style="width: 900px; height: 100px;">{{tabletItem}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 新增項目對話框 -->
|
||||||
|
<v-dialog v-model="addDialog" max-width="400">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title style="font-size: 1rem;">新增項目</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<div class="mb-2">
|
||||||
|
<v-chip
|
||||||
|
v-for="(phrase, idx) in phrases"
|
||||||
|
:key="idx"
|
||||||
|
small
|
||||||
|
class="mr-1 mb-1"
|
||||||
|
:title="phrase.length > 5 ? phrase : ''"
|
||||||
|
@click="newItemText = (newItemText || '') + phrase"
|
||||||
|
style="cursor: pointer;"
|
||||||
|
>{{ phrase.length > 5 ? phrase.slice(0, 5) + '...' : phrase }}</v-chip>
|
||||||
|
</div>
|
||||||
|
<v-text-field
|
||||||
|
v-model="newItemText"
|
||||||
|
label="請輸入名稱"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
clearable
|
||||||
|
autofocus
|
||||||
|
@keyup.enter="confirmAddItem"
|
||||||
|
></v-text-field>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<v-checkbox
|
||||||
|
class="pt-0"
|
||||||
|
v-model="noSpace"
|
||||||
|
label="不加空格"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
></v-checkbox>
|
||||||
|
<v-icon class="ml-2 mt-1">mdi-backspace</v-icon>
|
||||||
|
</div>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn text @click="addDialog = false">取消</v-btn>
|
||||||
|
<v-btn color="primary" @click="confirmAddItem">確定</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<!-- 確認刪除對話框 -->
|
||||||
|
<v-dialog v-model="deleteDialog" max-width="350">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title style="font-size: 1rem;">確認刪除</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
確定要刪除「<strong>{{ deleteMemberName }}</strong>」嗎?<br>
|
||||||
|
<span class="red--text">此為手動新增項目,刪除後無法復原。</span>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn text @click="deleteDialog = false">取消</v-btn>
|
||||||
|
<v-btn color="error" @click="doRemove">確定刪除</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
</v-app>
|
</v-app>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -286,6 +388,15 @@
|
|||||||
return {
|
return {
|
||||||
isAllSelected: false,
|
isAllSelected: false,
|
||||||
dialog: false,
|
dialog: false,
|
||||||
|
addDialog: false, // 新增項目對話框
|
||||||
|
addDialogType: '', // 'Y' 或 'N'
|
||||||
|
newItemText: '', // 新增項目的文字
|
||||||
|
noSpace: true, // 不加空格 checkbox(預設勾選)
|
||||||
|
deleteDialog: false, // 確認刪除對話框
|
||||||
|
deleteIndex: -1, // 要刪除的 index
|
||||||
|
deleteType: '', // 'Y' 或 'N'
|
||||||
|
deleteMemberName: '', // 要刪除的名稱(顯示用)
|
||||||
|
phrases: [], // 常用片語
|
||||||
familyMembers: [], // 親友名單
|
familyMembers: [], // 親友名單
|
||||||
tabletItem: {}, // 傳入的資料(信眾/牌位資訊)
|
tabletItem: {}, // 傳入的資料(信眾/牌位資訊)
|
||||||
item: {},
|
item: {},
|
||||||
@@ -361,6 +472,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
// 載入常用片語
|
||||||
|
fetch('phrases.json')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => { this.phrases = data; })
|
||||||
|
.catch(err => console.error('載入 phrases.json 失敗:', err));
|
||||||
|
|
||||||
// 監聽來自父頁面的消息
|
// 監聽來自父頁面的消息
|
||||||
window.addEventListener('message', (event) => {
|
window.addEventListener('message', (event) => {
|
||||||
this.isAllSelected = false;
|
this.isAllSelected = false;
|
||||||
@@ -452,6 +569,34 @@
|
|||||||
console.log(this.family_deceased_N_selected)
|
console.log(this.family_deceased_N_selected)
|
||||||
console.log(this.family_deceased_Y_selected)
|
console.log(this.family_deceased_Y_selected)
|
||||||
},
|
},
|
||||||
|
openAddDialog(type) {
|
||||||
|
this.addDialogType = type;
|
||||||
|
this.newItemText = '';
|
||||||
|
this.noSpace = true; // 重置為預設勾選
|
||||||
|
this.addDialog = true;
|
||||||
|
},
|
||||||
|
confirmAddItem() {
|
||||||
|
if (!this.newItemText.trim()) {
|
||||||
|
return; // 不允許空白
|
||||||
|
}
|
||||||
|
const newItem = {
|
||||||
|
num: 0,
|
||||||
|
fam_name: this.newItemText.trim(),
|
||||||
|
fam_gender: '',
|
||||||
|
deceased: false,
|
||||||
|
fam_title: '',
|
||||||
|
option_break: false,
|
||||||
|
IsShuWen: this.isAllSelected,
|
||||||
|
nospace: this.noSpace
|
||||||
|
};
|
||||||
|
if (this.addDialogType === 'Y') {
|
||||||
|
this.family_deceased_Y_selected.push(newItem);
|
||||||
|
} else if (this.addDialogType === 'N') {
|
||||||
|
this.family_deceased_N_selected.push(newItem);
|
||||||
|
}
|
||||||
|
this.addDialog = false;
|
||||||
|
this.newItemText = '';
|
||||||
|
},
|
||||||
addToSelected(member, type) {
|
addToSelected(member, type) {
|
||||||
const selectedMember = {
|
const selectedMember = {
|
||||||
num: member.num,
|
num: member.num,
|
||||||
@@ -471,21 +616,27 @@
|
|||||||
console.log(this.family_deceased_N_selected)
|
console.log(this.family_deceased_N_selected)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeFromSelected(member, type) {
|
confirmRemove(member, index, type) {
|
||||||
|
if (member.num === 0) {
|
||||||
|
// num=0 需確認
|
||||||
|
this.deleteIndex = index;
|
||||||
|
this.deleteType = type;
|
||||||
|
this.deleteMemberName = member.fam_name;
|
||||||
|
this.deleteDialog = true;
|
||||||
|
} else {
|
||||||
|
// num!=0 直接刪除
|
||||||
|
this.removeFromSelected(index, type);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doRemove() {
|
||||||
|
this.removeFromSelected(this.deleteIndex, this.deleteType);
|
||||||
|
this.deleteDialog = false;
|
||||||
|
},
|
||||||
|
removeFromSelected(index, type) {
|
||||||
if (type === 'Y') {
|
if (type === 'Y') {
|
||||||
this.family_deceased_Y_selected.forEach(m => {
|
this.family_deceased_Y_selected.splice(index, 1);
|
||||||
if (m.num === member.num) {
|
|
||||||
Vue.delete(m, 'IsShuWen');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.family_deceased_Y_selected = this.family_deceased_Y_selected.filter(m => m.num !== member.num);
|
|
||||||
} else if (type === 'N') {
|
} else if (type === 'N') {
|
||||||
this.family_deceased_N_selected.forEach(m => {
|
this.family_deceased_N_selected.splice(index, 1);
|
||||||
if (m.num === member.num) {
|
|
||||||
Vue.delete(m, 'IsShuWen');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.family_deceased_N_selected = this.family_deceased_N_selected.filter(m => m.num !== member.num);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
moveUp(member, type, index) {
|
moveUp(member, type, index) {
|
||||||
@@ -508,23 +659,25 @@
|
|||||||
console.log("breakAfter", member, type);
|
console.log("breakAfter", member, type);
|
||||||
member.option_break = !member.option_break;
|
member.option_break = !member.option_break;
|
||||||
},
|
},
|
||||||
|
toggleNoSpace(member) {
|
||||||
|
this.$set(member, 'nospace', !member.nospace);
|
||||||
|
},
|
||||||
join_text(target) {
|
join_text(target) {
|
||||||
// console.log("join_text", target);
|
|
||||||
// join each item by ' '
|
|
||||||
// and for each item, if true for "option_break", then add "<br>" in the item text
|
|
||||||
let result = '';
|
let result = '';
|
||||||
target.forEach((member, index) => {
|
target.forEach((member, index) => {
|
||||||
|
// 每項前面加空格,但例外:
|
||||||
|
// 1. 第一項前面不加空格 (index === 0)
|
||||||
|
// 2. nospace === true 的項目前面不加空格
|
||||||
|
if (index > 0 && !member.nospace) {
|
||||||
|
result += ' ';
|
||||||
|
}
|
||||||
result += member.fam_name;
|
result += member.fam_name;
|
||||||
// Add break if option_break is true and not the last item
|
// 處理換行:如果 option_break 為 true 且不是最後一項,加 <br>
|
||||||
if (member.option_break && index < target.length - 1) {
|
if (member.option_break && index < target.length - 1) {
|
||||||
result += '<br>';
|
result += '<br>';
|
||||||
} else if (index < target.length - 1) {
|
|
||||||
// Add space between names if not the last item and no break
|
|
||||||
result += ' ';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
result = result.replace('|', '<br>');
|
result = result.replace('|', '<br>');
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
calculateTextStyle(text) {
|
calculateTextStyle(text) {
|
||||||
|
|||||||
13
web/admin/print/tablet_edit/phrases.json
Normal file
13
web/admin/print/tablet_edit/phrases.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[
|
||||||
|
"歷代祖先",
|
||||||
|
"冤親債主",
|
||||||
|
"嬰靈",
|
||||||
|
"地基主",
|
||||||
|
"無祀孤魂",
|
||||||
|
"累世父母",
|
||||||
|
"六親眷屬",
|
||||||
|
"有緣無緣眾生",
|
||||||
|
"十方法界眾生",
|
||||||
|
"水陸空一切眾生"
|
||||||
|
]
|
||||||
|
|
||||||
Reference in New Issue
Block a user