filter รายงานทะเบียนประวัติ

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-02-21 17:04:49 +07:00
parent ef0ed08870
commit 4c2e85b595
2 changed files with 922 additions and 789 deletions

View file

@ -73,6 +73,15 @@ watch(
async () => {
if (modal.value) {
await fetchTree();
if (!orgName.value) {
nodeData.name = "";
nodeData.node = "";
nodeData.nodeId = "";
store.formFilter.node = null;
store.formFilter.nodeId = null;
expanded.value = [];
}
}
}
);
@ -143,8 +152,8 @@ watch(
<q-separator />
<q-card-actions align="right">
<q-btn label="ค้นหา" color="secondary" @click="sendNode">
<q-tooltip>นหา</q-tooltip></q-btn
<q-btn label="เลือก" color="secondary" @click="sendNode">
<q-tooltip>เลอก</q-tooltip></q-btn
>
</q-card-actions>
</q-card>

View file

@ -1,9 +1,6 @@
<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { ref, onMounted, watch, computed } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { VuePDF, usePDF } from "@tato30/vue-pdf";
import axios from "axios";
import genReportXLSX from "@/plugins/genreportxlsx";
import * as XLSX from "xlsx";
import http from "@/plugins/http";
@ -11,6 +8,8 @@ import config from "@/app.config";
import { checkPermission } from "@/utils/permissions";
import { useCounterMixin } from "@/stores/mixin";
import { useReportStore } from "@/modules/21_report/store";
import { useRegistryNewDataStore } from "@/modules/04_registryPerson/store";
import type { OptionData } from "@/modules/07_insignia/interface/index/Main";
import type {
RangeAge,
@ -22,11 +21,11 @@ import type {
DataEducationLevel,
} from "@/modules/21_report/interface/Main";
import LoadView from "@/components/LoadView.vue";
import DialogOrg from "@/modules/21_report/components/01_org/DialogOrg.vue";
const $q = useQuasar();
const storeReport = useReportStore();
const stroeRegistry = useRegistryNewDataStore();
const mixin = useCounterMixin();
const { messageError, showLoader, hideLoader, date2Thai } = mixin;
@ -45,9 +44,6 @@ const detailReport = ref<any>();
/** ช่วงเวลา */
const dateStart = ref<Date | null>(null); //
const dateEnd = ref<Date | null>(null); //
const objMarkerLabel = computed(() => {
return { 39: `ช่วงอายุ ${rangeAge.value.min}-${rangeAge.value.max} ปี` };
});
const rangeAge = ref<RangeAge>({
min: 18,
@ -92,31 +88,19 @@ const isProbation = ref<boolean>(false);
const isRetire = ref<boolean>(false);
const pagination = ref<any>({
sortBy: "dateAppoint",
descending: true,
page: 1,
rowsPerPage: 19,
});
const sortBy = ref<string>("ASC");
const sortBy = ref<string>("DESC");
const retireType = ref<string>("");
const retireTypeOps = ref<DataOption[]>([]);
const retireTypeOpsMain = ref<DataOption[]>([
{ id: "RETIRE", name: "เกษียณ" },
{ id: "RETIRE_RESIGN", name: "ลาออก" },
{ id: "RETIRE_DECEASED", name: "ถึงแก่กรรม" },
{ id: "RETIRE_OUT", name: "ให้ออกจากราชการ" },
{ id: "DISCIPLINE_RESULT_REMOVE", name: "ปลดออกจากราชการ" },
{ id: "DISCIPLINE_RESULT_DISMISS", name: "ไล่ออกจากราชการ" },
{ id: "DISCIPLINE_SUSPEND", name: "ถูกพักจากราชการ" },
{ id: "PROBATION_REPORT", name: "ไม่ผ่านทดลองงาน" },
]);
const retireTypeOpsMain = ref<DataOption[]>(stroeRegistry.retireTypeOps);
const retireTypeOpsMainEMP = ref<DataOption[]>([
{ id: "RETIRE", name: "เกษียณ" },
{ id: "RETIRE_RESIGN_EMP", name: "ลาออก" },
{ id: "RETIRE_DECEASED", name: "ถึงแก่กรรม" },
{ id: "RETIRE_OUT_EMP", name: "ให้ออกจากราชการ" },
]);
const retireTypeOpsMainEMP = ref<DataOption[]>(stroeRegistry.retireTypeEmpOps);
const visibleColumns = ref<string[]>([
const visibleColumnsBase = ref<string[]>([
"no",
"fullName",
"posNo",
@ -134,7 +118,8 @@ const visibleColumns = ref<string[]>([
"lengthPosition",
]);
const columns = ref<QTableProps["columns"]>([
const columns = computed<QTableProps["columns"]>(() => {
return [
{
name: "no",
align: "left",
@ -171,7 +156,7 @@ const columns = ref<QTableProps["columns"]>([
{
name: "position",
align: "left",
label: "ตำแหน่งในสายงาน",
label: employeeClass.value === "officer" ? "ตำแหน่งในสายงาน" : "ตำแหน่ง",
sortable: true,
field: "position",
headerStyle: "font-size: 14px",
@ -264,6 +249,9 @@ const columns = ref<QTableProps["columns"]>([
field: "dateAppoint",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
return val ? date2Thai(row.dateAppointFull) : "";
},
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
@ -300,7 +288,14 @@ const columns = ref<QTableProps["columns"]>([
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
]);
];
});
const visibleColumns = computed<string[]>(() => {
return employeeClass.value === "officer"
? visibleColumnsBase.value
: visibleColumnsBase.value.filter((e: string) => e !== "positionExecutive");
});
function onOpenOrg() {
modalOrg.value = true;
@ -362,7 +357,6 @@ function filterOption(val: string, update: any, typeOp: string) {
*/
function updateLevel(val: string) {
posType.value = val;
if (val) {
const listData: any = posTypeMainOp.value.find(
(item: PosType) => item.posTypeName == val
@ -420,9 +414,7 @@ async function getOptions() {
});
}
/**
* งกเรยกขอมลรายการตำแหนงทางการบรหาร
*/
/** ฟังก์เรียกข้อมูลรายการตำแหน่งทางการบริหาร*/
async function getExecutive() {
await http
.get(config.API.orgPosExecutive)
@ -529,6 +521,7 @@ async function onSearch() {
status: item.relationship ?? "-",
education: item.degree ?? "-",
dateAppoint: item.dateAppoint ? date2Thai(item.dateAppoint) : "-",
dateAppointFull: item.dateAppoint,
age: item.age ?? "-",
currentPosition: item.currentPosition ?? "-",
lengthPosition: item.lengthPosition ?? "-",
@ -547,8 +540,13 @@ async function onSearch() {
}
function exportToExcel() {
const newData = rows.value.map((e: any) => {
const { dateAppointFull, ...rest } = e;
return rest;
});
const headers = columns.value?.map((item: any) => item.label) || []; //
const worksheet = XLSX.utils.json_to_sheet(rows.value, {
const worksheet = XLSX.utils.json_to_sheet(newData, {
header: visibleColumns.value,
});
@ -556,10 +554,48 @@ function exportToExcel() {
XLSX.utils.sheet_add_aoa(worksheet, [headers], { origin: "A1" });
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "รายงานทะเบียนประวัติ"); // sheet
XLSX.writeFile(workbook, "รายงานทะเบียนประวัติ.xlsx");
XLSX.utils.book_append_sheet(workbook, worksheet, `รายงานทะเบียนประวัติ`); // sheet
XLSX.writeFile(
workbook,
`รายงานทะเบียนประวัติ${
employeeClass.value === "officer"
? "(ข้าราชการ กทม. สามัญ)"
: "(ลูกจ้างประจำ กทม.)"
}.xlsx`
);
}
/** ฟังก์ชันล้างตัวกรองทั้งหมด*/
function clearFilter() {
//
org.value = "";
storeReport.formFilter.node = null;
storeReport.formFilter.nodeId = null;
posType.value = ""; //,
posLevel.value = ""; //,
position.value = ""; //
positionExecutive.value = ""; //
gender.value = ""; //
status.value = ""; //
education.value = ""; //
//
dateStart.value = null; //
dateEnd.value = null; //
//
rangeAge.value.min = 18;
rangeAge.value.max = 60;
isProbation.value = false; //
isRetire.value = false; //
retireType.value = ""; //
}
watch(
() => pagination.value.descending,
() => {
sortBy.value = pagination.value.descending ? "DESC" : "ASC";
}
);
onMounted(async () => {
showLoader();
Promise.all([
@ -569,16 +605,14 @@ onMounted(async () => {
getDataPerson(),
getEducationLevel(),
])
.then(() => {
hideLoader();
})
.catch((e) => {
messageError($q, e);
hideLoader();
})
.finally(() => {
setTimeout(() => {
loadingBtn.value = false;
hideLoader();
}, 500);
});
});
@ -590,11 +624,7 @@ onMounted(async () => {
</div>
<div class="col-12">
<q-form
greedy
@submit.prevent
@validation-success="onSearch"
>
<q-form greedy @submit.prevent @validation-success="onSearch">
<div class="row col-12 q-gutter-sm">
<q-card class="col-12 q-pa-sm">
<div class="row col-12 q-col-gutter-sm no-wrap">
@ -609,11 +639,11 @@ onMounted(async () => {
map-options
option-label="name"
option-value="id"
@update:model-value="retireType = ''"
@update:model-value="clearFilter(), getType()"
>
</q-select>
</div>
<div class="col-lg-9 col-md-8 col-sm-8 col-xs-11">
<!-- <div class="col-lg-9 col-md-8 col-sm-8 col-xs-11">
<q-input
outlined
dense
@ -634,7 +664,7 @@ onMounted(async () => {
/>
</template>
</q-input>
</div>
</div> -->
<q-space />
<div>
<q-btn
@ -700,15 +730,51 @@ onMounted(async () => {
<div class="col-12 row q-pa-sm q-col-gutter-sm">
<div class="col">
<q-card flat bordered class="col-12">
<q-card-section bordered class="bg-primary text-subtitle2 text-white q-pa-sm row col-12 items-center">
<q-card-section
bordered
class="bg-primary text-subtitle2 text-white q-pa-sm row col-12 items-center"
>
<q-icon name="mdi-filter" class="q-mr-xs" />
วกรอง
<q-space />
<q-btn dense size="12px" class="q-px-sm" rounded flat label="ล้างทั้งหมด" />
<q-btn
dense
size="12px"
class="q-px-sm"
rounded
flat
label="ล้างทั้งหมด"
@click.stop.pervent="clearFilter"
/>
</q-card-section>
<q-separator />
<div class="row col-12">
<div class="row col-12 q-col-x-gutter-xs items-center">
<div class="col-12 q-px-sm">
<q-input
dense
:model-value="org ? org : 'ทั้งหมด'"
autogrow
borderless
label="สังกัด"
class="bg-white"
@click="onOpenOrg"
>
<template v-if="org" v-slot:append>
<q-icon
name="cancel"
@click.stop.prevent="
(org = ''),
(storeReport.formFilter.node = null),
(storeReport.formFilter.nodeId = null)
"
class="cursor-pointer"
style="opacity: 0.6"
/>
</template>
</q-input>
</div>
<div class="col-12"><q-separator /></div>
<div class="col-12 q-px-sm">
<q-select
class="bg-white"
@ -719,7 +785,9 @@ onMounted(async () => {
hide-selected
:model-value="posType == '' ? 'ทั้งหมด' : posType"
:label="`${
employeeClass == 'officer' ? 'ประเภทตำแหน่ง' : 'กลุ่มงาน'
employeeClass == 'officer'
? 'ประเภทตำแหน่ง'
: 'กลุ่มงาน'
}`"
emit-value
map-options
@ -736,7 +804,9 @@ onMounted(async () => {
<template v-if="posType" v-slot:append>
<q-icon
name="cancel"
@click.stop.prevent="(posType = ''), (posLevel = '')"
@click.stop.prevent="
(posType = ''), (posLevel = '')
"
class="cursor-pointer"
style="opacity: 0.6"
/>
@ -801,7 +871,11 @@ onMounted(async () => {
<q-select
dense
:model-value="position == '' ? 'ทั้งหมด' : position"
label="ตำแหน่งในสายงาน"
:label="`${
employeeClass == 'officer'
? 'ตำแหน่งในสายงาน'
: 'ตำแหน่ง'
}`"
emit-value
map-options
fill-input
@ -834,12 +908,19 @@ onMounted(async () => {
/> </template
></q-select>
</div>
<div class="col-12"> <q-separator /> </div>
<div class="col-12 q-px-sm">
<div class="col-12" v-if="employeeClass === 'officer'">
<q-separator />
</div>
<div
class="col-12 q-px-sm"
v-if="employeeClass === 'officer'"
>
<q-select
label="ตำแหน่งทางการบริหาร"
:model-value="
positionExecutive == '' ? 'ทั้งหมด' : positionExecutive
positionExecutive == ''
? 'ทั้งหมด'
: positionExecutive
"
:options="executiveOps"
emit-value
@ -1000,7 +1081,6 @@ onMounted(async () => {
<template #trigger>
<q-input
dense
:model-value="
dateStart === null ? '' : date2Thai(dateStart)
"
@ -1049,7 +1129,6 @@ onMounted(async () => {
<q-input
dense
:readonly="!dateStart"
:model-value="
dateEnd === null ? '' : date2Thai(dateEnd)
"
@ -1075,7 +1154,6 @@ onMounted(async () => {
<div class="col-12 row">
<div class="text-grey-8 text-caption">วงอาย</div>
<q-space />
<!-- <div class="text-black">{{ rangeAge.min }} - {{ rangeAge.max }}</div> -->
</div>
<div class="q-pa-sm row">
<q-range
@ -1090,22 +1168,40 @@ onMounted(async () => {
dense
><!-- :marker-labels="objMarkerLabel" -->
</q-range>
<div class="col-12 justify-around items-center row no-wrap q-pt-sm">
<div><q-input type="number" style="max-width: 60px" v-model="rangeAge.min" dense standout="bg-teal text-white"/></div>
<div
class="col-12 justify-around items-center row no-wrap q-pt-sm"
>
<div>
<q-input
type="number"
style="max-width: 60px"
v-model="rangeAge.min"
dense
standout="bg-teal text-white"
/>
</div>
<div class="q-px-sm text-grey-8">-</div>
<div><q-input type="number" style="max-width: 60px" v-model="rangeAge.max" dense standout="bg-teal text-white"/></div>
<div>
<q-input
type="number"
style="max-width: 60px"
v-model="rangeAge.max"
dense
standout="bg-teal text-white"
/>
</div>
</div>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="col-12 row q-pl-sm items-center no-wrap">
<div
class="col-12 row q-pl-sm items-center no-wrap"
v-if="employeeClass === 'officer'"
>
<div class="text-grey-8">ทดลองปฏราชการ</div>
<q-space />
<q-toggle
v-model="isProbation"
size="sm"
/>
<q-toggle v-model="isProbation" size="sm" />
</div>
<div class="col-12 row q-pl-sm items-center">
<div class="text-grey-8">แสดงผนจากราชการ</div>
@ -1197,7 +1293,14 @@ onMounted(async () => {
<div class="col-12"><q-separator /></div>
<div class="col-12 row q-pa-sm">
<q-space />
<q-btn dense class="q-px-md" label="ค้นหา" unelevated color="public" type="submit">
<q-btn
dense
class="q-px-md"
label="ค้นหา"
unelevated
color="public"
type="submit"
>
</q-btn>
</div>
</div>
@ -1211,18 +1314,23 @@ onMounted(async () => {
class="row items-center q-pa-sm no-wrap bg-grey-1"
style="border: #c8d3db solid 1px; border-radius: 3px"
>
<div class="text-weight-medium q-pr-md">จำนวนทพบทงหมด</div>
<div class="text-weight-medium q-pr-md">
จำนวนทพบทงหมด
</div>
<q-space />
<q-badge color="primary" class="q-pa-xs">
{{ total.toLocaleString() }}
</q-badge>
</div>
<q-space />
<div class="text-weight-medium q-pr-sm">เรยงตามวนทบรรจเเตงต :</div>
<div class="text-weight-medium q-pr-sm">
เรยงตามวนทบรรจเเตงต :
</div>
<q-btn-dropdown
:label="
sortBy
? sortBy == 'DESC'
? sortBy == 'ASC'
? `(เก่า-ล่าสุด)`
: `(ล่าสุด-เก่า)`
: 'ลำดับการเเสดงผล'
@ -1235,19 +1343,31 @@ onMounted(async () => {
rounded
>
<q-list>
<q-item clickable v-close-popup @click="sortBy = 'ASC'">
<q-item-section>
<q-item-label
>(าส-เก)</q-item-label
<q-item
clickable
v-close-popup
@click="
(sortBy = 'DESC'),
(pagination.sortBy = 'dateAppoint'),
(pagination.descending = true)
"
>
<q-item-section>
<q-item-label>(าส-เก)</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="sortBy = 'DESC'">
<q-item-section>
<q-item-label
>(เก-าส)</q-item-label
<q-item
clickable
v-close-popup
@click="
(sortBy = 'ASC'),
(pagination.sortBy = 'dateAppoint'),
(pagination.descending = false)
"
>
<q-item-section>
<q-item-label>(เก-าส)</q-item-label>
</q-item-section>
</q-item>
</q-list>
@ -1263,7 +1383,11 @@ onMounted(async () => {
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<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>