From d983e0b89e7d029a3015a2fdecb2aeff5666b97e Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 20 Mar 2025 18:16:01 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B8=A3=E0=B8=B2=E0=B8=A2=E0=B8=81=E0=B8=B2?= =?UTF-8?q?=E0=B8=A3=20=E0=B9=81=E0=B8=81=E0=B9=89=E0=B9=84=E0=B8=82?= =?UTF-8?q?=E0=B8=97=E0=B8=B0=E0=B9=80=E0=B8=9A=E0=B8=B5=E0=B8=A2=E0=B8=99?= =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=A7=E0=B8=B1=E0=B8=95=E0=B8=B4?= =?UTF-8?q?=20=E0=B8=95=E0=B8=B3=E0=B9=81=E0=B8=AB=E0=B8=99=E0=B9=88?= =?UTF-8?q?=E0=B8=87/=E0=B9=80=E0=B8=87=E0=B8=B4=E0=B8=99=E0=B9=80?= =?UTF-8?q?=E0=B8=94=E0=B8=B7=E0=B8=AD=E0=B8=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/02_organizational/api.organization.ts | 5 + src/modules/04_registryPerson/router.ts | 2 +- src/modules/04_registryPerson/stores/Edit.ts | 39 + .../views/edit/components/DialogForm.vue | 473 +++++++++++++ .../views/edit/components/FormPosition.vue | 669 ++++++++++++++++++ .../views/edit/components/Table.vue | 524 ++++++++++++++ .../04_registryPerson/views/edit/list.vue | 464 +++++++++++- .../04_registryPerson/views/edit/salary.vue | 225 +++++- 8 files changed, 2373 insertions(+), 28 deletions(-) create mode 100644 src/modules/04_registryPerson/stores/Edit.ts create mode 100644 src/modules/04_registryPerson/views/edit/components/DialogForm.vue create mode 100644 src/modules/04_registryPerson/views/edit/components/FormPosition.vue create mode 100644 src/modules/04_registryPerson/views/edit/components/Table.vue diff --git a/src/api/02_organizational/api.organization.ts b/src/api/02_organizational/api.organization.ts index 76c37250e..41ebc7af1 100644 --- a/src/api/02_organizational/api.organization.ts +++ b/src/api/02_organizational/api.organization.ts @@ -178,4 +178,9 @@ export default { keycloakLogSSO: `${organization}/keycloak/log/sso`, reportOrgByType: (type: string) => `${reportOrg}/registry-${type}`, + + //EditPage + salaryTemp: `${orgProfile}/salaryTemp`, + profileidPosition: (type: string) => + `${orgProfile}${type}/profileid/position`, }; diff --git a/src/modules/04_registryPerson/router.ts b/src/modules/04_registryPerson/router.ts index a509ac585..91df7be5f 100644 --- a/src/modules/04_registryPerson/router.ts +++ b/src/modules/04_registryPerson/router.ts @@ -138,7 +138,7 @@ export default [ }, }, { - path: "/registry/edit/salary/:id", + path: "/registry/edit/salary/:type/:id", name: "registryEditSalary", component: EditListSalaryPage, meta: { diff --git a/src/modules/04_registryPerson/stores/Edit.ts b/src/modules/04_registryPerson/stores/Edit.ts new file mode 100644 index 000000000..4727c2256 --- /dev/null +++ b/src/modules/04_registryPerson/stores/Edit.ts @@ -0,0 +1,39 @@ +import { ref } from "vue"; +import { defineStore } from "pinia"; +import { useQuasar } from "quasar"; + +import { useCounterMixin } from "@/stores/mixin"; + +import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main"; + +const $q = useQuasar(); +const mixin = useCounterMixin(); +const {} = mixin; + +export const useEditPosDataStore = defineStore("EditPos", () => { + const commandCodeData = ref([]); + const posTypeData = ref([]); //รายการประเภทตำแหน่ง | กลุ่มงาน + const posLevelData = ref([]); //รายการระดับตำแหน่ง | ระดับชั้นงาน + const posLineData = ref([]); //รายการสายงาน + const posPathSideData = ref([]); //รายการด้าน/สาขา + const posExecutiveData = ref([]); //รายการตำแหน่งทางการบริหาร + + function convertCommandCodeName(val: string) { + return ( + commandCodeData.value.find((e: DataOption) => e.id === val)?.name ?? "-" + ); + } + + return { + // Data + commandCodeData, + posTypeData, + posLevelData, + posLineData, + posPathSideData, + posExecutiveData, + + // Function + convertCommandCodeName, + }; +}); diff --git a/src/modules/04_registryPerson/views/edit/components/DialogForm.vue b/src/modules/04_registryPerson/views/edit/components/DialogForm.vue new file mode 100644 index 000000000..b71b595da --- /dev/null +++ b/src/modules/04_registryPerson/views/edit/components/DialogForm.vue @@ -0,0 +1,473 @@ + + + + + diff --git a/src/modules/04_registryPerson/views/edit/components/FormPosition.vue b/src/modules/04_registryPerson/views/edit/components/FormPosition.vue new file mode 100644 index 000000000..3a6f31fe3 --- /dev/null +++ b/src/modules/04_registryPerson/views/edit/components/FormPosition.vue @@ -0,0 +1,669 @@ + + + + + diff --git a/src/modules/04_registryPerson/views/edit/components/Table.vue b/src/modules/04_registryPerson/views/edit/components/Table.vue new file mode 100644 index 000000000..2458b2df4 --- /dev/null +++ b/src/modules/04_registryPerson/views/edit/components/Table.vue @@ -0,0 +1,524 @@ + + + + + diff --git a/src/modules/04_registryPerson/views/edit/list.vue b/src/modules/04_registryPerson/views/edit/list.vue index e0b2d52a9..78f8726b4 100644 --- a/src/modules/04_registryPerson/views/edit/list.vue +++ b/src/modules/04_registryPerson/views/edit/list.vue @@ -4,33 +4,287 @@ import { useQuasar } from "quasar"; import http from "@/plugins/http"; import config from "@/app.config"; -import { useRegistryNewDataStore } from "@/modules/04_registryPerson/store"; import { useCounterMixin } from "@/stores/mixin"; import { useRoute, useRouter } from "vue-router"; /** importType*/ -import type { - DataNodeData, - QueryParams, -} from "@/modules/04_registryPerson/interface/request/Main"; -import type { - DataPerson, - DataType, -} from "@/modules/04_registryPerson/interface/response/Main"; +import type { QTableColumn } from "quasar"; const $q = useQuasar(); -const store = useRegistryNewDataStore(); const { showLoader, hideLoader, messageError } = useCounterMixin(); const route = useRoute(); const router = useRouter(); -const empType = ref("officer"); // officer / employee / perm -const dataPersonMain = ref([]); //ข้อมูลรายการที่ค้นหาข้อมูลทะเบียนประวัติ +const organizationOps = ref([]); +const organizationOpsMain = ref([]); +const employeeClassOpsMain = ref([ + { id: "officer", name: "ข้าราชการ กทม.สามัญ" }, + { id: "employee", name: "ลูกจ้างประจำ" }, +]); +const employeeClassOps = ref(employeeClassOpsMain.value); +const statusOpsMain = ref([ + { + id: "ALL", + name: "ทั้งหมด", + }, + { + id: "PENDING", + name: "ยังไม่ได้แก้ไข", + }, + { + id: "EDITED", + name: "แก้ไขแล้ว", + }, + { + id: "CHECKED", + name: "ตรวจสอบแล้ว", + }, +]); +const statusOps = ref(statusOpsMain.value); -const isLoad = ref(false); //โหลดข้อมูลโครงสร้าง +//Table +const organization = ref(""); +const filter = reactive({ + status: "ALL", + empType: "officer", + keyword: "", + page: 1, + pageSize: 10, +}); +const total = ref(0); +const maxPage = ref(0); +const rows = ref([]); +const columns = ref([ + { + name: "posNo", + align: "left", + label: filter.empType === "officer" ? "เลขที่ตำแหน่ง" : "ตำแหน่งเลขที่", + sortable: true, + field: "posNo", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "citizenId", + align: "left", + label: "เลขประจำตัวประชาชน", + sortable: true, + field: "citizenId", + headerStyle: "font-size: 14px; min-width: 200px", + style: "font-size: 14px", + }, + { + name: "fullName", + align: "left", + label: "ชื่อ-นามสกุล", + sortable: true, + field: "fullName", + format(val, row) { + return `${row.prefix}${row.firstName} ${row.lastName}`; + }, + headerStyle: "font-size: 14px; min-width: 200px", + 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: filter.empType === "officer" ? "ตำแหน่งประเภท" : "กลุ่มงาน", + sortable: true, + field: "posType", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "posLevel", + align: "left", + label: filter.empType === "officer" ? "ระดับ" : "ระดับชั้นงาน", + sortable: true, + field: "posLevel", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + format(val, row) { + return row.posTypeShortName + ? row.posTypeShortName + " " + row.posLevel + : row.posLevel; + }, + }, + { + name: "org", + align: "left", + label: "สังกัด", + sortable: true, + field: "org", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + }, + { + name: "statusCheckEdit", + align: "left", + label: "สถานะ", + sortable: true, + field: "statusCheckEdit", + format(val, row) { + return statusOpsMain.value.find((e) => e.id === val)?.name; + }, + headerStyle: "font-size: 14px;pointer-events: none;", + style: "font-size: 14px", + }, +]); +const visibleColumns = ref([ + "posNo", + "citizenId", + "fullName", + "position", + "posType", + "posLevel", + "org", + "statusCheckEdit", +]); + +/** function fetch ข้อมูลโครงสร้างปัจจุบัน*/ +async function fetchActiveOrg() { + showLoader(); + http + .get(config.API.activeOrganization) + .then((res) => { + const data = res.data.result; + fetchListOrg(data.activeId); + }) + .catch((err) => { + messageError($q, err); + hideLoader(); + }); +} + +/** + * function fetch ข้อมูลหน่วยงาน + * @param id โครงสร้างปัจจุบัน + */ +function fetchListOrg(id: string) { + showLoader(); + http + .get(config.API.orgByIdSystem(id, route.meta.Key as string)) + .then(async (res) => { + const data = await res.data.result.map((item: any) => ({ + id: item.orgTreeId, + name: item.orgName, + })); + organizationOpsMain.value = data; + organizationOps.value = data; + }) + .catch((err) => { + messageError($q, err); + }) + .finally(() => { + hideLoader(); + }); +} + +/** + * function ค้นหาคำใน select + * @param val คำค้นหา + * @param update function + * @param type ประเภท select + */ +function filterSelector(val: string, update: Function, type: string) { + switch (type) { + case "organization": + update(() => { + organizationOps.value = organizationOpsMain.value.filter( + (v: any) => v.name.toLowerCase().indexOf(val) > -1 + ); + }); + break; + case "employeeClass": + update(() => { + employeeClassOps.value = employeeClassOpsMain.value.filter( + (v: any) => v.name.toLowerCase().indexOf(val) > -1 + ); + }); + break; + + case "status": + update(() => { + statusOps.value = statusOpsMain.value.filter( + (v: any) => v.name.toLowerCase().indexOf(val) > -1 + ); + }); + break; + default: + break; + } +} + +/** function fetch รายการแก้ไขทะเบียนประวัติ ตำแหน่ง/เงินเดือน*/ +function fetchData() { + let queryParams = { + page: filter.page, + pageSize: filter.pageSize, + type: filter.empType?.toLocaleUpperCase(), + searchKeyword: filter.keyword, + statusCheckEdit: filter.status?.toLocaleUpperCase(), + rootId: organization.value, + }; + + if (organization.value !== "" && filter.empType !== "") { + rows.value = []; + showLoader(); + http + .get(config.API.salaryTemp, { params: queryParams }) + .then((res) => { + const data = res.data.result; + total.value = data.total; + maxPage.value = Math.ceil(data.total / filter.pageSize); + rows.value = data.data; + }) + .catch((err) => { + messageError($q, err); + }) + .finally(() => { + hideLoader(); + }); + } +} + +/** + * function ค้นหาข้อมูล + * @param val true จะค้นหาหน้าแรก + */ +function onSearchData(val: boolean = true) { + if (val) { + filter.page = 1; + } + + fetchData(); +} + +/** + * function เปลี่ยนแถวต่อหน้า + * @param newPagination ข้อมูล Pagination + */ +function updatePageSize(newPagination: any) { + filter.pageSize = newPagination.rowsPerPage; + onSearchData(); +} + +function onRedirectToPosition(id: string, type: string) { + const tyepeLower = type?.toLocaleLowerCase(); + router.push(`/registry/edit/salary/${tyepeLower}/${id}`); +} /** hook เมื่อมีการเรียกใช้ Components*/ -onMounted(async () => {}); +onMounted(async () => { + await fetchActiveOrg(); +}); diff --git a/src/modules/04_registryPerson/views/edit/salary.vue b/src/modules/04_registryPerson/views/edit/salary.vue index a5207b19d..07f297ed5 100644 --- a/src/modules/04_registryPerson/views/edit/salary.vue +++ b/src/modules/04_registryPerson/views/edit/salary.vue @@ -9,36 +9,235 @@ import { useCounterMixin } from "@/stores/mixin"; import { useRoute, useRouter } from "vue-router"; /** importType*/ -import type { - DataNodeData, - QueryParams, -} from "@/modules/04_registryPerson/interface/request/Main"; -import type { - DataPerson, - DataType, -} from "@/modules/04_registryPerson/interface/response/Main"; + +import Table from "@/modules/04_registryPerson/views/edit/components/Table.vue"; const $q = useQuasar(); const store = useRegistryNewDataStore(); -const { showLoader, hideLoader, messageError } = useCounterMixin(); +const { showLoader, hideLoader, messageError, dialogConfirm, findOrgName } = + useCounterMixin(); const route = useRoute(); const router = useRouter(); -const empType = ref("officer"); // officer / employee / perm -const dataPersonMain = ref([]); //ข้อมูลรายการที่ค้นหาข้อมูลทะเบียนประวัติ +const dataProfile = ref(); +const tabs = ref("PENDING"); +const empType = ref(route.params.type.toString()); +const profileId = ref(route.params.id.toString()); -const isLoad = ref(false); //โหลดข้อมูลโครงสร้าง +async function fetchDataProfile() { + showLoader(); + await http + .get( + config.API.profileidPosition( + empType.value === "officer" ? "" : "-employee" + ) + `/${profileId.value}` + ) + .then(async (res) => { + const data = res.data.result; + dataProfile.value = { + fullName: `${data.prefix}${data.firstName} ${data.lastName}`, + position: data.position, + citizenId: data.citizenId, + posNo: data.posNo, + posType: data.posTypeName, + posLevel: data.posLevelName, + org: findOrgName(data), + }; + }) + .catch((err) => { + messageError($q, err); + }) + .finally(() => { + hideLoader(); + }); +} + +function onConfirmEdit() { + dialogConfirm( + $q, + () => { + showLoader(); + http + .post(config.API.salaryTemp + `/confirm-edit`, { + profileId: profileId.value, + type: empType.value, + }) + .then((res) => {}) + .catch((err) => { + messageError($q, err); + }) + .finally(() => { + hideLoader(); + }); + }, + "ยืนยันเสร็จสิ้นการแก้ไข", + "ต้องการยืนยันเสร็จสิ้นการแก้ไขใช่หรือไม่?" + ); +} + +function onConfirmDone() { + dialogConfirm( + $q, + () => { + showLoader(); + http + .post(config.API.salaryTemp + `/confirm-done`, { + profileId: profileId.value, + type: empType.value, + }) + .then((res) => {}) + .catch((err) => { + messageError($q, err); + }) + .finally(() => { + hideLoader(); + }); + }, + "ยืนยันข้อมูลถูกต้อง", + "ต้องการยืนยันข้อมูลถูกต้องใช่หรือไม่" + ); +} /** hook เมื่อมีการเรียกใช้ Components*/ -onMounted(async () => {}); +onMounted(async () => { + fetchDataProfile(); +});