This commit is contained in:
Warunee Tamkoo 2024-09-11 18:06:04 +07:00
parent 9ab3001ff0
commit f68c4af30b
6 changed files with 261 additions and 34 deletions

View 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>

View file

@ -4,8 +4,10 @@ import { VuePDF, usePDF } from "@tato30/vue-pdf";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import axios from "axios";
// import genReport from "@/plugins/genreport";
const $q = useQuasar();
const mixin = useCounterMixin();
@ -48,25 +50,77 @@ function backPage() {
}
}
const showDocument = (url: any) => {
const pdfData = usePDF(url);
setTimeout(() => {
pdfSrc.value = pdfData.pdf.value;
numOfPages.value = pdfData.pages.value;
}, 1000);
};
function replaceAllTag(html: string) {
return html.replace("div", "p");
}
async function fetchDocumentTemplate() {
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(
() => idOrder.value,
(newValue, oldValue) => {
if (newValue && newValue !== oldValue) {
showLoader();
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);
fetchDocumentTemplate();
}
},
{ immediate: true }
@ -81,7 +135,7 @@ watch(
outlined
dense
v-model="documentFile"
label="ไฟล์เอกสารหลักฐาน"
:label="`ไฟล์ต้นแบบ${type == 'order' ? 'คำสั่ง' : 'บัญชีแนบท้าย'}`"
hide-bottom-space
:accept="type == 'order' ? '.docx' : '.pdf'"
clearable

View file

@ -3,7 +3,7 @@ interface Pagination {
}
interface ActiveOptions {
value: string;
value: boolean;
label: string;
}

View file

@ -3,7 +3,13 @@ import { ref } from "vue";
export const useDataStore = defineStore("commandStore", () => {
const currentTab = ref<string>("order");
const toolbarOptions = ref([
["left", "center", "right", "justify"],
["token", "bold", "italic", "underline", "subscript", "superscript"],
]);
return {
currentTab
currentTab,
toolbarOptions,
};
});

View file

@ -15,6 +15,7 @@ import type {
import Header from "@/components/DialogHeader.vue";
import PageOrder from "@/modules/05_command/components/ViewPdf.vue";
import TemplateDetail from "@/modules/05_command/components/FormTemplate.vue";
const $q = useQuasar();
const mixin = useCounterMixin();
@ -28,18 +29,20 @@ const {
messageError,
} = mixin;
const inActive = ref<string>(""); //Select Active/InActive
const isActive = ref<string>(""); //
// options
const activeOptions = ref<ActiveOptions[]>([
{
value: "Active",
value: true,
label: "Active",
},
{
value: "InActive",
value: false,
label: "InActive",
},
]);
// Tabs
const tabs = ref<Tabs[]>([
{
value: "order",
@ -49,25 +52,32 @@ const tabs = ref<Tabs[]>([
value: "account",
label: "บัญชีแนบท้าย",
},
{
value: "template",
label: "ข้อความต้นแบบ",
},
]);
const idOrder = ref<string>("");
const activeOrderId = ref<string>("");
const idOrder = ref<string>(""); // Id
const activeOrderId = ref<string>(""); // Id
const name = ref<string>(""); //
const listOrder = ref<ListOrder[]>([]); // list
const status = ref<boolean>(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);
}
/** เปิด dialog */
function onDialogAdd() {
isEdit.value = false;
modelDialogActive.value = true;
dialogFormCommand.value = true;
}
/**
* เป dialog Edit
@ -79,7 +89,7 @@ function onDialogEdit(data: ListOrder) {
status.value = data.status;
isEdit.value = true;
modelDialogActive.value = true;
dialogFormCommand.value = true;
}
/**
@ -102,7 +112,7 @@ function onDelete(id: string) {
function closeDialog() {
idOrder.value = "";
isEdit.value = false;
modelDialogActive.value = false;
dialogFormCommand.value = false;
name.value = "";
status.value = false;
}
@ -174,14 +184,14 @@ onMounted(() => {
<q-select
outlined
dense
v-model="inActive"
v-model="isActive"
class="inputgreen"
label="สถานะการใช้งาน"
:options="activeOptions"
option-label="label"
option-value="value"
emit-value
@update:model-value="searchActive"
@update:model-value="searchByStatus"
></q-select>
</div>
</div>
@ -294,6 +304,12 @@ onMounted(() => {
:id-order="activeOrderId"
/>
</q-tab-panel>
<q-tab-panel name="template">
<TemplateDetail
v-model:type="store.currentTab"
:command-id="activeOrderId"
/>
</q-tab-panel>
</q-tab-panels>
</div>
<div v-else style="height: auto; max-width: 100%; max-height: 90vh">
@ -315,11 +331,11 @@ onMounted(() => {
</div>
</div>
<q-dialog v-model="modelDialogActive" persistent>
<q-dialog v-model="dialogFormCommand" persistent>
<q-card class="col-12" style="min-width: 30%">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<Header
:tittle="isEdit ? 'แก้ไขข้อมูลคำสั่ง' : 'เพิ่มข้อมูลคำสั่ง'"
:tittle="isEdit ? 'แก้ไขคำสั่ง' : 'เพิ่มคำสั่ง'"
:close="closeDialog"
/>
<q-separator />

View file

@ -12,7 +12,7 @@ const { showLoader, hideLoader, messageError } = mixin;
async function genReport(data: any, fileName: string, type: string = "docx") {
showLoader();
await axios
.post(`${config.API.reportTemplate}/docx`, data, {
.post(`${config.API.reportTemplate}/docx/html`, data, {
headers:
type == "docx"
? {