updated format code

This commit is contained in:
Warunee Tamkoo 2024-09-03 11:28:01 +07:00
parent b75d69ea08
commit b14bad2249
241 changed files with 14012 additions and 13811 deletions

View file

@ -530,7 +530,6 @@ const pagination = ref({
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
@ -606,7 +605,6 @@ const pagination = ref({
<q-td v-for="col in props.cols" :key="col.name" :props="props">{{
col.name == "no" ? props.rowIndex + 1 : col.value
}}</q-td>
</q-tr>
</template>
</d-table>

View file

@ -503,7 +503,6 @@ const updateData = (row: DataCopyOrder) => {
</template>
</q-select>
</q-td>
</q-tr>
</template>
</d-table>

File diff suppressed because it is too large Load diff

View file

@ -1,316 +1,316 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import config from "@/app.config";
import http from "@/plugins/http";
/** importType*/
import type { QTableProps } from "quasar";
import type { NewPagination } from "@/modules/13_salary/interface/index/Main";
import type { DataFilterPerson } from "@/modules/13_salary/interface/index/SalaryList";
import type { DataPersonReq } from "@/modules/13_salary/interface/request/SalaryList";
import type { DataPerson } from "@/modules/13_salary/interface/response/SalaryList";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const { messageError, showLoader, hideLoader, dialogConfirm, success } =
useCounterMixin();
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const props = defineProps({
fetchData: {
type: Function,
},
});
/** Table*/
const columns = ref<QTableProps["columns"]>([
{
name: "no",
align: "left",
label: "ลำดับ",
sortable: false,
field: "no",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "citizenId",
align: "left",
label: "เลขประจำตัวประชาชน",
sortable: true,
field: "citizenId",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "fullName",
align: "left",
label: "ชื่อ-นามสกุล",
field: "fullName",
sortable: true,
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "position",
align: "left",
label: "ตำแหน่งในสายงาน",
sortable: true,
field: "position",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posType",
align: "left",
label: "ประเภทตำเเหน่ง",
sortable: true,
field: "posType",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posLevel",
align: "left",
label: "ระดับตำเเหน่ง",
sortable: true,
field: "posLevel",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
const rows = ref<DataPerson[]>([]);
/** ข้อมูุลค้นหา*/
const formFilter = reactive<DataFilterPerson>({
page: 1,
pageSize: 10,
keyword: "",
rootId: "",
year: 0,
period: "",
});
const maxPage = ref<number>(1);
/** function close popup*/
function closeModal() {
modal.value = false;
formFilter.page = 1;
formFilter.keyword = "";
}
/** function เรียกรายชื่อ คนเลื่อนเงินเดือน*/
function fetchListPerson() {
showLoader();
formFilter.rootId = store.rootId;
formFilter.period = store.roundMainCode;
formFilter.year = store.roundYear;
http
.post(config.API.salaryListPerson, formFilter)
.then((res) => {
const data = res.data.result.data;
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
rows.value = data;
})
.catch((err) => {
messageError($q, err);
closeModal();
})
.finally(() => {
hideLoader();
});
}
/**
* function นยนการเพมคนเลอนเงนเดอน
* @param data อมลคนทเพ
*/
function onClickAddPerson(data: DataPerson) {
const body: DataPersonReq = {
id: store.groupId,
type: store.tabType,
...data,
};
dialogConfirm(
$q,
() => {
showLoader();
http
.post(config.API.salaryPeriodProfile, body)
.then(async () => {
await props.fetchData?.();
await success($q, "เพื่มรายชื่อสำเร็จ");
closeModal();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการเพิ่มรายชื่อ",
"ต้องการยืนยันการเพิ่มรายชื่อนี้ใช่หรือไม่?"
);
}
/** function updatePage*/
async function updatePagePagination() {
fetchListPerson();
}
/** function updatePageSize*/
function updatePageSizePagination(newPagination: NewPagination) {
formFilter.page = 1;
formFilter.pageSize = newPagination.rowsPerPage;
}
/** function ค้นหาข้อมูลตาม keyword*/
function searchData() {
formFilter.page = 1;
fetchListPerson();
}
/** callblack function เรียกข้อมูลรายชื่อคนเลื่อนเงินเดือน เมื่อมีการเปิด Popup*/
watch(
() => modal.value,
() => {
if (modal.value) {
fetchListPerson();
}
}
);
/** callblack function เรียกข้อมูลรายชื่อคนเลื่อนเงินเดือน เมื่อมีการเปลี่ยน PageSize*/
watch(
() => formFilter.pageSize,
() => {
updatePagePagination();
}
);
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card style="max-width: 100vw">
<Header :tittle="'เพิ่มคนเลื่อนเงินเดือน'" :close="closeModal" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-input
borderless
dense
debounce="300"
outlined
placeholder="ค้นหา"
v-model="formFilter.keyword"
@keydown.enter.prevent="searchData"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
</div>
<div class="col-12">
<d-table
ref="table"
:columns="columns"
:rows="rows"
row-key="id"
flat
bordered
:paging="true"
dense
:rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePageSizePagination"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width></q-th>
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<q-btn
outline
color="primary"
label="เพิ่ม"
@click="onClickAddPerson(props.row)"
/>
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<div v-if="col.name === 'no'">
{{
(formFilter.page - 1) * formFilter.pageSize +
props.rowIndex +
1
}}
</div>
<div v-else-if="col.name === 'fullName'">
{{
`${props.row.prefix}${props.row.firstName} ${props.row.lastName}`
}}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope">
<q-pagination
v-model="formFilter.page"
active-color="primary"
color="dark"
:max="Number(maxPage)"
:max-pages="5"
size="sm"
boundary-links
direction-links
@update:model-value="updatePagePagination()"
></q-pagination>
</template>
</d-table>
</div>
</div>
</q-card-section>
<q-separator />
<!-- <q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
unelevated
dense
class="q-px-md items-center"
color="light-blue-10"
label="บันทึก"
/>
</q-card-actions> -->
</q-card>
</q-dialog>
</template>
<style scoped></style>
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import config from "@/app.config";
import http from "@/plugins/http";
/** importType*/
import type { QTableProps } from "quasar";
import type { NewPagination } from "@/modules/13_salary/interface/index/Main";
import type { DataFilterPerson } from "@/modules/13_salary/interface/index/SalaryList";
import type { DataPersonReq } from "@/modules/13_salary/interface/request/SalaryList";
import type { DataPerson } from "@/modules/13_salary/interface/response/SalaryList";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const { messageError, showLoader, hideLoader, dialogConfirm, success } =
useCounterMixin();
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const props = defineProps({
fetchData: {
type: Function,
},
});
/** Table*/
const columns = ref<QTableProps["columns"]>([
{
name: "no",
align: "left",
label: "ลำดับ",
sortable: false,
field: "no",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "citizenId",
align: "left",
label: "เลขประจำตัวประชาชน",
sortable: true,
field: "citizenId",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "fullName",
align: "left",
label: "ชื่อ-นามสกุล",
field: "fullName",
sortable: true,
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "position",
align: "left",
label: "ตำแหน่งในสายงาน",
sortable: true,
field: "position",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posType",
align: "left",
label: "ประเภทตำเเหน่ง",
sortable: true,
field: "posType",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posLevel",
align: "left",
label: "ระดับตำเเหน่ง",
sortable: true,
field: "posLevel",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
const rows = ref<DataPerson[]>([]);
/** ข้อมูุลค้นหา*/
const formFilter = reactive<DataFilterPerson>({
page: 1,
pageSize: 10,
keyword: "",
rootId: "",
year: 0,
period: "",
});
const maxPage = ref<number>(1);
/** function close popup*/
function closeModal() {
modal.value = false;
formFilter.page = 1;
formFilter.keyword = "";
}
/** function เรียกรายชื่อ คนเลื่อนเงินเดือน*/
function fetchListPerson() {
showLoader();
formFilter.rootId = store.rootId;
formFilter.period = store.roundMainCode;
formFilter.year = store.roundYear;
http
.post(config.API.salaryListPerson, formFilter)
.then((res) => {
const data = res.data.result.data;
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
rows.value = data;
})
.catch((err) => {
messageError($q, err);
closeModal();
})
.finally(() => {
hideLoader();
});
}
/**
* function นยนการเพมคนเลอนเงนเดอน
* @param data อมลคนทเพ
*/
function onClickAddPerson(data: DataPerson) {
const body: DataPersonReq = {
id: store.groupId,
type: store.tabType,
...data,
};
dialogConfirm(
$q,
() => {
showLoader();
http
.post(config.API.salaryPeriodProfile, body)
.then(async () => {
await props.fetchData?.();
await success($q, "เพื่มรายชื่อสำเร็จ");
closeModal();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการเพิ่มรายชื่อ",
"ต้องการยืนยันการเพิ่มรายชื่อนี้ใช่หรือไม่?"
);
}
/** function updatePage*/
async function updatePagePagination() {
fetchListPerson();
}
/** function updatePageSize*/
function updatePageSizePagination(newPagination: NewPagination) {
formFilter.page = 1;
formFilter.pageSize = newPagination.rowsPerPage;
}
/** function ค้นหาข้อมูลตาม keyword*/
function searchData() {
formFilter.page = 1;
fetchListPerson();
}
/** callblack function เรียกข้อมูลรายชื่อคนเลื่อนเงินเดือน เมื่อมีการเปิด Popup*/
watch(
() => modal.value,
() => {
if (modal.value) {
fetchListPerson();
}
}
);
/** callblack function เรียกข้อมูลรายชื่อคนเลื่อนเงินเดือน เมื่อมีการเปลี่ยน PageSize*/
watch(
() => formFilter.pageSize,
() => {
updatePagePagination();
}
);
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card style="max-width: 100vw">
<Header :tittle="'เพิ่มคนเลื่อนเงินเดือน'" :close="closeModal" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-input
borderless
dense
debounce="300"
outlined
placeholder="ค้นหา"
v-model="formFilter.keyword"
@keydown.enter.prevent="searchData"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
</div>
<div class="col-12">
<d-table
ref="table"
:columns="columns"
:rows="rows"
row-key="id"
flat
bordered
:paging="true"
dense
:rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePageSizePagination"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width></q-th>
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<q-btn
outline
color="primary"
label="เพิ่ม"
@click="onClickAddPerson(props.row)"
/>
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<div v-if="col.name === 'no'">
{{
(formFilter.page - 1) * formFilter.pageSize +
props.rowIndex +
1
}}
</div>
<div v-else-if="col.name === 'fullName'">
{{
`${props.row.prefix}${props.row.firstName} ${props.row.lastName}`
}}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope">
<q-pagination
v-model="formFilter.page"
active-color="primary"
color="dark"
:max="Number(maxPage)"
:max-pages="5"
size="sm"
boundary-links
direction-links
@update:model-value="updatePagePagination()"
></q-pagination>
</template>
</d-table>
</div>
</div>
</q-card-section>
<q-separator />
<!-- <q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
unelevated
dense
class="q-px-md items-center"
color="light-blue-10"
label="บันทึก"
/>
</q-card-actions> -->
</q-card>
</q-dialog>
</template>
<style scoped></style>

View file

@ -1,112 +1,112 @@
<script setup lang="ts">
import { ref } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
/** use*/
const $q = useQuasar();
const mixin = useCounterMixin();
const { dialogConfirm, success, messageError, showLoader, hideLoader } = mixin;
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const amount = defineModel<number | null>("amount", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
fetchData: {
type: Function,
},
});
const amountRef = ref<any>();
/** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
if (amountRef.value.validate()) {
onSubmit();
}
}
/** function ปืด Popup */
function close() {
modal.value = false;
amount.value = null;
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
if (amount.value !== null) {
showLoader();
const amountString: string = amount.value.toString();
const body = {
profileId: profileId.value,
amount:
typeof amount.value === "number"
? amount.value
: Number(amountString.replace(/,/g, "")),
};
http
.post(config.API.salaryPeriod() + `/change/amount`, body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
});
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 30%">
<Header :tittle="`แก้ไขเงินเดือน`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-input
ref="amountRef"
dense
outlined
v-model="amount"
label="เงินเดือนฐาน"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือนฐาน'}`]"
lazy-rules
hide-bottom-space
class="inputgreen"
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import { ref } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
/** use*/
const $q = useQuasar();
const mixin = useCounterMixin();
const { dialogConfirm, success, messageError, showLoader, hideLoader } = mixin;
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const amount = defineModel<number | null>("amount", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
fetchData: {
type: Function,
},
});
const amountRef = ref<any>();
/** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
if (amountRef.value.validate()) {
onSubmit();
}
}
/** function ปืด Popup */
function close() {
modal.value = false;
amount.value = null;
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
if (amount.value !== null) {
showLoader();
const amountString: string = amount.value.toString();
const body = {
profileId: profileId.value,
amount:
typeof amount.value === "number"
? amount.value
: Number(amountString.replace(/,/g, "")),
};
http
.post(config.API.salaryPeriod() + `/change/amount`, body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
}
});
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 30%">
<Header :tittle="`แก้ไขเงินเดือน`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-input
ref="amountRef"
dense
outlined
v-model="amount"
label="เงินเดือนฐาน"
mask="###,###,###,###"
reverse-fill-mask
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือนฐาน'}`]"
lazy-rules
hide-bottom-space
class="inputgreen"
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>

View file

@ -1,160 +1,160 @@
<script setup lang="ts">
import { ref } from "vue";
import Header from "@/components/DialogHeader.vue";
const modal = defineModel<boolean>("modal", { required: true });
const separator = ref<any>("cell");
/** ปิด Dialog */
function closeDialog() {
modal.value = !modal.value;
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" full-width>
<Header
tittle="หลักเกณฑ์การพิจารณาเลื่อนขั้นเงินข้าราชการ"
:close="closeDialog"
/>
<q-separator />
<q-card-section>
<div class="q-pa-md">
<q-markup-table
:separator="separator"
flat
bordered
class="custom-header-table"
>
<thead>
<tr>
<th class="text-center">หลกเกณฑในการพจารณาเลอนข </th>
<th class="text-center">หนงข</th>
<th class="text-center">ครงข</th>
<th class="text-center">ไมไดบการเลอนข</th>
</tr>
</thead>
<tbody>
<!-- อ1 -->
<tr>
<td class="text-left">1. ผลการประเมนผลการปฎราชการ</td>
<td class="text-center">
ผลการประเมนผลในระดบดเด<br />(90-100%)
</td>
<td class="text-center">
ผลการประเมนเปนทยอมรบได<br />(60-89%)
</td>
<td class="text-center">
ผลการประเมนตองปรบปร<br />(ำกว 60%)
</td>
</tr>
<!-- อ2 -->
<tr>
<td class="text-left">
2. ระยะเวลาการปฎราชการในรอบครงป
</td>
<td class="text-center">ไมอยกว 4 เดอน</td>
<td class="text-center">ไมอยกว 4 เดอน</td>
<td class="text-center">
อยกว 4 เดอน<br />(บรรจใหม ลาศกษา กอบรมดงาน)
</td>
</tr>
<!-- อ3 -->
<tr>
<td class="text-left">3. การลงโทษทางว</td>
<td class="text-center">
กสงลงโทษไมหนกกว<br />ภาคทณฑ
</td>
<td class="text-center">
กสงลงโทษไมหนกกว<br />ภาคทณฑ
</td>
<td class="text-center">
กสงลงโทษไมหนกกว<br />ภาคทณฑ
</td>
</tr>
<!-- อ4 -->
<tr>
<td class="text-left">4. กราชการ</td>
<td class="text-center">ไมกสงพกราชการ</td>
<td class="text-center">
กสงพกราชการ<br />ไมเก 2 เดอน
</td>
<td class="text-center">
กสงพกราชการ<br />ไมเก 2 เดอน
</td>
</tr>
<!-- อ5 -->
<tr>
<td class="text-left">5. ขาดราชการ</td>
<td class="text-center">ไมขาดราชการ</td>
<td class="text-center">ไมขาดราชการ</td>
<td class="text-center">ไมขาดราชการ</td>
</tr>
<!-- อ6 -->
<tr class="vertical-top">
<td class="text-left">6. นลา</td>
<td class="text-left">
<p class="q-mb-none txt-under">
ไมเก 5 คร 23 <br />สายไมเก 5 คร
</p>
<p class="q-mb-none">(บเฉพาะการลาปวยลาก)</p>
<p class="text-bold q-mb-none">ยกเว</p>
<p class="q-mb-none">
- ลาอปสมบท
<br />
- ลาคลอดบตร (ไมเก 90 )
<br />
* กรณลาปวยซงจำเปนตองรกษาตวเปนเวลานาน<br />ไมาคราวเดยวหรอหลายคราว
รวมก<span class="txt-under">ไมเก</span> 60 นทำการ
</p>
</td>
<td class="text-left">
<p class="txt-under q-mb-none">
ไมเก 8 คร 23 <br />สายไมเก 23 คร
</p>
<p class="q-mb-none">(บเฉพาะการลาปวยลาก)</p>
<p class="text-bold q-mb-none">ยกเว</p>
<p class="q-mb-none">
- ลาอปสมบท
<br />
- ลาคลอดบตร (ไมเก 90 )
<br />
* กรณลาปวยซงจำเปนตองรกษาตวเปนเวลานาน<br />ไมาคราวเดยวหรอหลายคราว
รวมก<span class="txt-under">ไมเก</span> 60 นทำการ
</p>
</td>
<td class="text-left">
<p class="txt-under q-mb-none">
ไมเก 8 คร 23 <br />สายไมเก 23 คร
</p>
<p>(บเฉพาะการลาปวยลาก)</p>
<br />
<br />
<p class="q-mb-none">
* กรณลาปวยซงจำเปนตองรกษาตวเปนเวลานาน<br />ไมาคราวเดยวหรอหลายคราว
รวมก<span class="txt-under">ไมเก</span> 60 นทำการ
</p>
</td>
</tr>
</tbody>
</q-markup-table>
</div>
</q-card-section>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped>
.txt-under {
text-decoration: underline;
}
.q-table th {
font-size: 14px !important;
}
</style>
<script setup lang="ts">
import { ref } from "vue";
import Header from "@/components/DialogHeader.vue";
const modal = defineModel<boolean>("modal", { required: true });
const separator = ref<any>("cell");
/** ปิด Dialog */
function closeDialog() {
modal.value = !modal.value;
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" full-width>
<Header
tittle="หลักเกณฑ์การพิจารณาเลื่อนขั้นเงินข้าราชการ"
:close="closeDialog"
/>
<q-separator />
<q-card-section>
<div class="q-pa-md">
<q-markup-table
:separator="separator"
flat
bordered
class="custom-header-table"
>
<thead>
<tr>
<th class="text-center">หลกเกณฑในการพจารณาเลอนข </th>
<th class="text-center">หนงข</th>
<th class="text-center">ครงข</th>
<th class="text-center">ไมไดบการเลอนข</th>
</tr>
</thead>
<tbody>
<!-- อ1 -->
<tr>
<td class="text-left">1. ผลการประเมนผลการปฎราชการ</td>
<td class="text-center">
ผลการประเมนผลในระดบดเด<br />(90-100%)
</td>
<td class="text-center">
ผลการประเมนเปนทยอมรบได<br />(60-89%)
</td>
<td class="text-center">
ผลการประเมนตองปรบปร<br />(ำกว 60%)
</td>
</tr>
<!-- อ2 -->
<tr>
<td class="text-left">
2. ระยะเวลาการปฎราชการในรอบครงป
</td>
<td class="text-center">ไมอยกว 4 เดอน</td>
<td class="text-center">ไมอยกว 4 เดอน</td>
<td class="text-center">
อยกว 4 เดอน<br />(บรรจใหม ลาศกษา กอบรมดงาน)
</td>
</tr>
<!-- อ3 -->
<tr>
<td class="text-left">3. การลงโทษทางว</td>
<td class="text-center">
กสงลงโทษไมหนกกว<br />ภาคทณฑ
</td>
<td class="text-center">
กสงลงโทษไมหนกกว<br />ภาคทณฑ
</td>
<td class="text-center">
กสงลงโทษไมหนกกว<br />ภาคทณฑ
</td>
</tr>
<!-- อ4 -->
<tr>
<td class="text-left">4. กราชการ</td>
<td class="text-center">ไมกสงพกราชการ</td>
<td class="text-center">
กสงพกราชการ<br />ไมเก 2 เดอน
</td>
<td class="text-center">
กสงพกราชการ<br />ไมเก 2 เดอน
</td>
</tr>
<!-- อ5 -->
<tr>
<td class="text-left">5. ขาดราชการ</td>
<td class="text-center">ไมขาดราชการ</td>
<td class="text-center">ไมขาดราชการ</td>
<td class="text-center">ไมขาดราชการ</td>
</tr>
<!-- อ6 -->
<tr class="vertical-top">
<td class="text-left">6. นลา</td>
<td class="text-left">
<p class="q-mb-none txt-under">
ไมเก 5 คร 23 <br />สายไมเก 5 คร
</p>
<p class="q-mb-none">(บเฉพาะการลาปวยลาก)</p>
<p class="text-bold q-mb-none">ยกเว</p>
<p class="q-mb-none">
- ลาอปสมบท
<br />
- ลาคลอดบตร (ไมเก 90 )
<br />
* กรณลาปวยซงจำเปนตองรกษาตวเปนเวลานาน<br />ไมาคราวเดยวหรอหลายคราว
รวมก<span class="txt-under">ไมเก</span> 60 นทำการ
</p>
</td>
<td class="text-left">
<p class="txt-under q-mb-none">
ไมเก 8 คร 23 <br />สายไมเก 23 คร
</p>
<p class="q-mb-none">(บเฉพาะการลาปวยลาก)</p>
<p class="text-bold q-mb-none">ยกเว</p>
<p class="q-mb-none">
- ลาอปสมบท
<br />
- ลาคลอดบตร (ไมเก 90 )
<br />
* กรณลาปวยซงจำเปนตองรกษาตวเปนเวลานาน<br />ไมาคราวเดยวหรอหลายคราว
รวมก<span class="txt-under">ไมเก</span> 60 นทำการ
</p>
</td>
<td class="text-left">
<p class="txt-under q-mb-none">
ไมเก 8 คร 23 <br />สายไมเก 23 คร
</p>
<p>(บเฉพาะการลาปวยลาก)</p>
<br />
<br />
<p class="q-mb-none">
* กรณลาปวยซงจำเปนตองรกษาตวเปนเวลานาน<br />ไมาคราวเดยวหรอหลายคราว
รวมก<span class="txt-under">ไมเก</span> 60 นทำการ
</p>
</td>
</tr>
</tbody>
</q-markup-table>
</div>
</q-card-section>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped>
.txt-under {
text-decoration: underline;
}
.q-table th {
font-size: 14px !important;
}
</style>

View file

@ -1,131 +1,131 @@
<script setup lang="ts">
import { ref, defineModel, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const { dialogConfirm, success, messageError, showLoader, hideLoader } =
useCounterMixin();
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
group: { type: String },
fetchData: {
type: Function,
},
});
/** ตัวแปร*/
const group = ref<string>("");
const groupRef = ref<any>(null);
const isReadonly = ref<boolean>(false); //
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
if (groupRef.value.validate()) {
onSubmit();
}
}
/** function ปืด Popup */
function close() {
modal.value = false;
group.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
profileId: profileId.value,
groupId: group.value,
};
http
.post(config.API.salaryPeriod() + `/change/group`, body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
watch(
() => modal.value,
() => {
if (modal.value) {
group.value =
props.group === "กลุ่ม1" ? store.groupOp[1].id : store.groupOp[0].id;
}
}
);
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 30%">
<Header :tittle="`ย้ายกลุ่ม`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-select
ref="groupRef"
:class="inputEdit(isReadonly)"
v-model="group"
label="กลุ่ม"
dense
outlined
emit-value
map-options
option-label="name"
option-value="id"
:options="store.groupOp.filter((e) => e.name !== props.group)"
:rules="[(val) => !!val || `${'กรุณากลุ่ม'}`]"
lazy-rules
hide-bottom-space
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import { ref, defineModel, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const { dialogConfirm, success, messageError, showLoader, hideLoader } =
useCounterMixin();
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
group: { type: String },
fetchData: {
type: Function,
},
});
/** ตัวแปร*/
const group = ref<string>("");
const groupRef = ref<any>(null);
const isReadonly = ref<boolean>(false); //
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
if (groupRef.value.validate()) {
onSubmit();
}
}
/** function ปืด Popup */
function close() {
modal.value = false;
group.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
profileId: profileId.value,
groupId: group.value,
};
http
.post(config.API.salaryPeriod() + `/change/group`, body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
watch(
() => modal.value,
() => {
if (modal.value) {
group.value =
props.group === "กลุ่ม1" ? store.groupOp[1].id : store.groupOp[0].id;
}
}
);
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 30%">
<Header :tittle="`ย้ายกลุ่ม`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-select
ref="groupRef"
:class="inputEdit(isReadonly)"
v-model="group"
label="กลุ่ม"
dense
outlined
emit-value
map-options
option-label="name"
option-value="id"
:options="store.groupOp.filter((e) => e.name !== props.group)"
:rules="[(val) => !!val || `${'กรุณากลุ่ม'}`]"
lazy-rules
hide-bottom-space
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>

View file

@ -1,191 +1,191 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const {
dialogConfirm,
success,
messageError,
showLoader,
hideLoader,
dialogMessageNotify,
} = useCounterMixin();
/**porps*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
typeLevel: { type: String, required: true },
isReserve: { type: Boolean, required: true },
remark: { type: String, required: true },
fetchData: {
type: Function,
},
});
const type = ref<string>("");
const note = ref<string>("");
const typeRef = ref<any>(null);
const isReadonly = ref<boolean>(false); //
const isChange = ref<boolean>(false); //
const isReserve = ref<boolean>(false); //
const typeRangeOps = computed(() => {
return store.roundMainCode == "OCT"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
{ id: "FULLHAFT", name: "1.5 ขั้น" },
]
: store.roundMainCode == "APR"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
]
: [
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
];
});
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
if (typeRef.value.validate()) {
onSubmit();
}
}
/** function ปืด Popup */
function close() {
modal.value = false;
type.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
profileId: profileId.value,
type: type.value,
isReserve: isReserve.value,
remark: type.value === "NONE" ? note.value : undefined,
};
http
.post(config.API.salaryPeriod() + `/change/type`, body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
function chengType() {
note.value = props.typeLevel === "NONE" ? props.remark : "";
}
watch(
() => modal.value,
() => {
console.log(props.remark);
type.value = props.typeLevel == "PENDING" ? "" : props.typeLevel;
note.value = props.typeLevel === "NONE" ? props.remark : "";
isReserve.value = props.isReserve;
isChange.value = false;
}
);
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 30%">
<Header :tittle="`เลื่อนขั้น`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-select
ref="typeRef"
:class="inputEdit(isReadonly)"
v-model="type"
label="เลื่อนขั้น"
dense
outlined
emit-value
map-options
option-label="name"
option-value="id"
:options="typeRangeOps"
:rules="[(val) => !!val || `${'กรุณาเลือก ขั้น'}`]"
lazy-rules
hide-bottom-space
@update:model-value="(isChange = true), chengType()"
/>
<q-checkbox
v-if="type === 'FULL'"
keep-color
label="สำรอง"
dense
v-model="isReserve"
@update:model-value="isChange = true"
/>
<q-input
v-if="type === 'NONE'"
outlined
dense
v-model="note"
label="หมายเหตุ"
type="textarea"
:class="inputEdit(isReadonly)"
@update:model-value="isChange = true"
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
:disabled="!isChange"
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const {
dialogConfirm,
success,
messageError,
showLoader,
hideLoader,
dialogMessageNotify,
} = useCounterMixin();
/**porps*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("profileId", { required: true });
const props = defineProps({
typeLevel: { type: String, required: true },
isReserve: { type: Boolean, required: true },
remark: { type: String, required: true },
fetchData: {
type: Function,
},
});
const type = ref<string>("");
const note = ref<string>("");
const typeRef = ref<any>(null);
const isReadonly = ref<boolean>(false); //
const isChange = ref<boolean>(false); //
const isReserve = ref<boolean>(false); //
const typeRangeOps = computed(() => {
return store.roundMainCode == "OCT"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
{ id: "FULLHAFT", name: "1.5 ขั้น" },
]
: store.roundMainCode == "APR"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
]
: [
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
];
});
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
if (typeRef.value.validate()) {
onSubmit();
}
}
/** function ปืด Popup */
function close() {
modal.value = false;
type.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
profileId: profileId.value,
type: type.value,
isReserve: isReserve.value,
remark: type.value === "NONE" ? note.value : undefined,
};
http
.post(config.API.salaryPeriod() + `/change/type`, body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
function chengType() {
note.value = props.typeLevel === "NONE" ? props.remark : "";
}
watch(
() => modal.value,
() => {
console.log(props.remark);
type.value = props.typeLevel == "PENDING" ? "" : props.typeLevel;
note.value = props.typeLevel === "NONE" ? props.remark : "";
isReserve.value = props.isReserve;
isChange.value = false;
}
);
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 30%">
<Header :tittle="`เลื่อนขั้น`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm">
<q-select
ref="typeRef"
:class="inputEdit(isReadonly)"
v-model="type"
label="เลื่อนขั้น"
dense
outlined
emit-value
map-options
option-label="name"
option-value="id"
:options="typeRangeOps"
:rules="[(val) => !!val || `${'กรุณาเลือก ขั้น'}`]"
lazy-rules
hide-bottom-space
@update:model-value="(isChange = true), chengType()"
/>
<q-checkbox
v-if="type === 'FULL'"
keep-color
label="สำรอง"
dense
v-model="isReserve"
@update:model-value="isChange = true"
/>
<q-input
v-if="type === 'NONE'"
outlined
dense
v-model="note"
label="หมายเหตุ"
type="textarea"
:class="inputEdit(isReadonly)"
@update:model-value="isChange = true"
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
:disabled="!isChange"
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>

View file

@ -1,155 +1,155 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const {
dialogConfirm,
success,
messageError,
showLoader,
hideLoader,
dialogMessageNotify,
} = useCounterMixin();
/**porps*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("id", { required: true });
const props = defineProps({
isPunish: { type: Boolean, required: true },
isSuspension: { type: Boolean, required: true },
isAbsent: { type: Boolean, required: true },
isLeave: { type: Boolean, required: true },
fetchData: {
type: Function,
},
});
const type = ref<string>("");
const isPunish = ref<boolean>(false); //
const isSuspension = ref<boolean>(false); //
const isAbsent = ref<boolean>(false); //
const isLeave = ref<boolean>(false); //
const typeRangeOps = computed(() => {
return store.roundMainCode == "OCT"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
{ id: "FULLHAFT", name: "1.5 ขั้น" },
]
: [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
];
});
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
onSubmit();
}
/** function ปืด Popup */
function close() {
modal.value = false;
type.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
isPunish: isPunish.value,
isSuspension: isSuspension.value,
isAbsent: isAbsent.value,
isLeave: isLeave.value,
};
http
.put(config.API.salaryProperty(profileId.value), body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
watch(
() => modal.value,
() => {
if (modal.value) {
isPunish.value = props.isPunish ? props.isPunish : false;
isSuspension.value = props.isSuspension ? props.isSuspension : false;
isAbsent.value = props.isAbsent ? props.isAbsent : false;
isLeave.value = props.isLeave ? props.isLeave : false;
}
}
);
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 20%">
<Header :tittle="`แก้ไขคุณสมบัติ`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm column">
<q-checkbox
keep-color
label="ไม่ถูกลงโทษทางวินัย"
dense
v-model="isPunish"
/>
<q-checkbox
keep-color
label="ไม่ถูกพักราชการ"
dense
v-model="isSuspension"
/>
<q-checkbox
keep-color
label="ไม่ขาดราชการ"
dense
v-model="isAbsent"
/>
<q-checkbox keep-color label="วันลาไม่เกิน" dense v-model="isLeave" />
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const {
dialogConfirm,
success,
messageError,
showLoader,
hideLoader,
dialogMessageNotify,
} = useCounterMixin();
/**porps*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("id", { required: true });
const props = defineProps({
isPunish: { type: Boolean, required: true },
isSuspension: { type: Boolean, required: true },
isAbsent: { type: Boolean, required: true },
isLeave: { type: Boolean, required: true },
fetchData: {
type: Function,
},
});
const type = ref<string>("");
const isPunish = ref<boolean>(false); //
const isSuspension = ref<boolean>(false); //
const isAbsent = ref<boolean>(false); //
const isLeave = ref<boolean>(false); //
const typeRangeOps = computed(() => {
return store.roundMainCode == "OCT"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
{ id: "FULLHAFT", name: "1.5 ขั้น" },
]
: [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
];
});
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
onSubmit();
}
/** function ปืด Popup */
function close() {
modal.value = false;
type.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
isPunish: isPunish.value,
isSuspension: isSuspension.value,
isAbsent: isAbsent.value,
isLeave: isLeave.value,
};
http
.put(config.API.salaryProperty(profileId.value), body)
.then(async () => {
await props.fetchData?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
watch(
() => modal.value,
() => {
if (modal.value) {
isPunish.value = props.isPunish ? props.isPunish : false;
isSuspension.value = props.isSuspension ? props.isSuspension : false;
isAbsent.value = props.isAbsent ? props.isAbsent : false;
isLeave.value = props.isLeave ? props.isLeave : false;
}
}
);
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 20%">
<Header :tittle="`แก้ไขคุณสมบัติ`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm column">
<q-checkbox
keep-color
label="ไม่ถูกลงโทษทางวินัย"
dense
v-model="isPunish"
/>
<q-checkbox
keep-color
label="ไม่ถูกพักราชการ"
dense
v-model="isSuspension"
/>
<q-checkbox
keep-color
label="ไม่ขาดราชการ"
dense
v-model="isAbsent"
/>
<q-checkbox keep-color label="วันลาไม่เกิน" dense v-model="isLeave" />
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
type="submit"
for="#submitForm"
color="secondary"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>

View file

@ -1,482 +1,482 @@
<script setup lang="ts">
import { ref, defineProps, onMounted } from "vue";
import { useQuasar } from "quasar";
import { checkPermission } from "@/utils/permissions";
import axios from "axios";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import DialogPopupReason from "@/components/Dialogs/PopupReason.vue"; //
/** importStore*/
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
import { useCounterMixin } from "@/stores/mixin";
/* use**/
const $q = useQuasar(); // noti quasar
const store = useSalaryListSDataStore();
const {
messageError,
dialogConfirm,
showLoader,
hideLoader,
success,
dialogRemove,
} = useCounterMixin();
/** props*/
const props = defineProps({
rootId: String,
periodId: String,
getData: Function,
});
const modalRecommend = ref<boolean>(false);
const titleRecommend = ref<string>("");
const listFile = ref<any>([]);
const type = ref<string>("");
const sendStep = ref<number>(1);
const fileUpload = ref<any>(null);
const document = ref<string>("");
/**
* function ปโหลดไฟลเจาหนาท
* @param event file
*/
async function uploadFile(event: any) {
const fileName = { fileName: event.name };
dialogConfirm(
$q,
async () => {
showLoader();
const selectedFile = event;
const formdata = new FormData();
formdata.append("Document", selectedFile);
http
.post(
config.API.subFile(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
),
{
replace: false, //
fileList: fileName,
}
)
.then(async (res) => {
const foundKey: string | undefined = Object.keys(res.data).find(
(key) =>
res.data[key]?.fileName !== undefined &&
res.data[key]?.fileName !== ""
);
foundKey &&
(await uploadfile(res.data[foundKey]?.uploadUrl, fileUpload.value));
})
.catch((err) => {
messageError($q, err);
hideLoader();
});
},
"ยืนยันการอัปโหลดไฟล์",
"ต้องการยืนยันการอัปโหลดไฟล์นี้หรือไม่ ?"
);
}
/**
* functoin ปโหลดไฟล
* @param uploadUrl link ปโหลด
* @param file ไฟล
*/
function uploadfile(uploadUrl: string, file: any) {
showLoader();
axios
.put(uploadUrl, file, {
headers: {
"Content-Type": file.type,
},
})
.then(async () => {
await getListFile();
success($q, "อัปโหลไฟล์สำเร็จ");
fileUpload.value = null;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/**
* fetchList ไฟล
*/
function getListFile() {
http
.get(
config.API.subFile(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
)
)
.then((res) => {
listFile.value = res.data;
})
.catch((e) => {
messageError($q, e);
});
}
/**
* โหลดไฟล
* @param fileName อไฟล
*/
function downloadFile(fileName: string) {
showLoader();
http
.get(
config.API.subFileByFileName(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : "",
fileName
)
)
.then((res) => {
const data = res.data.downloadUrl;
window.open(data, "_blank");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
});
}
/**
* ลบไฟล
* @param fileName อไฟล
*/
function deleteFile(fileName: string) {
dialogRemove($q, () => {
showLoader();
http
.delete(
config.API.subFileByFileName(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : "",
fileName
)
)
.then(() => {
setTimeout(async () => {
await getListFile();
await success($q, "ลบไฟล์สำเร็จ");
hideLoader();
}, 2000);
})
.catch((e) => {
messageError($q, e);
hideLoader();
});
});
}
/**
* นยนการส
* @param msg งเอกสารให ผอ. ตรวจสอบ,นยนและสงเอกสารให,นยนการตรวจสอบ
* @param type officer, head,owner
*/
function sendToDirector(msg: string, type: string) {
dialogConfirm(
$q,
async () => {
showLoader();
http
.get(
config.API.salaryPeriodStatus(
type,
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
)
)
.then(() => {
props.getData?.();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการ" + msg,
"ต้องการยืนยันการ" + msg + "หรือไม่?"
);
}
/**
* งคำแนะนำให ผอ. ตรวจสอบ
* @param title วข
* @param typeOrder ประเภทคำส
*/
function sendAndRecommend(title: string, typeOrder: string) {
modalRecommend.value = true;
titleRecommend.value = title;
type.value = typeOrder;
}
/**
* นยนการบนทกคำแนะนำ
* @param reason คำแนะนำ
*/
function saveReccommend(reason: string) {
dialogConfirm(
$q,
async () => {
showLoader();
http
.put(
config.API.salaryPeriodStatusComment(
type.value,
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
),
{
titleRecommend: reason,
}
)
.then(async () => {
await props.getData?.();
sendStep.value = sendStep.value + 1;
modalRecommend.value = false;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการ" + titleRecommend.value,
"ต้องการยืนยันการ" + titleRecommend.value + "หรือไม่?"
);
}
onMounted(() => {
if (props.rootId) {
getListFile();
}
});
</script>
<template>
<q-card class="col-12">
<q-card-section>
<q-toolbar
class="q-pa-none"
v-if="
store.statusQuota == 'PENDING' &&
checkPermission($route)?.attrIsUpdate
"
>
<q-file
bg-color="white"
clearable
outlined
dense
v-model="fileUpload"
accept=".pdf"
label="อัปโหลดไฟล์"
>
<template v-slot:prepend>
<q-icon color="light-blue" name="attach_file" />
<q-tooltip>ปโหลดไฟล</q-tooltip>
</template>
</q-file>
<q-btn
dense
flat
round
color="light-blue"
icon="upload"
@click="uploadFile(fileUpload)"
v-if="fileUpload !== null"
>
<q-tooltip>ปโหลดไฟล</q-tooltip>
</q-btn>
<div v-if="document">
<q-btn
dense
color="primary"
icon-right="mdi-download"
label="ดาวน์โหลดไฟล์"
outline
:href="document"
target="_blank"
>
<q-tooltip>ดาวนโหลด</q-tooltip></q-btn
>
</div>
<q-toolbar-title>
<!-- Toolbar -->
</q-toolbar-title>
</q-toolbar>
<div class="row">
<div class="col-6" v-if="listFile.length !== 0">
<q-card bordered style="border: 1px solid #d6dee1">
<div class="col-12 text-weight-medium bg-grey-1 q-py-sm q-px-md">
รายการเอกสาร
</div>
<q-list bordered separator>
<q-item clickable v-ripple v-for="item in listFile">
<q-item-section>{{ item.fileName }}</q-item-section>
<q-item-section avatar>
<div class="row">
<div>
<q-btn
v-if="checkPermission($route)?.attrIsGet"
dense
flat
round
color="blue"
icon="mdi-download"
@click="downloadFile(item.fileName)"
>
<q-tooltip>ดาวนโหลดเอกสาร</q-tooltip>
</q-btn>
</div>
<div>
<q-btn
v-if="checkPermission($route)?.attrIsDelete"
dense
flat
round
color="red"
icon="delete"
@click="deleteFile(item.fileName)"
><q-tooltip>ลบเอกสาร</q-tooltip></q-btn
>
</div>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<div>
<!-- การเจาหนาทของหนวยงานสงเอกสารให ผอ. หนวยงานตรวจสอบ -->
<q-btn
v-if="
store.statusQuota == 'PENDING' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ส่งเอกสารให้ ผอ. ตรวจสอบ"
@click="sendToDirector('ส่งเอกสารให้ ผอ. ตรวจสอบ', 'officer')"
/>
<!-- ผอ. หนวยงานทำการยนยนและสงให สกจ. -->
<q-btn
v-if="
store.statusQuota == 'WAITHEAD1' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ยืนยันและส่งเอกสารให้ สกจ."
@click="sendToDirector('ยืนยันและส่งเอกสารให้ สกจ.', 'head')"
/>
<!-- สกจ. ตรวจสอบเอกสารและขอมลรายการเงนเดอนทแตละหนวยงานสงมา ไมปรบโควต -->
<q-btn
v-if="
store.statusQuota == 'WAITOWNER1' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="green"
label="ยืนยันการตรวจสอบ"
@click="sendToDirector('ยืนยันการตรวจสอบ', 'owner')"
/>
<!-- สกจ. ตรวจสอบเอกสารและขอมลรายการเงนเดอนทแตละหนวยงานสงมา ปรบโควต -->
<q-btn
v-if="
store.statusQuota == 'WAITOWNER1' &&
checkPermission($route)?.attrIsUpdate
"
class="q-ml-sm"
unelevated
color="warning"
label="ส่งคำแนะนำให้ ผอ. ตรวจสอบ"
@click="sendAndRecommend('ส่งคำแนะนำให้ ผอ. ตรวจสอบ', 'owner')"
/>
<!-- ผอ.หนวยงานสงคำแนะนำใหการเจาหนาทหนวยงาน -->
<q-btn
v-if="
store.statusQuota == 'WAITHEAD2' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ส่งคำแนะนำให้การเจ้าหน้าที่หน่วยงาน"
@click="
sendAndRecommend('ส่งคำแนะนำให้การเจ้าหน้าที่หน่วยงาน', 'head')
"
/>
<!-- งไปออกคำส -->
<q-btn
v-if="
store.statusQuota == 'WAITOFFICER2' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ส่งไปออกคำสั่ง"
/>
<!-- รอออกคำส -->
<q-btn
v-if="
store.statusQuota == 'REPORT' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
disable
label="รอออกคำสั่ง"
/>
</div>
</q-card-actions>
</q-card>
<DialogPopupReason
v-model:modal="modalRecommend"
:title="titleRecommend"
label="คำแนะนำ"
:savaForm="saveReccommend"
textReport=""
/>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import { ref, defineProps, onMounted } from "vue";
import { useQuasar } from "quasar";
import { checkPermission } from "@/utils/permissions";
import axios from "axios";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import DialogPopupReason from "@/components/Dialogs/PopupReason.vue"; //
/** importStore*/
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
import { useCounterMixin } from "@/stores/mixin";
/* use**/
const $q = useQuasar(); // noti quasar
const store = useSalaryListSDataStore();
const {
messageError,
dialogConfirm,
showLoader,
hideLoader,
success,
dialogRemove,
} = useCounterMixin();
/** props*/
const props = defineProps({
rootId: String,
periodId: String,
getData: Function,
});
const modalRecommend = ref<boolean>(false);
const titleRecommend = ref<string>("");
const listFile = ref<any>([]);
const type = ref<string>("");
const sendStep = ref<number>(1);
const fileUpload = ref<any>(null);
const document = ref<string>("");
/**
* function ปโหลดไฟลเจาหนาท
* @param event file
*/
async function uploadFile(event: any) {
const fileName = { fileName: event.name };
dialogConfirm(
$q,
async () => {
showLoader();
const selectedFile = event;
const formdata = new FormData();
formdata.append("Document", selectedFile);
http
.post(
config.API.subFile(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
),
{
replace: false, //
fileList: fileName,
}
)
.then(async (res) => {
const foundKey: string | undefined = Object.keys(res.data).find(
(key) =>
res.data[key]?.fileName !== undefined &&
res.data[key]?.fileName !== ""
);
foundKey &&
(await uploadfile(res.data[foundKey]?.uploadUrl, fileUpload.value));
})
.catch((err) => {
messageError($q, err);
hideLoader();
});
},
"ยืนยันการอัปโหลดไฟล์",
"ต้องการยืนยันการอัปโหลดไฟล์นี้หรือไม่ ?"
);
}
/**
* functoin ปโหลดไฟล
* @param uploadUrl link ปโหลด
* @param file ไฟล
*/
function uploadfile(uploadUrl: string, file: any) {
showLoader();
axios
.put(uploadUrl, file, {
headers: {
"Content-Type": file.type,
},
})
.then(async () => {
await getListFile();
success($q, "อัปโหลไฟล์สำเร็จ");
fileUpload.value = null;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/**
* fetchList ไฟล
*/
function getListFile() {
http
.get(
config.API.subFile(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
)
)
.then((res) => {
listFile.value = res.data;
})
.catch((e) => {
messageError($q, e);
});
}
/**
* โหลดไฟล
* @param fileName อไฟล
*/
function downloadFile(fileName: string) {
showLoader();
http
.get(
config.API.subFileByFileName(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : "",
fileName
)
)
.then((res) => {
const data = res.data.downloadUrl;
window.open(data, "_blank");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
});
}
/**
* ลบไฟล
* @param fileName อไฟล
*/
function deleteFile(fileName: string) {
dialogRemove($q, () => {
showLoader();
http
.delete(
config.API.subFileByFileName(
"ระบบเงินเดือน",
"เลื่อนเงินเดือน",
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : "",
fileName
)
)
.then(() => {
setTimeout(async () => {
await getListFile();
await success($q, "ลบไฟล์สำเร็จ");
hideLoader();
}, 2000);
})
.catch((e) => {
messageError($q, e);
hideLoader();
});
});
}
/**
* นยนการส
* @param msg งเอกสารให ผอ. ตรวจสอบ,นยนและสงเอกสารให,นยนการตรวจสอบ
* @param type officer, head,owner
*/
function sendToDirector(msg: string, type: string) {
dialogConfirm(
$q,
async () => {
showLoader();
http
.get(
config.API.salaryPeriodStatus(
type,
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
)
)
.then(() => {
props.getData?.();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการ" + msg,
"ต้องการยืนยันการ" + msg + "หรือไม่?"
);
}
/**
* งคำแนะนำให ผอ. ตรวจสอบ
* @param title วข
* @param typeOrder ประเภทคำส
*/
function sendAndRecommend(title: string, typeOrder: string) {
modalRecommend.value = true;
titleRecommend.value = title;
type.value = typeOrder;
}
/**
* นยนการบนทกคำแนะนำ
* @param reason คำแนะนำ
*/
function saveReccommend(reason: string) {
dialogConfirm(
$q,
async () => {
showLoader();
http
.put(
config.API.salaryPeriodStatusComment(
type.value,
props.periodId ? props.periodId : "",
props.rootId ? props.rootId : ""
),
{
titleRecommend: reason,
}
)
.then(async () => {
await props.getData?.();
sendStep.value = sendStep.value + 1;
modalRecommend.value = false;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
},
"ยืนยันการ" + titleRecommend.value,
"ต้องการยืนยันการ" + titleRecommend.value + "หรือไม่?"
);
}
onMounted(() => {
if (props.rootId) {
getListFile();
}
});
</script>
<template>
<q-card class="col-12">
<q-card-section>
<q-toolbar
class="q-pa-none"
v-if="
store.statusQuota == 'PENDING' &&
checkPermission($route)?.attrIsUpdate
"
>
<q-file
bg-color="white"
clearable
outlined
dense
v-model="fileUpload"
accept=".pdf"
label="อัปโหลดไฟล์"
>
<template v-slot:prepend>
<q-icon color="light-blue" name="attach_file" />
<q-tooltip>ปโหลดไฟล</q-tooltip>
</template>
</q-file>
<q-btn
dense
flat
round
color="light-blue"
icon="upload"
@click="uploadFile(fileUpload)"
v-if="fileUpload !== null"
>
<q-tooltip>ปโหลดไฟล</q-tooltip>
</q-btn>
<div v-if="document">
<q-btn
dense
color="primary"
icon-right="mdi-download"
label="ดาวน์โหลดไฟล์"
outline
:href="document"
target="_blank"
>
<q-tooltip>ดาวนโหลด</q-tooltip></q-btn
>
</div>
<q-toolbar-title>
<!-- Toolbar -->
</q-toolbar-title>
</q-toolbar>
<div class="row">
<div class="col-6" v-if="listFile.length !== 0">
<q-card bordered style="border: 1px solid #d6dee1">
<div class="col-12 text-weight-medium bg-grey-1 q-py-sm q-px-md">
รายการเอกสาร
</div>
<q-list bordered separator>
<q-item clickable v-ripple v-for="item in listFile">
<q-item-section>{{ item.fileName }}</q-item-section>
<q-item-section avatar>
<div class="row">
<div>
<q-btn
v-if="checkPermission($route)?.attrIsGet"
dense
flat
round
color="blue"
icon="mdi-download"
@click="downloadFile(item.fileName)"
>
<q-tooltip>ดาวนโหลดเอกสาร</q-tooltip>
</q-btn>
</div>
<div>
<q-btn
v-if="checkPermission($route)?.attrIsDelete"
dense
flat
round
color="red"
icon="delete"
@click="deleteFile(item.fileName)"
><q-tooltip>ลบเอกสาร</q-tooltip></q-btn
>
</div>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<div>
<!-- การเจาหนาทของหนวยงานสงเอกสารให ผอ. หนวยงานตรวจสอบ -->
<q-btn
v-if="
store.statusQuota == 'PENDING' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ส่งเอกสารให้ ผอ. ตรวจสอบ"
@click="sendToDirector('ส่งเอกสารให้ ผอ. ตรวจสอบ', 'officer')"
/>
<!-- ผอ. หนวยงานทำการยนยนและสงให สกจ. -->
<q-btn
v-if="
store.statusQuota == 'WAITHEAD1' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ยืนยันและส่งเอกสารให้ สกจ."
@click="sendToDirector('ยืนยันและส่งเอกสารให้ สกจ.', 'head')"
/>
<!-- สกจ. ตรวจสอบเอกสารและขอมลรายการเงนเดอนทแตละหนวยงานสงมา ไมปรบโควต -->
<q-btn
v-if="
store.statusQuota == 'WAITOWNER1' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="green"
label="ยืนยันการตรวจสอบ"
@click="sendToDirector('ยืนยันการตรวจสอบ', 'owner')"
/>
<!-- สกจ. ตรวจสอบเอกสารและขอมลรายการเงนเดอนทแตละหนวยงานสงมา ปรบโควต -->
<q-btn
v-if="
store.statusQuota == 'WAITOWNER1' &&
checkPermission($route)?.attrIsUpdate
"
class="q-ml-sm"
unelevated
color="warning"
label="ส่งคำแนะนำให้ ผอ. ตรวจสอบ"
@click="sendAndRecommend('ส่งคำแนะนำให้ ผอ. ตรวจสอบ', 'owner')"
/>
<!-- ผอ.หนวยงานสงคำแนะนำใหการเจาหนาทหนวยงาน -->
<q-btn
v-if="
store.statusQuota == 'WAITHEAD2' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ส่งคำแนะนำให้การเจ้าหน้าที่หน่วยงาน"
@click="
sendAndRecommend('ส่งคำแนะนำให้การเจ้าหน้าที่หน่วยงาน', 'head')
"
/>
<!-- งไปออกคำส -->
<q-btn
v-if="
store.statusQuota == 'WAITOFFICER2' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
label="ส่งไปออกคำสั่ง"
/>
<!-- รอออกคำส -->
<q-btn
v-if="
store.statusQuota == 'REPORT' &&
checkPermission($route)?.attrIsUpdate
"
unelevated
color="public"
disable
label="รอออกคำสั่ง"
/>
</div>
</q-card-actions>
</q-card>
<DialogPopupReason
v-model:modal="modalRecommend"
:title="titleRecommend"
label="คำแนะนำ"
:savaForm="saveReccommend"
textReport=""
/>
</template>
<style lang="scss" scoped></style>

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
div<script setup lang="ts">
div
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";