migrate to new git
This commit is contained in:
602
web/admin/print/tablet_edit/editor.html
Normal file
602
web/admin/print/tablet_edit/editor.html
Normal file
@@ -0,0 +1,602 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<link href="../../../js/vuetify.css" rel="stylesheet" />
|
||||
<link href="../../../js/mdi-font/css/materialdesignicons.min.css" rel="stylesheet" />
|
||||
<script src="../../../js/vue.min.js"></script>
|
||||
<script src="../../../js/vuetify.min.js"></script>
|
||||
<script src="../../../js/axios.min.js"></script>
|
||||
<style>
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollable-list {
|
||||
max-height: 250px;
|
||||
height: 220px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.scrollable-list .v-list-item__content {
|
||||
padding: 4px 0px;
|
||||
}
|
||||
|
||||
.scrollable-list .v-list-item {
|
||||
min-height: 30px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.scrollable-list .v-list-item__action {
|
||||
min-width: 0 !important;
|
||||
width: auto !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.scrollable-list .v-btn--icon.v-size--default {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
#app .v-card__subtitle,
|
||||
#app .v-card__text,
|
||||
#app .v-card__title {
|
||||
padding: 12px 16px 0 16px;
|
||||
}
|
||||
|
||||
#app .v-list-item.hover-item .v-list-item__subtitle {
|
||||
/*display: none !important;*/
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
#app .v-list-item.hover-item:hover .v-list-item__subtitle {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.badge-deceased {
|
||||
background-color: #ffc904;
|
||||
color: #300a0a;
|
||||
padding: 2px 4px;
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.badge-zero {
|
||||
background-color: #CCC;
|
||||
color: #FFF;
|
||||
padding: 2px 4px;
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
.equal-card {
|
||||
min-height: 260px;
|
||||
}
|
||||
.checkbox-narrow {
|
||||
min-width: 32px;
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="print.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<v-app>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col cols="4" md="4">
|
||||
<v-card class="pa-2" outlined tile>
|
||||
<div class="docs editor">
|
||||
<div class="page border" data-body-class="tblt-l a3">
|
||||
<div class="content">
|
||||
<div class="bg"><img alt="Alternate Text" :src="'../' + item_type_image"></div>
|
||||
<div class="text">
|
||||
<div class="top_text_1"></div>
|
||||
<div class="top_text_2">{{tabletItem.print_id}}</div>
|
||||
<div class="top_text_3"></div>
|
||||
<div class="right_text text-block fit-text vertical text-start border"
|
||||
style="--lines:0;--line_len:5;"></div>
|
||||
<div class="mid_text text-block fit-text vertical border"
|
||||
:style="mid_text_style" v-html="join_mid_text"></div>
|
||||
<div class="mid_text_2 text-block fit-text vertical border"
|
||||
style="--lines:0;--line_len:5;"></div>
|
||||
<div class="left_text text-block fit-text vertical text-start border"
|
||||
:style="left_text_style" v-html="join_left_text"></div>
|
||||
<div class="txt_up vertical" v-if="item_type == 'B'">陽上</div>
|
||||
<div class="txt_down vertical" v-if="item_type == 'B'">拜薦</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
<div class="mt-2">
|
||||
<v-btn color="primary" @click="saveData">儲存牌位</v-btn>
|
||||
</div>
|
||||
</v-col>
|
||||
<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-checkbox v-model="isAllSelected"
|
||||
@change="toggleSelectAll"
|
||||
color="primary"
|
||||
hide-details
|
||||
class="checkbox-narrow d-inline-flex"></v-checkbox>
|
||||
<v-card-subtitle class="d-inline-flex ">疏文代表</v-card-subtitle>
|
||||
<v-card-subtitle class="d-inline-flex ml-2">超渡-已選</v-card-subtitle>
|
||||
<v-list class="scrollable-list">
|
||||
<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-action>
|
||||
<v-checkbox v-model="member.IsShuWen"
|
||||
color="primary"
|
||||
class="checkbox-narrow d-inline-flex align-center" />
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
<span class="badge-zero" v-if="member.num==0">0</span>
|
||||
<span class="badge-deceased" v-if="member.deceased">{{ member.deceased ? '卍' : '' }}</span>
|
||||
{{ member.fam_name }}
|
||||
<v-chip v-if="member.fam_title" small>
|
||||
{{ member.fam_title }}
|
||||
</v-chip>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="d-flex justify-end">
|
||||
<v-btn icon @click="moveUp(member, 'Y', index)" :disabled="index === 0">
|
||||
<v-icon color="grey lighten-1">mdi-arrow-up</v-icon>
|
||||
</v-btn>
|
||||
<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-btn>
|
||||
<v-btn icon @click="removeFromSelected(member, 'Y')">
|
||||
<v-icon color="grey lighten-1">mdi-minus</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action class="align-self-start">
|
||||
<v-btn icon @click="breakAfter(member, 'Y')">
|
||||
<v-icon :color="member.option_break ? 'blue' : 'grey lighten-1'">
|
||||
mdi-subdirectory-arrow-left
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</v-card>
|
||||
<v-card elevation="2" class="equal-card">
|
||||
<v-card-subtitle>超渡-可選</v-card-subtitle>
|
||||
<v-list class="scrollable-list">
|
||||
<v-list-item-group>
|
||||
<v-list-item v-for="member in family_deceased_Y_unselected" :key="member.fam_name">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
<span class="badge-deceased" v-if="member.deceased">{{ member.deceased ? '卍' : '' }}</span>
|
||||
{{ member.fam_name }}
|
||||
<v-chip v-if="member.fam_title" small>
|
||||
{{ member.fam_title }}
|
||||
</v-chip>
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn icon @click="addToSelected(member, 'Y')">
|
||||
<v-icon color="grey lighten-1">mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<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-checkbox v-model="isAllSelected"
|
||||
@change="toggleSelectAll"
|
||||
color="primary"
|
||||
hide-details
|
||||
class="checkbox-narrow d-inline-flex align-center" v-if="item_type==='A'"></v-checkbox>
|
||||
<v-card-subtitle class="d-inline-flex align-center" v-if="item_type==='A'">疏文代表</v-card-subtitle>
|
||||
<v-card-subtitle class="d-inline-flex align-center ml-2">陽上/祈福-已選</v-card-subtitle>
|
||||
<v-list class="scrollable-list">
|
||||
<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-action v-if="item_type==='A'">
|
||||
<v-checkbox v-model="member.IsShuWen"
|
||||
color="primary"
|
||||
class="checkbox-narrow d-inline-flex align-center" />
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
<span class="badge-zero" v-if="member.num==0">0</span>
|
||||
<span class="badge-deceased" v-if="member.deceased">{{ member.deceased ? '卍' : '' }}</span>
|
||||
{{ member.fam_name }}
|
||||
<v-chip v-if="member.fam_title" small>
|
||||
{{ member.fam_title }}
|
||||
</v-chip>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="d-flex justify-end">
|
||||
<v-btn icon @click="moveUp(member, 'N', index)" :disabled="index === 0">
|
||||
<v-icon color="grey lighten-1">mdi-arrow-up</v-icon>
|
||||
</v-btn>
|
||||
<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-btn>
|
||||
<v-btn icon @click="removeFromSelected(member, 'N')">
|
||||
<v-icon color="grey lighten-1">mdi-minus</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</div>
|
||||
<v-list-item-action class="align-self-start">
|
||||
<v-btn icon @click="breakAfter(member, 'N')">
|
||||
<v-icon :color="member.option_break ? 'blue' : 'grey lighten-1'">
|
||||
mdi-subdirectory-arrow-left
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</v-card>
|
||||
<v-card elevation="2" class="equal-card">
|
||||
<v-card-subtitle>陽上/祈福-可選</v-card-subtitle>
|
||||
<v-list class="scrollable-list">
|
||||
<v-list-item-group>
|
||||
<v-list-item v-for="member in family_deceased_N_unselected" :key="member.fam_name">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
<span class="badge-deceased" v-if="member.deceased">{{ member.deceased ? '卍' : '' }}</span>
|
||||
{{ member.fam_name }}
|
||||
<v-chip v-if="member.fam_title" small>
|
||||
{{ member.fam_title }}
|
||||
</v-chip>
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn icon @click="addToSelected(member, 'N')">
|
||||
<v-icon color="grey lighten-1">mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<div style="display:none;">
|
||||
<textarea id="desc_iframe" style="width: 900px; height: 100px;">{{tabletItem}}</textarea>
|
||||
</div>
|
||||
</v-app>
|
||||
</div>
|
||||
<script>
|
||||
var VueApp = new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(),
|
||||
data() {
|
||||
return {
|
||||
isAllSelected: false,
|
||||
dialog: false,
|
||||
familyMembers: [], // 親友名單
|
||||
tabletItem: {}, // 傳入的資料(信眾/牌位資訊)
|
||||
item: {},
|
||||
family_deceased_Y_selected: [], // 超渡/超薦/超冤名單
|
||||
family_deceased_N_selected: [] // 消災/陽上名單
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
family_deceased_N_selected: {
|
||||
handler(newValue) {
|
||||
if (this.item_type === 'A') {
|
||||
if (Array.isArray(newValue) && newValue.length > 0) {
|
||||
this.isAllSelected = newValue.every(member => member.IsShuWen === true);
|
||||
}
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
family_deceased_Y_selected: {
|
||||
handler(newValue) {
|
||||
if (this.item_type === 'B') {
|
||||
if (Array.isArray(newValue) && newValue.length > 0) {
|
||||
this.isAllSelected = newValue.every(member => member.IsShuWen === true);
|
||||
}
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
family_deceased_Y_unselected() {
|
||||
return this.familyMembers.filter(member => member.deceased === true && !this.family_deceased_Y_selected.some(selected => selected.num === member.num));
|
||||
},
|
||||
family_deceased_N_unselected() {
|
||||
return this.familyMembers.filter(member => member.deceased === false && !this.family_deceased_N_selected.some(selected => selected.num === member.num));
|
||||
},
|
||||
item_type() {
|
||||
return this.tabletItem?.actitem_num_selected?.text?.includes('超') ? 'B' : 'A';
|
||||
// A:消災, 陽上.....
|
||||
// B:超渡, 超薦.....
|
||||
},
|
||||
item_type_image() {
|
||||
if (this.item_type === 'B') {
|
||||
return 'tablet-1.svg';
|
||||
} else {
|
||||
return 'tablet-2.svg';
|
||||
}
|
||||
},
|
||||
join_mid_text() {
|
||||
const target = this.item_type === 'B'
|
||||
? this.family_deceased_Y_selected
|
||||
: this.family_deceased_N_selected;
|
||||
return this.join_text(target);
|
||||
},
|
||||
join_left_text() {
|
||||
let target = '';
|
||||
if (this.item_type === 'B') {
|
||||
target = this.join_text(this.family_deceased_N_selected);
|
||||
}
|
||||
return target;
|
||||
},
|
||||
mid_text_style() {
|
||||
const text = this.join_mid_text; // Remove function call since join_mid_text is a computed property
|
||||
return this.calculateTextStyle(text);
|
||||
},
|
||||
left_text_style() {
|
||||
if (this.item_type !== 'B') return '--lines:1;--line_len:5';
|
||||
return this.calculateTextStyle(this.join_left_text);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 監聽來自父頁面的消息
|
||||
window.addEventListener('message', (event) => {
|
||||
this.isAllSelected = false;
|
||||
console.log('editor.html - received message event');
|
||||
console.log('editor.html - event origin:', event.origin);
|
||||
console.log('editor.html - parent origin:', window.parent.location.origin);
|
||||
|
||||
if (event.origin === window.parent.location.origin) {
|
||||
console.log('editor.html - origin check passed');
|
||||
console.log('editor.html - received data:', event.data);
|
||||
const receivedData = event.data;
|
||||
this.family_deceased_Y_selected = [];
|
||||
this.family_deceased_N_selected = [];
|
||||
|
||||
if (receivedData.tabletItem) {
|
||||
console.log('editor.html - updating tabletItem:', receivedData.tabletItem);
|
||||
this.tabletItem = receivedData.tabletItem;
|
||||
if (receivedData.familyMembers) {
|
||||
this.familyMembers = receivedData.familyMembers; // 更新 familyMembers
|
||||
console.log("app mounted, window message: ", this.familyMembers, receivedData);
|
||||
}
|
||||
if (receivedData.tabletItem) {
|
||||
this.tabletItem = receivedData.tabletItem;
|
||||
}
|
||||
// 處理 f_num_tablet 資料
|
||||
if (this.tabletItem.f_num_tablet) {
|
||||
try {
|
||||
const data = JSON.parse(this.tabletItem.f_num_tablet);
|
||||
|
||||
if (this.item_type === 'B') {
|
||||
// B類型:超渡、超薦等
|
||||
this.family_deceased_Y_selected = data.mid_items || [];
|
||||
this.family_deceased_N_selected = data.left_items || [];
|
||||
|
||||
this.family_deceased_Y_selected.forEach(item => {
|
||||
if (item.IsShuWen === undefined) {
|
||||
Vue.set(item, 'IsShuWen', false);
|
||||
}
|
||||
});
|
||||
if (this.family_deceased_Y_selected.length > 0) {
|
||||
this.isAllSelected = this.family_deceased_Y_selected.every(member => member.IsShuWen === true);
|
||||
} else {
|
||||
this.isAllSelected = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// A類型:消災、陽上等
|
||||
this.family_deceased_Y_selected = [];
|
||||
this.family_deceased_N_selected = data.mid_items || [];
|
||||
|
||||
this.family_deceased_N_selected.forEach(item => {
|
||||
if (item.IsShuWen === undefined) {
|
||||
Vue.set(item, 'IsShuWen', false);
|
||||
}
|
||||
});
|
||||
if (this.family_deceased_Y_selected.length > 0) {
|
||||
this.isAllSelected = this.family_deceased_N_selected.every(member => member.IsShuWen === true);
|
||||
|
||||
} else {
|
||||
this.isAllSelected = false;
|
||||
}
|
||||
console.log(this.family_deceased_N_selected)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析牌位資料時發生錯誤:', e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
toggleSelectAll(checked) {
|
||||
this.isAllSelected = checked
|
||||
if (this.item_type === 'B') {
|
||||
this.family_deceased_Y_selected.forEach(member => {
|
||||
member.IsShuWen = checked;
|
||||
});
|
||||
}
|
||||
else if (this.item_type === 'A') {
|
||||
this.family_deceased_N_selected.forEach(member => {
|
||||
member.IsShuWen = checked;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
console.log(checked)
|
||||
console.log(this.family_deceased_N_selected)
|
||||
console.log(this.family_deceased_Y_selected)
|
||||
},
|
||||
addToSelected(member, type) {
|
||||
const selectedMember = {
|
||||
num: member.num,
|
||||
fam_name: member.fam_name,
|
||||
fam_gender: member.fam_gender,
|
||||
deceased: member.deceased,
|
||||
fam_title: member.fam_title, // 新增,讓上方顯示稱謂 tag
|
||||
option_break: false, // 默認為 false,根據需要可以更改
|
||||
IsShuWen: this.isAllSelected //是否加入疏文名單,默認false
|
||||
};
|
||||
console.log(this.isAllSelected)
|
||||
if (type === 'Y') {
|
||||
this.family_deceased_Y_selected.push(selectedMember);
|
||||
console.log(this.family_deceased_Y_selected)
|
||||
} else if (type === 'N') {
|
||||
this.family_deceased_N_selected.push(selectedMember);
|
||||
console.log(this.family_deceased_N_selected)
|
||||
}
|
||||
},
|
||||
removeFromSelected(member, type) {
|
||||
if (type === 'Y') {
|
||||
this.family_deceased_Y_selected.forEach(m => {
|
||||
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') {
|
||||
this.family_deceased_N_selected.forEach(m => {
|
||||
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) {
|
||||
if (index > 0) {
|
||||
const array = type === 'Y' ? this.family_deceased_Y_selected : this.family_deceased_N_selected;
|
||||
const temp = array[index - 1];
|
||||
this.$set(array, index - 1, member);
|
||||
this.$set(array, index, temp);
|
||||
}
|
||||
},
|
||||
moveDown(member, type, index) {
|
||||
if (index < (type === 'Y' ? this.family_deceased_Y_selected : this.family_deceased_N_selected).length - 1) {
|
||||
const array = type === 'Y' ? this.family_deceased_Y_selected : this.family_deceased_N_selected;
|
||||
const temp = array[index + 1];
|
||||
this.$set(array, index + 1, member);
|
||||
this.$set(array, index, temp);
|
||||
}
|
||||
},
|
||||
breakAfter(member, type) {
|
||||
console.log("breakAfter", member, type);
|
||||
member.option_break = !member.option_break;
|
||||
},
|
||||
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 = '';
|
||||
target.forEach((member, index) => {
|
||||
result += member.fam_name;
|
||||
// Add break if option_break is true and not the last item
|
||||
if (member.option_break && index < target.length - 1) {
|
||||
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>');
|
||||
|
||||
return result;
|
||||
},
|
||||
calculateTextStyle(text) {
|
||||
if (!text) return '--lines:1;--line_len:5';
|
||||
|
||||
const lines = text.split('<br>');
|
||||
const line_len = Math.max(...lines.map(line => {
|
||||
return Array.from(line).reduce((acc, char) => {
|
||||
// Full width (Chinese) characters
|
||||
if (char.match(/[\u4e00-\u9fa5]/)) {
|
||||
return acc + 1;
|
||||
}
|
||||
// Half width (English, numbers, etc.)
|
||||
return acc + 0.5;
|
||||
}, 0);
|
||||
}));
|
||||
|
||||
return `--lines:${lines.length};--line_len:${Math.ceil(line_len)}`;
|
||||
},
|
||||
saveData() {
|
||||
// 其它資料欄位, 不應在這裡修改
|
||||
// 應該在進來的時候, 就已經修改(insert)好了
|
||||
let tablet_data = {};
|
||||
if (this.item_type === 'B') {// B:超渡, 超薦.....
|
||||
tablet_data = {
|
||||
mid_items: this.family_deceased_Y_selected,
|
||||
left_items: this.family_deceased_N_selected
|
||||
}
|
||||
}
|
||||
else {// A:消災, 陽上.....
|
||||
tablet_data = {
|
||||
mid_items: this.family_deceased_N_selected,
|
||||
left_items: null
|
||||
}
|
||||
}
|
||||
console.log(tablet_data)
|
||||
const ret = {
|
||||
source: 'editor.btn.click',
|
||||
data: {
|
||||
tabletItem: this.tabletItem,
|
||||
tablet_data: tablet_data
|
||||
}
|
||||
};
|
||||
console.log("儲存牌位資料", ret);
|
||||
window.parent.postMessage(ret, '/');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
const desc_iframe = document.getElementById('desc_iframe');
|
||||
const btn = document.getElementById('btn');
|
||||
|
||||
//window.addEventListener('message', (event) => {
|
||||
// if (event.source === window.parent) {
|
||||
// let data = event.data;
|
||||
// if (data.source === 'order.btn.click') {
|
||||
// console.log('editor message', event.source, window.parent);
|
||||
// app.item = data;
|
||||
// console.log(app);
|
||||
// desc_iframe.value = JSON.stringify(data);
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
/*
|
||||
btn.addEventListener('click', () => {
|
||||
const ret = {
|
||||
source: 'editor.btn.click',
|
||||
desc: desc_iframe.value,
|
||||
}
|
||||
debugger;
|
||||
console.log("btn click", ret);
|
||||
window.parent.postMessage(ret, '/');
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
36
web/admin/print/tablet_edit/editor1.html
Normal file
36
web/admin/print/tablet_edit/editor1.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Editor1</h1>
|
||||
<div>
|
||||
<textarea id="desc_iframe" style="width: 500px; height: 300px;"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<button id="btn">save</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const desc_iframe = document.getElementById('desc_iframe');
|
||||
const btn = document.getElementById('btn');
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.source === window.parent) {
|
||||
desc_iframe.value = event.data;
|
||||
}
|
||||
});
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
const ret = {
|
||||
source: 'editor.btn.click',
|
||||
desc: desc_iframe.value,
|
||||
}
|
||||
window.parent.postMessage(ret, '/');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
50
web/admin/print/tablet_edit/index1.html
Normal file
50
web/admin/print/tablet_edit/index1.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Document</h1>
|
||||
<div>
|
||||
<textarea id="desc" style="width: 500px; height: 300px;">test</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<button id="btn">edit</button>
|
||||
</div>
|
||||
<hr>
|
||||
<div id="popup" style="display: none;">
|
||||
<div>
|
||||
<button id="close">close</button>
|
||||
</div>
|
||||
<iframe id="iframe" width="600" height="500" style="border: none;" src="editor1.html"></iframe>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const btn = document.getElementById('btn');
|
||||
const popup = document.getElementById('popup');
|
||||
const close = document.getElementById('close');
|
||||
const iframe = document.getElementById('iframe');
|
||||
const desc = document.getElementById('desc');
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
popup.style.display = 'block';
|
||||
iframe.contentWindow.postMessage(desc.value, '/');
|
||||
});
|
||||
|
||||
close.addEventListener('click', () => {
|
||||
popup.style.display = 'none';
|
||||
});
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
// 檢查是否為物件且來自 editor 的儲存操作
|
||||
if (typeof event.data === 'object' &&
|
||||
event.data.source === 'editor.btn.click') {
|
||||
desc.value = event.data.desc;
|
||||
popup.style.display = 'none';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
412
web/admin/print/tablet_edit/print.css
Normal file
412
web/admin/print/tablet_edit/print.css
Normal file
@@ -0,0 +1,412 @@
|
||||
/*頁面設定*/
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin: 0;
|
||||
orphans: 4;
|
||||
widows: 2;
|
||||
}
|
||||
|
||||
@page a3 {
|
||||
size: a3 portrait;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page a3l {
|
||||
size: a3 landscape;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page a4 {
|
||||
size: a4 portrait;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page a4l {
|
||||
size: a4 landscape;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page a5 {
|
||||
size: a5 portrait;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page a5l {
|
||||
size: a5 landscape;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page tablet-l {
|
||||
size: 274mm 392mm;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page tablet-m {
|
||||
size: 214mm 305mm;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@page tablet-s {
|
||||
size: 197mm 215mm;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.docs.editor { /*body*/
|
||||
--page-w: 250px;
|
||||
--page-h: 460px;
|
||||
--font-max: 22pt;
|
||||
--bg-padding: 0;
|
||||
font-family: 標楷體;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
margin: 0 auto;
|
||||
width: var(--page-w);
|
||||
height: var(--page-h);
|
||||
position: relative;
|
||||
page-break-inside: avoid;
|
||||
|
||||
outline: .25pt solid #0CC;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: var(--page-w);
|
||||
height: var(--page-h);
|
||||
/* outline: 0.25pt solid #000; */
|
||||
}
|
||||
|
||||
.border {
|
||||
/* outline: 0.25pt solid #000; */
|
||||
}
|
||||
|
||||
.text {}
|
||||
|
||||
pre {
|
||||
font-family: 標楷體;
|
||||
}
|
||||
|
||||
/*自動字型*/
|
||||
.text-block {
|
||||
/* border: .25pt solid #000; */
|
||||
/* margin: 5mm; */
|
||||
|
||||
font-family: 標楷體;
|
||||
text-align: start;
|
||||
vertical-align: middle;
|
||||
|
||||
/* --divw: 120mm; */
|
||||
/* --divh: 50mm; */
|
||||
--line_len: 10;
|
||||
--lines: 1;
|
||||
--fs_w: var(--divw)/var(--line_len);
|
||||
--fs_h: var(--divh)/var(--lines);
|
||||
--fs: min(var(--fs_w), var(--fs_h), var(--font-max));
|
||||
|
||||
width: var(--divw);
|
||||
height: var(--divh);
|
||||
|
||||
font-size: var(--fs);
|
||||
line-height: calc(var(--fs_h) * 1.0);
|
||||
|
||||
outline: 0.25pt solid #F00;
|
||||
}
|
||||
|
||||
.text-block.vertical {
|
||||
--fs_r: 0.97;
|
||||
--fs_w: var(--fs_r)*var(--divw)/var(--lines);
|
||||
--fs_h: var(--fs_r)*var(--divh)/var(--line_len);
|
||||
--fs: min(var(--fs_w), var(--fs_h), var(--font-max));
|
||||
line-height: calc(var(--fs_w) * 1.0);
|
||||
}
|
||||
|
||||
.vertical {
|
||||
writing-mode: vertical-rl;
|
||||
/*text-orientation: upright;*/
|
||||
text-orientation: mixed;
|
||||
}
|
||||
|
||||
.text-start {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-end {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.bg {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
padding: var(--bg-padding);
|
||||
}
|
||||
|
||||
.bg > svg,
|
||||
.bg > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.bg img {
|
||||
width: 100%;
|
||||
height: calc(var(--page-h) - var(--bg-padding) * 2);
|
||||
max-height: var(--page-h);
|
||||
/*outline: 0.25pt solid #000;*/
|
||||
}
|
||||
|
||||
.d-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.d-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.d-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.justify-content-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-content-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justify-content-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.justify-content-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.align-items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.align-items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.align-items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-start {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-end {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.h-100 {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.m-0 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.my-0 {
|
||||
margin-block-start: 0 !important;
|
||||
margin-block-end: 0 !important;
|
||||
}
|
||||
|
||||
.mx-0 {
|
||||
margin-inline-start: 0 !important;
|
||||
margin-inline-end: 0 !important;
|
||||
}
|
||||
|
||||
.mt-0 {
|
||||
margin-block-start: 0 !important;
|
||||
}
|
||||
|
||||
.mb-0 {
|
||||
margin-block-end: 0 !important;
|
||||
}
|
||||
|
||||
.ms-0 {
|
||||
margin-inline-start: 0 !important;
|
||||
}
|
||||
|
||||
.me-0 {
|
||||
margin-inline-end: 0 !important;
|
||||
}
|
||||
|
||||
.my-1 {
|
||||
margin-block-start: .25em !important;
|
||||
margin-block-end: .25em !important;
|
||||
}
|
||||
|
||||
.mx-1 {
|
||||
margin-inline-start: .25em !important;
|
||||
margin-inline-end: .25em !important;
|
||||
}
|
||||
|
||||
.mt-1 {
|
||||
margin-block-start: .25em !important;
|
||||
}
|
||||
|
||||
.mb-1 {
|
||||
margin-block-end: .25em !important;
|
||||
}
|
||||
|
||||
.ms-1 {
|
||||
margin-inline-start: .25em !important;
|
||||
}
|
||||
|
||||
.me-1 {
|
||||
margin-inline-end: .25em !important;
|
||||
}
|
||||
|
||||
.mid_text {
|
||||
--divw: 50mm;
|
||||
/* --divh: 220mm; */
|
||||
--divh: 200mm;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 54%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.mid_text_2 {
|
||||
--divw: 50mm;
|
||||
--divh: 50mm;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 18%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.right_text {
|
||||
--divw: 10mm;
|
||||
--divh: 260mm;
|
||||
position: absolute;
|
||||
right: 8mm;
|
||||
top: 80mm;
|
||||
}
|
||||
|
||||
.left_text {
|
||||
--divw: 20mm;
|
||||
--divh: 160mm;
|
||||
position: absolute;
|
||||
left: 0mm;
|
||||
top: 180mm;
|
||||
}
|
||||
|
||||
.txt_up,
|
||||
.txt_down {
|
||||
position: absolute;
|
||||
left: 5mm;
|
||||
|
||||
outline: .25pt solid #090;
|
||||
}
|
||||
|
||||
.txt_up {
|
||||
top: 155mm;
|
||||
}
|
||||
|
||||
.txt_down {
|
||||
bottom: 30mm;
|
||||
}
|
||||
|
||||
.top_text_1,
|
||||
.top_text_2,
|
||||
.top_text_3 {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.top_text_1 {
|
||||
top: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 20pt;
|
||||
}
|
||||
|
||||
.top_text_2,
|
||||
.top_text_3 {
|
||||
top: 2mm;
|
||||
top: 7mm;
|
||||
width: 60%;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.top_text_2 {
|
||||
text-align: right;
|
||||
right: 2mm;
|
||||
}
|
||||
|
||||
.top_text_3 {
|
||||
text-align: left;
|
||||
left: 2mm;
|
||||
}
|
||||
|
||||
.top_text_3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.docs.editor{
|
||||
font-size: 12px;
|
||||
& *{
|
||||
outline: 0 none !important;
|
||||
}
|
||||
& .content{
|
||||
--page-w: calc(460px * 0.3);
|
||||
--page-h: 460px;
|
||||
}
|
||||
& .bg{
|
||||
--bg-padding: 3px;
|
||||
}
|
||||
& .top_text_2,
|
||||
& .top_text_3 {
|
||||
top: 0;
|
||||
width: 60%;
|
||||
font-size: 9px;
|
||||
}
|
||||
& .top_text_2 {
|
||||
right: 0;
|
||||
}
|
||||
& .mid_text {
|
||||
--divw: 65px;
|
||||
--divh: 260px;
|
||||
}
|
||||
& .mid_text_2{
|
||||
display: none;
|
||||
}
|
||||
& .right_text {
|
||||
display: none;
|
||||
}
|
||||
& .txt_up {
|
||||
top: 200px;
|
||||
}
|
||||
& .txt_down {
|
||||
bottom: 62px;
|
||||
}
|
||||
& .txt_up,
|
||||
& .txt_down {
|
||||
left: 4px;
|
||||
}
|
||||
& .left_text {
|
||||
--divw: 25px;
|
||||
--divh: 140px;
|
||||
position: absolute;
|
||||
left: 0mm;
|
||||
top: 62mm;
|
||||
}
|
||||
}
|
||||
56
web/admin/print/tablet_edit/sample.json
Normal file
56
web/admin/print/tablet_edit/sample.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": 26,
|
||||
"num": 10024,
|
||||
"order_no": "AA2412210001",
|
||||
"actitem_num_selected": {
|
||||
"text": "消災-大牌位",
|
||||
"val": 1241
|
||||
},
|
||||
"parent_num": 10020,
|
||||
"f_num_selected": {
|
||||
"text": "",
|
||||
"val": 0
|
||||
},
|
||||
"f_num_tablet": " 朱 惠 慈",
|
||||
"print_id": "副懺主XA0011-4",
|
||||
"address": null,
|
||||
"due_date": null,
|
||||
"start_date": null,
|
||||
"extend_date": null,
|
||||
"from_id_selected": {
|
||||
"text": "",
|
||||
"val": 0
|
||||
},
|
||||
"from_id_tablet": null,
|
||||
"price": 0,
|
||||
"qty": 1,
|
||||
"writeBedQty": 0,
|
||||
"notBedQty": 0,
|
||||
"category": 1,
|
||||
"pay": 0,
|
||||
"pay_date": null,
|
||||
"keyin1_selected": {
|
||||
"text": "未收款",
|
||||
"val": 1
|
||||
},
|
||||
"demo": "",
|
||||
"files": [
|
||||
{
|
||||
"num": 25,
|
||||
"subject": "[標準L1A]大牌位-佛光注照-長生祿位-A3(直)",
|
||||
"word": "<div class=\"page border\" data-body-class=\"tblt-l a3\">\r\n<div class=\"content\">\r\n<div class=\"bg\"><img alt=\"Alternate Text\" src=\"./tablet-2.svg\" /></div>\r\n\r\n<div class=\"text\">\r\n<div class=\"top_text_1\">{$牌位主標題}</div>\r\n\r\n<div class=\"top_text_2\">{orderItem.print_id}</div>\r\n\r\n<div class=\"top_text_3\">個</div>\r\n\r\n<div class=\"right_text text-block fit-text vertical text-start border\">{$右標題}</div>\r\n\r\n<div class=\"mid_text text-block fit-text vertical border\" style=\"{$mid_text_style}\">{orderItem.f_num_tablet}</div>\r\n\r\n<div class=\"mid_text_2 text-block fit-text vertical border\">{$祈福姓名2}</div>\r\n\r\n<div class=\"left_text text-block fit-text vertical text-start border\" style=\"{$left_text_style}\">{orderItem.from_id_tablet}</div>\r\n\r\n<div class=\"txt_up vertical\"> </div>\r\n\r\n<div class=\"txt_down vertical\"> </div>\r\n</div>\r\n</div>\r\n</div>\r\n",
|
||||
"cuz_column": "$牌位主標題:\r\n$牌位副標題:\r\n$右標題:\r\n$祈福姓名:\r\n$祈福姓名2:\r\n$陽上姓名:\r\n$編號:",
|
||||
"paperset": "tblt-l a3"
|
||||
}
|
||||
],
|
||||
"customize_data": "",
|
||||
"customize_data_comb": {
|
||||
"from_id_cuz_data": "",
|
||||
"activity_cuz_data": "",
|
||||
"actitem_cuz_data": "",
|
||||
"order_cuz_data": ""
|
||||
},
|
||||
"printed_files": "\"25\",",
|
||||
"isPackage": 0,
|
||||
"bom_order": "1002010024"
|
||||
}
|
||||
Reference in New Issue
Block a user