updated
This commit is contained in:
parent
9ab3001ff0
commit
f68c4af30b
6 changed files with 261 additions and 34 deletions
151
src/modules/05_command/components/FormTemplate.vue
Normal file
151
src/modules/05_command/components/FormTemplate.vue
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { watch, ref } from "vue";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useDataStore } from "@/modules/05_command/stores/main";
|
||||||
|
|
||||||
|
const $q = useQuasar();
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const {
|
||||||
|
dialogConfirm,
|
||||||
|
success,
|
||||||
|
showLoader,
|
||||||
|
hideLoader,
|
||||||
|
dialogRemove,
|
||||||
|
messageError,
|
||||||
|
} = mixin;
|
||||||
|
const store = useDataStore();
|
||||||
|
|
||||||
|
const commandId = defineModel<string>("commandId", { required: true });
|
||||||
|
const type = defineModel<string>("type", { required: true });
|
||||||
|
|
||||||
|
const textHeader = ref<string>("");
|
||||||
|
const textBody = ref<string>("");
|
||||||
|
const textFooter = ref<string>("");
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
textHeader.value = "";
|
||||||
|
textBody.value = "";
|
||||||
|
textFooter.value = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSave = () => {
|
||||||
|
console.log("textHeader===>", textHeader.value);
|
||||||
|
console.log("textBody===>", textBody.value);
|
||||||
|
console.log("textFooter===>", textFooter.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
function clearFormat(type: string) {
|
||||||
|
switch (type) {
|
||||||
|
case "textHeader":
|
||||||
|
textHeader.value = textHeader.value.replace(/<\/?[^>]+(>|$)/g, "");
|
||||||
|
break;
|
||||||
|
case "textBody":
|
||||||
|
textBody.value = textBody.value.replace(/<\/?[^>]+(>|$)/g, "");
|
||||||
|
break;
|
||||||
|
case "textFooter":
|
||||||
|
textFooter.value = textFooter.value.replace(/<\/?[^>]+(>|$)/g, "");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleInput = (event: any, type: string) => {
|
||||||
|
if (event.inputType === "insertFromPaste") {
|
||||||
|
clearFormat(type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => commandId.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue && newValue !== oldValue) {
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-card>
|
||||||
|
<q-card-section class="q-pt-none">
|
||||||
|
<div class="row items-center q-col-gutter-sm">
|
||||||
|
<div class="col-12">
|
||||||
|
<q-label>เนื้อหาคำสั่งส่วนต้น</q-label>
|
||||||
|
<q-field
|
||||||
|
class="q_field_p_none"
|
||||||
|
ref="fieldRef"
|
||||||
|
v-model="textHeader"
|
||||||
|
borderless
|
||||||
|
hide-bottom-space
|
||||||
|
>
|
||||||
|
<template #control>
|
||||||
|
<q-editor
|
||||||
|
class="full-width"
|
||||||
|
v-model="textHeader"
|
||||||
|
min-height="5rem"
|
||||||
|
:toolbar="store.toolbarOptions"
|
||||||
|
@input="(e:any) => handleInput(e, 'textHeader')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<q-label>เนื้อหาคำสั่งส่วนกลาง</q-label>
|
||||||
|
<q-field
|
||||||
|
class="q_field_p_none"
|
||||||
|
ref="fieldRef"
|
||||||
|
v-model="textBody"
|
||||||
|
borderless
|
||||||
|
hide-bottom-space
|
||||||
|
>
|
||||||
|
<template #control>
|
||||||
|
<q-editor
|
||||||
|
class="full-width"
|
||||||
|
v-model="textBody"
|
||||||
|
min-height="5rem"
|
||||||
|
:toolbar="store.toolbarOptions"
|
||||||
|
@input="(e:any) => handleInput(e, 'textBody')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<q-label>เนื้อหาคำสั่งส่วนท้าย</q-label>
|
||||||
|
<q-field
|
||||||
|
class="q_field_p_none"
|
||||||
|
ref="fieldRef"
|
||||||
|
v-model="textFooter"
|
||||||
|
borderless
|
||||||
|
hide-bottom-space
|
||||||
|
>
|
||||||
|
<template #control>
|
||||||
|
<q-editor
|
||||||
|
class="full-width"
|
||||||
|
v-model="textFooter"
|
||||||
|
min-height="5rem"
|
||||||
|
:toolbar="store.toolbarOptions"
|
||||||
|
@input="(e:any) => handleInput(e, 'textFooter')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section align="right">
|
||||||
|
<q-btn
|
||||||
|
for="#submitForm"
|
||||||
|
unelevated
|
||||||
|
dense
|
||||||
|
class="q-px-md items-center"
|
||||||
|
color="light-blue-10"
|
||||||
|
label="บันทึก"
|
||||||
|
@click="onSave"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</template>
|
||||||
|
|
@ -4,8 +4,10 @@ import { VuePDF, usePDF } from "@tato30/vue-pdf";
|
||||||
import { useQuasar } from "quasar";
|
import { useQuasar } from "quasar";
|
||||||
import { useCounterMixin } from "@/stores/mixin";
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
|
||||||
import http from "@/plugins/http";
|
|
||||||
import config from "@/app.config";
|
import config from "@/app.config";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
// import genReport from "@/plugins/genreport";
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const mixin = useCounterMixin();
|
const mixin = useCounterMixin();
|
||||||
|
|
@ -48,25 +50,77 @@ function backPage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const showDocument = (url: any) => {
|
function replaceAllTag(html: string) {
|
||||||
const pdfData = usePDF(url);
|
return html.replace("div", "p");
|
||||||
setTimeout(() => {
|
}
|
||||||
pdfSrc.value = pdfData.pdf.value;
|
|
||||||
numOfPages.value = pdfData.pages.value;
|
async function fetchDocumentTemplate() {
|
||||||
}, 1000);
|
showLoader();
|
||||||
};
|
let textEditHeader = "";
|
||||||
|
let textEditBody = "";
|
||||||
|
let textEditFooter = "";
|
||||||
|
textEditHeader +=
|
||||||
|
"อาศัยอำนาจตามความในมาตรา ๔๔ และมาตรา ๕๒ (๔) แห่งพระราชบัญญัติระเบียบข้าราชการ-กรุงเทพมหานครและบุคลากรกรุงเทพมหานคร พ.ศ. ๒๕๕๔ ประกอบกับกฎ ก.ก. ว่าด้วยการทดลองปฏิบัติ-หน้าที่ราชการและการพัฒนาข้าราชการกรุงเทพมหานครสามัญที่อยู่ระหว่างทดลองปฏิบัติหน้าที่ราชการ พ.ศ. ๒๕๕๕ มติคณะกรรมการข้าราชการกรุงเทพมหานครและบุคลากรกรุงเทพมหานคร ครั้งที่ ๑/๒๕๕๔ เมื่อวันที่ ๒๒ ธันวาคม ๒๕๕๔ มติ อ.ก.ก. วิสามัญเกี่ยวกับระบบราชการ การจัดส่วนราชการ และค่าตอบแทน ครั้งที่ ๙/๒๕๕๖";
|
||||||
|
|
||||||
|
textEditBody +=
|
||||||
|
"เมื่อวันที่ ๑๘ กันยายน ๒๕๕๖ ประกาศผลการสอบแข่งขันสำนักงานคณะกรรมการ-ข้าราชการกรุงเทพมหานคร ครั้งที่ ๑/๒๕๖๔ ลงวันที่ ๒๙ เมษายน ๒๕๖๕ ตำแหน่งนักทรัพยากรบุคคลปฏิบัติการ จึงบรรจุและแต่งตั้งผู้สอบแข่งขันได้เข้ารับราชการเป็นข้าราชการกรุงเทพมหานครสามัญ และแต่งตั้งให้ดำรงตำแหน่งนักทรัพยากรบุคคลปฏิบัติการ จำนวน ๔ ราย";
|
||||||
|
|
||||||
|
textEditFooter += "ดังบัญชีรายละเอียดแนบท้ายคำสั่งนี้";
|
||||||
|
const data = await {
|
||||||
|
template: "command_test",
|
||||||
|
reportName: "docx-report",
|
||||||
|
data: {
|
||||||
|
commandNo: "๑๒",
|
||||||
|
commandYear: "๒๕๖๗",
|
||||||
|
commandTitle: "บรรจุและแต่งตั้งผู้สอบแข่งขันได้",
|
||||||
|
detailHeader: textEditHeader,
|
||||||
|
detailBody:
|
||||||
|
'<meta charset="UTF-8"><body><p style="font-family: \'TH Sarabun Psk\'; font-size: 16pt;">' +
|
||||||
|
replaceAllTag(textEditBody) +
|
||||||
|
"</p></body>",
|
||||||
|
detailFooter:
|
||||||
|
'<meta charset="UTF-8"><body><p style="font-family: \'TH Sarabun Psk\'; font-size: 16pt;">' +
|
||||||
|
replaceAllTag(textEditFooter) +
|
||||||
|
"</p></body>",
|
||||||
|
commandDate: "๑ สิงหาคม ๒๕๖๗",
|
||||||
|
name: "Admin Administrator",
|
||||||
|
position: "Admin Administrator",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// genReport(data, `คำสั่ง`);
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.post(config.API.reportTemplate + `/docx/html`, data, {
|
||||||
|
headers: {
|
||||||
|
accept: "application/pdf",
|
||||||
|
"content-Type": "application/json",
|
||||||
|
},
|
||||||
|
responseType: "blob",
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
const blob = new Blob([res.data]);
|
||||||
|
const objectUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const pdfData = await usePDF(`${objectUrl}`);
|
||||||
|
showLoader();
|
||||||
|
setTimeout(() => {
|
||||||
|
pdfSrc.value = pdfData.pdf.value;
|
||||||
|
numOfPages.value = pdfData.pages.value;
|
||||||
|
hideLoader();
|
||||||
|
}, 1500);
|
||||||
|
})
|
||||||
|
.catch(async (e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
hideLoader();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => idOrder.value,
|
() => idOrder.value,
|
||||||
(newValue, oldValue) => {
|
(newValue, oldValue) => {
|
||||||
if (newValue && newValue !== oldValue) {
|
if (newValue && newValue !== oldValue) {
|
||||||
showLoader();
|
fetchDocumentTemplate();
|
||||||
setTimeout(() => {
|
|
||||||
const url =
|
|
||||||
"https://s3cluster.frappet.com/public/template-command.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=A3O4SZ1Q1L0A2SPWLMDY%2F20240909%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240909T064638Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJBM080U1oxUTFMMEEyU1BXTE1EWSIsImV4cCI6MTcyNTkwNzE4MiwicGFyZW50IjoiZnJhcHBldCJ9.4opHdRH9VegUbtcHsIucy-SpWyboCcuhg2jjtLT4Ypvg2Yg8WvvLoyL92-IabqEYlNvv_sMJMa7P8oQkMqpsSA&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=fce8a76e6d5d3e83eac102402b07ba2a8ac8c2a1e0a055f1d8a5ecc74434c0e0";
|
|
||||||
showDocument(url);
|
|
||||||
hideLoader();
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|
@ -81,7 +135,7 @@ watch(
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
v-model="documentFile"
|
v-model="documentFile"
|
||||||
label="ไฟล์เอกสารหลักฐาน"
|
:label="`ไฟล์ต้นแบบ${type == 'order' ? 'คำสั่ง' : 'บัญชีแนบท้าย'}`"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
:accept="type == 'order' ? '.docx' : '.pdf'"
|
:accept="type == 'order' ? '.docx' : '.pdf'"
|
||||||
clearable
|
clearable
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ interface Pagination {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ActiveOptions {
|
interface ActiveOptions {
|
||||||
value: string;
|
value: boolean;
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,13 @@ import { ref } from "vue";
|
||||||
|
|
||||||
export const useDataStore = defineStore("commandStore", () => {
|
export const useDataStore = defineStore("commandStore", () => {
|
||||||
const currentTab = ref<string>("order");
|
const currentTab = ref<string>("order");
|
||||||
|
const toolbarOptions = ref([
|
||||||
|
["left", "center", "right", "justify"],
|
||||||
|
["token", "bold", "italic", "underline", "subscript", "superscript"],
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentTab
|
currentTab,
|
||||||
|
toolbarOptions,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import type {
|
||||||
|
|
||||||
import Header from "@/components/DialogHeader.vue";
|
import Header from "@/components/DialogHeader.vue";
|
||||||
import PageOrder from "@/modules/05_command/components/ViewPdf.vue";
|
import PageOrder from "@/modules/05_command/components/ViewPdf.vue";
|
||||||
|
import TemplateDetail from "@/modules/05_command/components/FormTemplate.vue";
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const mixin = useCounterMixin();
|
const mixin = useCounterMixin();
|
||||||
|
|
@ -28,18 +29,20 @@ const {
|
||||||
messageError,
|
messageError,
|
||||||
} = mixin;
|
} = mixin;
|
||||||
|
|
||||||
const inActive = ref<string>(""); //Select Active/InActive
|
const isActive = ref<string>(""); // สถานะของรายการคำสั่ง
|
||||||
|
// options สถานะการใช้งาน
|
||||||
const activeOptions = ref<ActiveOptions[]>([
|
const activeOptions = ref<ActiveOptions[]>([
|
||||||
{
|
{
|
||||||
value: "Active",
|
value: true,
|
||||||
label: "Active",
|
label: "Active",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "InActive",
|
value: false,
|
||||||
label: "InActive",
|
label: "InActive",
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Tabs
|
||||||
const tabs = ref<Tabs[]>([
|
const tabs = ref<Tabs[]>([
|
||||||
{
|
{
|
||||||
value: "order",
|
value: "order",
|
||||||
|
|
@ -49,25 +52,32 @@ const tabs = ref<Tabs[]>([
|
||||||
value: "account",
|
value: "account",
|
||||||
label: "บัญชีแนบท้าย",
|
label: "บัญชีแนบท้าย",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: "template",
|
||||||
|
label: "ข้อความต้นแบบ",
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const idOrder = ref<string>("");
|
const idOrder = ref<string>(""); // Id คำสั่ง
|
||||||
const activeOrderId = ref<string>("");
|
const activeOrderId = ref<string>(""); // Id คำสั่งที่เลือก
|
||||||
const name = ref<string>(""); // ชื่อคำสั่ง
|
const name = ref<string>(""); // ชื่อคำสั่ง
|
||||||
const listOrder = ref<ListOrder[]>([]); // list คำสั่ง
|
const listOrder = ref<ListOrder[]>([]); // list คำสั่ง
|
||||||
const status = ref<boolean>(false); // สถานะ
|
const status = ref<boolean>(false); // สถานะ
|
||||||
const isEdit = ref<boolean>(false); //เก็บ true/false เช็คแก้ไข
|
const isEdit = ref<boolean>(false); //เก็บ true/false เช็คแก้ไข
|
||||||
const modelDialogActive = ref<boolean>(false); // model คำสั่ง
|
const dialogFormCommand = ref<boolean>(false); // model คำสั่ง
|
||||||
|
|
||||||
/** search Active / InActive */
|
/**
|
||||||
function searchActive(val: string) {
|
* ฟังก์ชั่นค้นหาคำสั่ง ตามสถานะ
|
||||||
|
* @param val สถานะ true/false
|
||||||
|
*/
|
||||||
|
function searchByStatus(val: string) {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** เปิด dialog */
|
/** เปิด dialog */
|
||||||
function onDialogAdd() {
|
function onDialogAdd() {
|
||||||
isEdit.value = false;
|
isEdit.value = false;
|
||||||
modelDialogActive.value = true;
|
dialogFormCommand.value = true;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* เปิด dialog Edit
|
* เปิด dialog Edit
|
||||||
|
|
@ -79,7 +89,7 @@ function onDialogEdit(data: ListOrder) {
|
||||||
status.value = data.status;
|
status.value = data.status;
|
||||||
|
|
||||||
isEdit.value = true;
|
isEdit.value = true;
|
||||||
modelDialogActive.value = true;
|
dialogFormCommand.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -102,7 +112,7 @@ function onDelete(id: string) {
|
||||||
function closeDialog() {
|
function closeDialog() {
|
||||||
idOrder.value = "";
|
idOrder.value = "";
|
||||||
isEdit.value = false;
|
isEdit.value = false;
|
||||||
modelDialogActive.value = false;
|
dialogFormCommand.value = false;
|
||||||
name.value = "";
|
name.value = "";
|
||||||
status.value = false;
|
status.value = false;
|
||||||
}
|
}
|
||||||
|
|
@ -174,14 +184,14 @@ onMounted(() => {
|
||||||
<q-select
|
<q-select
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
v-model="inActive"
|
v-model="isActive"
|
||||||
class="inputgreen"
|
class="inputgreen"
|
||||||
label="สถานะการใช้งาน"
|
label="สถานะการใช้งาน"
|
||||||
:options="activeOptions"
|
:options="activeOptions"
|
||||||
option-label="label"
|
option-label="label"
|
||||||
option-value="value"
|
option-value="value"
|
||||||
emit-value
|
emit-value
|
||||||
@update:model-value="searchActive"
|
@update:model-value="searchByStatus"
|
||||||
></q-select>
|
></q-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -294,6 +304,12 @@ onMounted(() => {
|
||||||
:id-order="activeOrderId"
|
:id-order="activeOrderId"
|
||||||
/>
|
/>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
<q-tab-panel name="template">
|
||||||
|
<TemplateDetail
|
||||||
|
v-model:type="store.currentTab"
|
||||||
|
:command-id="activeOrderId"
|
||||||
|
/>
|
||||||
|
</q-tab-panel>
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
</div>
|
</div>
|
||||||
<div v-else style="height: auto; max-width: 100%; max-height: 90vh">
|
<div v-else style="height: auto; max-width: 100%; max-height: 90vh">
|
||||||
|
|
@ -315,11 +331,11 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-dialog v-model="modelDialogActive" persistent>
|
<q-dialog v-model="dialogFormCommand" persistent>
|
||||||
<q-card class="col-12" style="min-width: 30%">
|
<q-card class="col-12" style="min-width: 30%">
|
||||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||||
<Header
|
<Header
|
||||||
:tittle="isEdit ? 'แก้ไขข้อมูลคำสั่ง' : 'เพิ่มข้อมูลคำสั่ง'"
|
:tittle="isEdit ? 'แก้ไขคำสั่ง' : 'เพิ่มคำสั่ง'"
|
||||||
:close="closeDialog"
|
:close="closeDialog"
|
||||||
/>
|
/>
|
||||||
<q-separator />
|
<q-separator />
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const { showLoader, hideLoader, messageError } = mixin;
|
||||||
async function genReport(data: any, fileName: string, type: string = "docx") {
|
async function genReport(data: any, fileName: string, type: string = "docx") {
|
||||||
showLoader();
|
showLoader();
|
||||||
await axios
|
await axios
|
||||||
.post(`${config.API.reportTemplate}/docx`, data, {
|
.post(`${config.API.reportTemplate}/docx/html`, data, {
|
||||||
headers:
|
headers:
|
||||||
type == "docx"
|
type == "docx"
|
||||||
? {
|
? {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue