หน้าที่ความรับผิดชอบ
diff --git a/src/modules/02_organization/components/TableMain.vue b/src/modules/02_organization/components/TableMain.vue
index 7d8a2756b..b307970f0 100644
--- a/src/modules/02_organization/components/TableMain.vue
+++ b/src/modules/02_organization/components/TableMain.vue
@@ -9,6 +9,7 @@ import { checkPermission } from "@/utils/permissions";
import { updateCurrentPage } from "@/utils/function";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
+import { formatPosmasterNo } from "@/utils/function";
/** importType*/
import type { QTableProps } from "quasar";
@@ -205,6 +206,14 @@ const columns = ref([
sortable: false,
field: "posMasterNo",
headerStyle: "font-size: 14px",
+ format(val, row) {
+ return formatPosmasterNo(
+ row.orgShortname,
+ row.posMasterNoPrefix,
+ row.posMasterNoMain,
+ row.posMasterNoSuffix
+ );
+ },
style: "font-size: 14px",
},
{
@@ -1124,7 +1133,7 @@ watch(
{
posLevelName: e.isSit ? e.profilePoslevel : e.posLevelName,
posExecutiveName: e.posExecutiveName,
isSit: e.isSit,
+ orgShortname: e.orgShortname,
+ posMasterNoPrefix: e.posMasterNoPrefix,
+ posMasterNoSuffix: e.posMasterNoSuffix,
+ posMasterNoMain: e.posMasterNo,
+
}));
return newPosMaster || [];
diff --git a/src/modules/03_recruiting/components/Table.vue b/src/modules/03_recruiting/components/Table.vue
index b5f2877f6..6ff82cda4 100644
--- a/src/modules/03_recruiting/components/Table.vue
+++ b/src/modules/03_recruiting/components/Table.vue
@@ -56,6 +56,7 @@ const optionsStatus = ref([
{ label: "ขาดสอบ", value: "missed_exam" },
{ label: "ผ่าน", value: "pass" },
{ label: "ไม่ผ่าน", value: "notpass" },
+ { label: "อื่น ๆ", value: "other" },
]);
const emit = defineEmits([
diff --git a/src/modules/03_recruiting/components/TableCandidate.vue b/src/modules/03_recruiting/components/TableCandidate.vue
index f5b1b2b21..d725a3bc1 100644
--- a/src/modules/03_recruiting/components/TableCandidate.vue
+++ b/src/modules/03_recruiting/components/TableCandidate.vue
@@ -363,37 +363,59 @@ async function downloadFileDashboard() {
}
async function clickPassExam() {
- showLoader();
- await http
- .get(config.API.downloadPassExam(examId.value))
- .then(async (res) => {
- const data = res.data.result;
- data.reportName = `Candidate_Dashboard_${dateToISO(new Date())}`;
- await genReport(data, data.reportName, "pdf");
- })
- .catch((e) => {
- messageError($q, e);
- })
- .finally(() => {
- hideLoader();
- });
+ try {
+ showLoader();
+ const res = await http.get(
+ config.API.downloadCandidatePassExam(examId.value),
+ {
+ headers: {
+ "Content-Type": "application/pdf",
+ Accept: "application/pdf",
+ },
+ responseType: "blob",
+ }
+ );
+ const url = window.URL.createObjectURL(new Blob([res.data]));
+ const link = document.createElement("a");
+ link.href = url;
+ link.setAttribute(
+ "download",
+ `Candidate_Dashboard_${dateToISO(new Date())}` + ".pdf"
+ );
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
}
async function clickCandidateList() {
- showLoader();
- await http
- .get(config.API.downloadCandidateExam(examId.value))
- .then(async (res) => {
- const data = res.data.result;
- data.reportName = `Candidate_Dashboard_${dateToISO(new Date())}`;
- await genReport(data, data.reportName, "pdf");
- })
- .catch((e) => {
- messageError($q, e);
- })
- .finally(() => {
- hideLoader();
+ try {
+ showLoader();
+ const res = await http.get(config.API.downloadCandidateExam(examId.value), {
+ headers: {
+ "Content-Type": "application/pdf",
+ Accept: "application/pdf",
+ },
+ responseType: "blob",
});
+ const url = window.URL.createObjectURL(new Blob([res.data]));
+ const link = document.createElement("a");
+ link.href = url;
+ link.setAttribute("download", "รายชื่อผู้มีสิทธิ์สอบ" + ".pdf");
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
}
async function onCheckShowExaminfo() {
@@ -549,8 +571,20 @@ watch(
-
- ดาวน์โหลดไฟล์
+
+
+ {{
+ attrs.rows.length !== 0
+ ? "ดาวน์โหลดไฟล์"
+ : "ไม่มีข้อมูลผู้สอบคัดเลือก"
+ }}
จัดการรอบสอบแข่งขัน
+
{
นำเข้าไฟล์ผู้สมัครสอบ
@@ -715,6 +849,9 @@ onMounted(async () => {
{
round
color="green"
@click.stop.prevent="clickEdit(props.row.id)"
- v-if="
- col.value == null && checkPermission($route)?.attrIsUpdate
- "
>
@@ -751,6 +885,11 @@ onMounted(async () => {
{
color="green"
round
@click.stop.prevent="clickResult(props.row.id)"
- v-if="
- (props.row.score == null ||
- props.row.score.resultCount == 0) &&
- checkPermission($route)?.attrIsUpdate
- "
>
นำเข้าไฟล์ผลการสอบ (บัญชีรายชื่อ)
@@ -921,12 +1055,12 @@ onMounted(async () => {
+
-
@@ -965,12 +1099,12 @@ onMounted(async () => {
+
-
@@ -1009,12 +1143,12 @@ onMounted(async () => {
+
-
diff --git a/src/modules/03_recruiting/views/01_compete/PeriodAdd.vue b/src/modules/03_recruiting/views/01_compete/PeriodAdd.vue
index 8cab7895c..68d8df9ae 100644
--- a/src/modules/03_recruiting/views/01_compete/PeriodAdd.vue
+++ b/src/modules/03_recruiting/views/01_compete/PeriodAdd.vue
@@ -2,11 +2,13 @@
import { onMounted, ref, watch, computed } from "vue";
import { useQuasar, QForm } from "quasar";
import { useRouter, useRoute } from "vue-router";
+import { storeToRefs } from "pinia";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { calculateFiscalYear } from "@/utils/function";
+import { usePositionKeycloakStore } from "@/stores/positionKeycloak";
import type { RequestPeriodCompete } from "@/modules/03_recruiting/interface/request/Period";
import type {
@@ -16,6 +18,7 @@ import type {
const $q = useQuasar(); // show dialog
const mixin = useCounterMixin();
+const { dataPositionKeycloak } = storeToRefs(usePositionKeycloakStore());
const router = useRouter();
const route = useRoute();
const {
@@ -53,6 +56,7 @@ const fileImgDataUpload = ref([]);
const fileImgs = ref([]);
const id = ref("");
const edit = ref(false);
+const scoreExpireDate = ref(null); //วันหมดอายุบัญชี
/** กลับไปหน้าหลัก */
function clickBack() {
@@ -98,6 +102,7 @@ async function fetchData() {
fileDocs.value = files;
fileImgs.value = images;
+ scoreExpireDate.value = data.scoreExpireDate;
})
.catch((e) => {
messageError($q, e);
@@ -253,6 +258,11 @@ function sendData() {
year: yearly.value,
announcementDate:
dateAnnounce.value !== null ? convertDateToAPI(dateAnnounce.value) : null,
+ scoreExpireDate:
+ scoreExpireDate.value !== null
+ ? convertDateToAPI(scoreExpireDate.value)
+ : null,
+ rootDnaId: !edit.value ? dataPositionKeycloak.value.rootDnaId : undefined,
};
return valueData;
}
@@ -355,6 +365,13 @@ function dateThaiRange(val: [Date, Date]) {
return `${date2Thai(val[0], true)} - ${date2Thai(val[1], true)}`;
}
}
+function onUpdateScoreExpireDate(val: Date | null) {
+ if (val) {
+ const newDate = new Date(val);
+ newDate.setFullYear(newDate.getFullYear() + 2);
+ scoreExpireDate.value = newDate;
+ }
+}
watch(organizationShortName, (count: DataOption2, prevCount: DataOption2) => {
organizationNameOptions.value = [];
@@ -451,6 +468,7 @@ onMounted(async () => {
+
{
input-class="text-right"
>
+
{
+
{
+
{
dateRegister != null ? dateThaiRange(dateRegister) : null
"
:label="`${'วันที่สมัคร'}`"
+ hide-bottom-space
>
{
+
{
"
:label="`${'วันที่ชำระเงิน'}`"
:rules="[(val:string) => !!val || `${'กรุณาเลือกวันที่ชำระเงิน'}`]"
+ hide-bottom-space
>
{
borderless
:enableTimePicker="false"
week-start="0"
+ @update:model-value="onUpdateScoreExpireDate"
>
{{ year + 543 }}
@@ -649,6 +674,48 @@ onMounted(async () => {
"
:label="`${'วันประกาศผลสอบ'}`"
:rules="[(val:string) => !!val || `${'กรุณาเลือกวันประกาศผลสอบ'}`]"
+ hide-bottom-space
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+
+
+ {{ parseInt(value + 543) }}
+
+
+
0) {
data.map((r: ResponseRecruitPeriod) => {
if (r.score != null) {
- r.scoreCount = r.score.scoreCount;
- r.scoreImportDate = r.score.importDate;
+ r.scoreCount = r.score.scoreCount ? r.score.scoreCount : 0;
+ r.scoreImportDate = r.score.importDate ? r.score.importDate : "-";
}
result.push(r);
});
@@ -715,7 +715,11 @@ onMounted(async () => {
นำเข้าไฟล์ผลคะแนนสอบ
- {{ props.row.score.scoreCount.toLocaleString() }}
+ {{
+ props.row.score
+ ? props.row.score.scoreCount.toLocaleString()
+ : "-"
+ }}
{
นำเข้าไฟล์ผลการสอบ (บัญชีรายชื่อ)
- {{ props.row.score.resultCount.toLocaleString() }}
+ {{
+ props.row.score
+ ? props.row.score.resultCount.toLocaleString()
+ : "-"
+ }}
([]);
const organizationShortName = ref({ id: "", name: "" });
const organizationName = ref({ id: "", name: "" });
const organizationNameOptions = ref([]);
-
+const scoreExpireDate = ref(null); //วันหมดอายุบัญชี
const fileDocDataUpload = ref([]);
const fileDocs = ref([]);
const fileImgDataUpload = ref([]);
@@ -90,6 +93,7 @@ async function fetchData() {
data.announcementDate != null ? new Date(data.announcementDate) : null;
fileDocs.value = data.documents;
fileImgs.value = data.images;
+ scoreExpireDate.value = data.scoreExpireDate;
})
.catch((e) => {
messageError($q, e);
@@ -159,6 +163,11 @@ function sendData() {
year: yearly.value,
announcementDate:
dateAnnounce.value !== null ? convertDateToAPI(dateAnnounce.value) : null,
+ rootDnaId: !edit.value ? dataPositionKeycloak.value.rootDnaId : undefined,
+ scoreExpireDate:
+ scoreExpireDate.value !== null
+ ? convertDateToAPI(scoreExpireDate.value)
+ : null,
};
return valueData;
}
@@ -348,6 +357,14 @@ function dateThaiRange(val: [Date, Date] | null) {
}
}
+function onUpdateScoreExpireDate(val: Date | null) {
+ if (val) {
+ const newDate = new Date(val);
+ newDate.setFullYear(newDate.getFullYear() + 2);
+ scoreExpireDate.value = newDate;
+ }
+}
+
watch(organizationShortName, (count: DataOption2, prevCount: DataOption2) => {
organizationNameOptions.value = [];
});
@@ -386,7 +403,7 @@ onMounted(async () => {
-
+
{
(val:string) =>
!!val || `${'กรุณากรอกชื่อรอบคัดเลือก/ชื่อประกาศ'}`,
]"
+ hide-bottom-space
>
+
{
dense
lazy-rules
:rules="[(val:number) => val > 0 || `${'กรุณากรอกรอบการสอบให้ถูกต้อง'}`]"
+ hide-bottom-space
>
+
{
:model-value="yearly + 543"
:rules="[(val:string) => !!val || `${'กรุณาเลือกปีงบประมาณ'}`]"
:label="`${'ปีงบประมาณ'}`"
+ hide-bottom-space
>
{
:rules="[
(val:any) => val >= 0 || `${'กรุณากรอกค่าธรรมเนียมให้ถูกต้อง'}`,
]"
+ hide-bottom-space
>
@@ -480,6 +503,7 @@ onMounted(async () => {
:model-value="dateExam != null ? date2Thai(dateExam) : null"
:label="`${'วันที่สอบ'}`"
:rules="[(val:string) => !!val || `${'กรุณาเลือกวันที่สอบ'}`]"
+ hide-bottom-space
>
{
{
{
{
borderless
:enableTimePicker="false"
week-start="0"
+ @update:model-value="onUpdateScoreExpireDate"
>
{{ year + 543 }}
@@ -629,12 +657,54 @@ onMounted(async () => {
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+
+
+ {{ parseInt(value + 543) }}
+
+
+
("");
+const scoreExpireDate = ref(null);
const fileDocDataUpload = ref([]);
const fileDocs = ref([]);
@@ -333,6 +334,7 @@ async function fetchData() {
refNo1.value = data.refNo1;
reason.value = data.reason;
graduationYearLock.value = data.graduationYearLock;
+ scoreExpireDate.value = data.scoreExpireDate;
})
.catch((e) => {
messageError($q, e);
@@ -506,6 +508,10 @@ function sendData() {
refNo1: refNo1.value,
reason: reason.value,
graduationYearLock: Number(graduationYearLock.value),
+ scoreExpireDate:
+ scoreExpireDate.value != null
+ ? convertDateToAPI(scoreExpireDate.value)
+ : null,
};
return valueData;
}
@@ -939,6 +945,14 @@ watch(
}
);
+function onUpdateScoreExpireDate(val: Date | null) {
+ if (val) {
+ const newDate = new Date(val);
+ newDate.setFullYear(newDate.getFullYear() + 2);
+ scoreExpireDate.value = newDate;
+ }
+}
+
onMounted(async () => {
hideLoader();
if (route.params.id != undefined) {
@@ -1242,6 +1256,7 @@ onMounted(async () => {
borderless
:enableTimePicker="false"
week-start="0"
+ @update:model-value="onUpdateScoreExpireDate"
>
{{ year + 543 }}
@@ -1275,21 +1290,63 @@ onMounted(async () => {
-
-
-
+
+
+ {{ year + 543 }}
+
+
+ {{ parseInt(value + 543) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ type="number"
+ >
diff --git a/src/modules/04_registryPerson/components/detail/GovernmentInformation/02_Discipline.vue b/src/modules/04_registryPerson/components/detail/GovernmentInformation/02_Discipline.vue
index a726a067f..3be9068cb 100644
--- a/src/modules/04_registryPerson/components/detail/GovernmentInformation/02_Discipline.vue
+++ b/src/modules/04_registryPerson/components/detail/GovernmentInformation/02_Discipline.vue
@@ -16,9 +16,11 @@ import type {
DisciplineOps,
DataOption,
} from "@/modules/04_registryPerson/interface/index/discipline";
+import type { Discipline } from "@/modules/04_registryPerson/interface/response/Discipline";
import DialogHeader from "@/components/DialogHeader.vue";
import DialogHistory from "@/modules/04_registryPerson/components/detail/DialogHistory.vue";
+import DialogPreviewCommand from "@/modules/18_command/components/DialogPreviewCommand.vue";
const route = useRoute();
const $q = useQuasar();
@@ -47,6 +49,9 @@ const empType = ref
(pathRegistryEmp(route.name?.toString() ?? ""));
const isLeave = defineModel("isLeave", {
required: true,
});
+const citizenId = defineModel("citizenId", {
+ required: true,
+});
const baseColumns = ref([
{
@@ -152,8 +157,8 @@ const baseVisibleColumns = ref([
"lastUpdatedAt",
]);
-const rows = ref([]); //รายการวินัย
-const rowsMain = ref([]); //รายการวินัย
+const rows = ref([]); //รายการวินัย
+const rowsMain = ref([]); //รายการวินัย
const mode = ref("table"); //การแสดงผล Table card
const filterKeyword = ref(""); //คำค้นหา
@@ -244,6 +249,10 @@ const fileUpload = ref(null);
const fileData = ref(null);
const isUpload = ref(false);
+const modalCommand = ref(false);
+const command = ref("");
+const commandId = ref("");
+
/**
* function ค้นหา คำใน option
* @param val คำค้นหา
@@ -305,7 +314,7 @@ async function fetchData(id: string) {
* กดเลือกข้อมูลที่จะแก้ไข
* @param props ค่า props ใน row ที่เลือก
*/
-async function openDialogEdit(props: RequestItemsObject) {
+async function openDialogEdit(props: Discipline) {
showLoader();
try {
modal.value = true;
@@ -478,6 +487,12 @@ function handleDelete(id: string) {
});
}
+function openViewCommand(data: Discipline) {
+ command.value = data.refCommandNo;
+ commandId.value = data.refCommandId;
+ modalCommand.value = true;
+}
+
/** ทำงานเมื่อ Components ถูกเรียกใช้งาน*/
onMounted(() => {
fetchData(profileId.value);
@@ -621,7 +636,19 @@ onMounted(() => {
:key="col.id"
:class="props.row.isEntry ? 'text-grey' : ''"
>
-
+
+ {{ col.value ? col.value : "-" }}
+ ดูคำสั่ง
+
+
{{ col.value ? col.value : "-" }}
@@ -975,6 +1002,13 @@ onMounted(() => {
:visible-columns="visibleColumnsHistory"
:fetch-data="fetchDataHistory"
/>
+
+
diff --git a/src/modules/04_registryPerson/components/detail/GovernmentInformation/06_HelpGovernment.vue b/src/modules/04_registryPerson/components/detail/GovernmentInformation/06_HelpGovernment.vue
index c97cbb2c3..71a7e3bd5 100644
--- a/src/modules/04_registryPerson/components/detail/GovernmentInformation/06_HelpGovernment.vue
+++ b/src/modules/04_registryPerson/components/detail/GovernmentInformation/06_HelpGovernment.vue
@@ -866,7 +866,8 @@ onMounted(() => {
outlined
dense
:model-value="date2Thai(formData.dateEnd)"
- :rules="[(val:string) => !!val || `${'กรุณาเลือก วันที่สิ้นสุด'}`]"
+ clearable
+ @clear="formData.dateEnd = null"
hide-bottom-space
:label="`${'วันที่สิ้นสุด'}`"
>
diff --git a/src/modules/04_registryPerson/components/detail/GovernmentInformation/Main.vue b/src/modules/04_registryPerson/components/detail/GovernmentInformation/Main.vue
index 3f30cf12e..189faa16b 100644
--- a/src/modules/04_registryPerson/components/detail/GovernmentInformation/Main.vue
+++ b/src/modules/04_registryPerson/components/detail/GovernmentInformation/Main.vue
@@ -58,7 +58,10 @@ const storeRegistry = useRegistryNewDataStore();
-
+
diff --git a/src/modules/04_registryPerson/components/detail/PersonalInformation/01_Profile.vue b/src/modules/04_registryPerson/components/detail/PersonalInformation/01_Profile.vue
index 7730029f7..0b2bca785 100644
--- a/src/modules/04_registryPerson/components/detail/PersonalInformation/01_Profile.vue
+++ b/src/modules/04_registryPerson/components/detail/PersonalInformation/01_Profile.vue
@@ -96,11 +96,11 @@ const columnsHistory = ref([
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
- name: "prefix",
+ name: "prefixMain",
align: "left",
label: "คำนำหน้าชื่อ",
sortable: true,
- field: "prefix",
+ field: "prefixMain",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
@@ -256,7 +256,7 @@ const columnsHistory = ref([
]);
const visibleColumnsHistory = ref([
"citizenId",
- "prefix",
+ "prefixMain",
"rank",
"firstName",
"lastName",
@@ -408,7 +408,8 @@ function calculateMinDate() {
function prefixRankRule() {
return [
- () => !!formData.rank || !!formData.prefix || "กรุณาเลือกคำนำหน้าชื่อ หรือยศ",
+ () =>
+ !!formData.rank || !!formData.prefix || "กรุณาเลือกคำนำหน้าชื่อ หรือยศ",
];
}
@@ -588,6 +589,8 @@ onMounted(() => {
{
option-value="name"
v-model="formData.prefix"
clearable
- class="inputgreen"
:options="store.Ops.prefixOps"
:label="dataLabel.prefix"
:rules="prefixRankRule()"
@@ -640,24 +642,24 @@ onMounted(() => {
@@ -721,6 +723,7 @@ onMounted(() => {
{
option-label="name"
option-value="name"
v-model="formData.gender"
- class="inputgreen"
:options="store.Ops.genderOps"
:label="dataLabel.gender"
@filter="(inputValue: string,
diff --git a/src/modules/04_registryPerson/components/detail/PersonalInformation/02_NameChangeHistory.vue b/src/modules/04_registryPerson/components/detail/PersonalInformation/02_NameChangeHistory.vue
index cbe7f361e..06b598ad8 100644
--- a/src/modules/04_registryPerson/components/detail/PersonalInformation/02_NameChangeHistory.vue
+++ b/src/modules/04_registryPerson/components/detail/PersonalInformation/02_NameChangeHistory.vue
@@ -59,6 +59,7 @@ const changeNameData = reactive({
profileId: profileId.value,
prefixId: "", // id คำนำหน้า
prefix: "", // คำนำหน้า
+ rank: "", // ยศ
firstName: "", // ชื่อ
lastName: "", // นามสกุล
status: "", // สถานะ
@@ -69,11 +70,13 @@ const selection = ref([]); // ตัวเลือก
const prefixChange = ref(""); // เปลี่ยนคำนำหน้า
const firstNameChange = ref(""); // เปลียนชื่อ
const lastNameChange = ref(""); // เปลี่ยนนามสกุล
+const rankChange = ref(""); // เปลี่ยนยศ
const profileInfo = ref(); // ข้อมูล Profile
const statusOption = ref([
"เปลี่ยนคำนำหน้าชื่อ",
+ "เปลี่ยนยศ",
"เปลี่ยนชื่อ",
"เปลี่ยนนามสกุล",
"เปลี่ยนชื่อ-นามสกุล",
@@ -84,6 +87,7 @@ const statusOption = ref([
const statusOptionFilter = ref([
"เปลี่ยนคำนำหน้าชื่อ",
"เปลี่ยนชื่อ",
+ "เปลี่ยนยศ",
"เปลี่ยนนามสกุล",
"เปลี่ยนชื่อ-นามสกุล",
"เปลี่ยนคำนำหน้าชื่อ และชื่อ",
@@ -107,6 +111,17 @@ const columns = ref([
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
+ {
+ name: "rank",
+ align: "left",
+ label: "ยศ",
+ sortable: true,
+ field: "rank",
+ headerStyle: "font-size: 14px",
+ style: "font-size: 14px",
+ sort: (a: string, b: string) =>
+ a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
+ },
{
name: "firstName",
align: "left",
@@ -156,6 +171,7 @@ const columns = ref([
]);
const visibleColumns = ref([
"prefix",
+ "rank",
"firstName",
"lastName",
"lastUpdateFullName",
@@ -215,6 +231,7 @@ function onSubmit() {
firstName: changeNameData.firstName,
lastName: changeNameData.lastName,
status: changeNameData.status,
+ rank: changeNameData.rank,
documentId: changeNameData.documentId,
})
.then(async (res) => {
@@ -346,6 +363,14 @@ function filterSelector(val: string, update: Function, refData: string) {
);
});
break;
+
+ case "rankOps":
+ update(() => {
+ store.Ops.rankOps = store.OpsFilter.rankOps.filter(
+ (v: DataOption) => v.name.indexOf(val) > -1
+ );
+ });
+ break;
default:
break;
}
@@ -390,12 +415,14 @@ watch(
changeNameData.prefix,
changeNameData.firstName,
changeNameData.lastName,
+ changeNameData.rank,
],
() => {
submitDisable.value =
changeNameData.prefix === prefixChange.value &&
changeNameData.firstName === firstNameChange.value &&
- changeNameData.lastName === lastNameChange.value;
+ changeNameData.lastName === lastNameChange.value &&
+ changeNameData.rank === rankChange.value;
}
);
@@ -411,6 +438,9 @@ watch(
if (!selection.value.includes("lastname")) {
changeNameData.lastName = lastNameChange.value;
}
+ if (!selection.value.includes("rank")) {
+ changeNameData.rank = rankChange.value;
+ }
}
);
/** ทำงานเมื่อ Components ถูกเรียกใช้งาน*/
@@ -448,9 +478,11 @@ onMounted(async () => {
changeNameData.prefix = profileInfo?.prefixMain;
changeNameData.firstName = profileInfo?.firstName;
changeNameData.lastName = profileInfo?.lastName;
+ changeNameData.rank = profileInfo?.rank;
prefixChange = changeNameData.prefix;
firstNameChange = changeNameData.firstName;
lastNameChange = changeNameData.lastName;
+ rankChange = changeNameData.rank;
changeNameData.status = '';
dialogStatus = 'create';
submitDisable = true;
@@ -533,7 +565,7 @@ onMounted(async () => {
:class="props.row.isEntry ? 'text-grey' : ''"
>
- {{ col.value }}
+ {{ col.value ? col.value : "-" }}
@@ -563,12 +595,17 @@ onMounted(async () => {
-
+
+
{
) "
/>
+
+ filterSelector(inputValue, doneFn,'rankOps'
+ ) "
+ />
+
{
{
id: "posNo",
name:
- route.name === "registryNew" ||
- route.name === "registryRetireOfficer"
+ route.name === "registryNew" || route.name === "registryRetireOfficer"
? "เลขที่ตำแหน่ง"
: "ตำแหน่งเลขที่",
},
@@ -130,6 +129,8 @@ export const useRegistryNewDataStore = defineStore("registryNew", () => {
return "ให้ออกจากราชการ";
case "DISCIPLINE_TEMP_SUSPEND":
return "ให้ออกจากราชการไว้ก่อน";
+ case "RETIRE_MILITARY":
+ return "ลาออกเพื่อไปรับราชการทหาร";
default:
return "";
}
diff --git a/src/modules/04_registryPerson/views/detailView.vue b/src/modules/04_registryPerson/views/detailView.vue
index 33ca37200..1318ed468 100644
--- a/src/modules/04_registryPerson/views/detailView.vue
+++ b/src/modules/04_registryPerson/views/detailView.vue
@@ -121,7 +121,8 @@ const itemsMenu = computed(() => {
if (
leaveType.value === "DISCIPLINE_TEMP_SUSPEND" ||
leaveType.value === "RETIRE_RESIGN" ||
- leaveType.value === "DISCIPLINE_SUSPEND"
+ leaveType.value === "DISCIPLINE_SUSPEND" ||
+ leaveType.value === "RETIRE_MILITARY"
) {
return (
baseItemsMenu.value?.filter(
@@ -323,10 +324,10 @@ async function uploadFileURL(uploadUrl: string, file: any) {
* ฟังก์ชันดึงข้อมูลรูปโปรไฟล์
* @param id โปรไฟล์
*/
-async function fetchProfile(id: string) {
- await http
+function fetchProfile(id: string) {
+ http
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, fileName.value))
- .then(async (res) => {
+ .then((res) => {
profilePicture.value = res.data.downloadUrl;
})
.catch(() => {
@@ -403,7 +404,7 @@ async function fetchDataPersonal() {
fileName.value = res.data.result.avatarName;
if (formDetail.value?.avatarName) {
- await fetchProfile(profileId.value);
+ fetchProfile(profileId.value);
} else {
profilePicture.value = avatar;
}
@@ -857,7 +858,8 @@ onMounted(async () => {
])) ||
leaveType === 'DISCIPLINE_TEMP_SUSPEND' ||
leaveType === 'RETIRE_RESIGN' ||
- leaveType === 'DISCIPLINE_SUSPEND'
+ leaveType === 'DISCIPLINE_SUSPEND' ||
+ leaveType === 'RETIRE_MILITARY'
"
size="md"
rounded
diff --git a/src/modules/04_registryPerson/views/edit/components/Table.vue b/src/modules/04_registryPerson/views/edit/components/Table.vue
index f470254c6..da180ac32 100644
--- a/src/modules/04_registryPerson/views/edit/components/Table.vue
+++ b/src/modules/04_registryPerson/views/edit/components/Table.vue
@@ -437,66 +437,6 @@ function classColorRow(isDelete: boolean, isEdit: boolean, isEntry: boolean) {
/** ฟังก์ชันดาวน์โหลดไฟล Excel */
function exportToExcel() {
exportToExcelPosition(rows.value);
- // const newData = rows.value.map((e: DataPosition) => {
- // return {
- // commandDateAffect: date2Thai(e.commandDateAffect),
- // positionName: e.positionName,
- // positionType: e.positionType,
- // positionLevel: e.positionLevel
- // ? e.positionLevel
- // : e.positionCee
- // ? e.positionCee
- // : "",
- // positionExecutive: e.positionExecutive,
- // amount: e.amount,
- // mouthSalaryAmount: e.mouthSalaryAmount,
- // positionSalaryAmount: e.positionSalaryAmount,
- // organization: findOrgName({
- // root: e.orgRoot,
- // child1: e.orgChild1,
- // child2: e.orgChild2,
- // child3: e.orgChild3,
- // child4: e.orgChild4,
- // }),
- // posNo:
- // e.posNoAbb && e.posNo
- // ? `${e.posNoAbb} ${e.posNo}`
- // : e.posNo
- // ? e.posNo
- // : "",
- // posNumCodeSit:
- // e.posNumCodeSitAbb && e.posNumCodeSit
- // ? `${e.posNumCodeSit} (${e.posNumCodeSitAbb})`
- // : e.posNumCodeSit
- // ? e.posNumCodeSit
- // : "",
- // commandNo:
- // e.commandNo && e.commandYear
- // ? `${e.commandNo}/${Number(e.commandYear) + 543}`
- // : "",
- // commandDateSign: date2Thai(e.commandDateSign),
- // commandCode: store.convertCommandCodeName(e.commandCode),
- // remark: e.remark,
- // };
- // });
-
- // const headers = columns.value.map((item: any) => item.label) || []; // หัวคอลัมน์ภาษาไทย
- // const worksheet = XLSX.utils.json_to_sheet(newData, {
- // header: visibleColumns.value,
- // });
-
- // //แทรกหัวคอลัมน์ภาษาไทย (ใช้ A1, B1, C1 แทน)
- // XLSX.utils.sheet_add_aoa(worksheet, [headers], { origin: "A1" });
-
- // // Create a new workbook and append the worksheet
- // const workbook = XLSX.utils.book_new();
-
- // XLSX.utils.book_append_sheet(
- // workbook,
- // worksheet,
- // `รายการประวัติตำแหน่งเงินเดือน`
- // );
- // XLSX.writeFile(workbook, "รายการประวัติตำแหน่งเงินเดือน.xlsx");
}
const commandCodeOptions = ref(store.commandCodeData); //รายการปรเภทคำสั่ง
@@ -931,6 +871,29 @@ function onCancelUpload() {
excelPreviewModal.value = false;
}
+/** ฟังก์ชันจัดเรียงข้อมูลตามวันที่*/
+function handleSortByDate() {
+ dialogConfirm(
+ $q,
+ async () => {
+ try {
+ showLoader();
+ await http.put(config.API.sortOrderByDate, {
+ type: empType.value.toLocaleUpperCase(),
+ profileId: profileId.value,
+ });
+ await fetchData();
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+ },
+ "ยืนยันการจัดลำดับ",
+ "ต้องการยืนยันการจัดลำดับข้อมูลตามวันที่คำสั่งมีผลใช่หรือไม่?"
+ );
+}
+
onMounted(async () => {
await Promise.all([fetchData(), fetchType()]);
});
@@ -966,8 +929,23 @@ onMounted(async () => {
icon="mdi-sort"
@click="modalSort = true"
>
- จัดลำดับข้อมูลจัดลำดับข้อมูล
+
+
+
+ จัดลำดับตามวันที่คำสั่งมีผล
+
{
:model-value="
dateEnd !== null ? date2Thai(dateEnd) : null
"
- :rules="edit ? [(val:string) => !!val || `${'กรุณาเลือกตั้งแต่วัน'}`]:[]"
hide-bottom-space
:label="`${'ถึงวันที่'}`"
+ clearable
+ @clear="dateEnd = null"
>
-
+
diff --git a/src/modules/05_placement/components/PersonalList/DialogDetail.vue b/src/modules/05_placement/components/PersonalList/DialogDetail.vue
index 13aa09aef..dff09ffdd 100644
--- a/src/modules/05_placement/components/PersonalList/DialogDetail.vue
+++ b/src/modules/05_placement/components/PersonalList/DialogDetail.vue
@@ -525,14 +525,14 @@ watch(props, () => {
{{ personalForm?.pass }}
{{ personalForm?.examNumber }}
-
{{ personalForm?.examRound }}
+
diff --git a/src/modules/05_placement/components/PersonalList/DialogOrders.vue b/src/modules/05_placement/components/PersonalList/DialogOrders.vue
index 8ac613a5f..c7d70b924 100644
--- a/src/modules/05_placement/components/PersonalList/DialogOrders.vue
+++ b/src/modules/05_placement/components/PersonalList/DialogOrders.vue
@@ -242,7 +242,7 @@ watch(
v.code === "C-PM-04" ||
v.code === "C-PM-06")) ||
((status?.examTypeName === "สอบคัดเลือก" ||
- status?.examTypeName === "คัดเลือกคนพิการ") &&
+ status?.examTypeName === "คัดเลือกอื่นๆ") &&
(v.code === "C-PM-02" ||
v.code === "C-PM-03" ||
v.code === "C-PM-04" ||
diff --git a/src/modules/05_placement/components/PersonalList/DialogSelectOrg.vue b/src/modules/05_placement/components/PersonalList/DialogSelectOrg.vue
index e54741069..ad1028738 100644
--- a/src/modules/05_placement/components/PersonalList/DialogSelectOrg.vue
+++ b/src/modules/05_placement/components/PersonalList/DialogSelectOrg.vue
@@ -165,7 +165,9 @@ async function fetchDataTable(id: string, level: number = 0) {
(e) => e !== props.dataRow?.posmasterId
);
- positionNo.value = posMain.filter((e: DataPositionNo) => !newUse.includes(e.id));
+ positionNo.value = posMain.filter(
+ (e: DataPositionNo) => !newUse.includes(e.id)
+ );
} else {
positionNo.value = posMain.filter(
(e: DataPositionNo) => !positionUse.value.includes(e.id)
@@ -241,6 +243,7 @@ async function onClickSubmit() {
posLevelId: selectedPos.value[0].posLevelId, //ชื่อตำแหน่ง
posLevelName: selectedPos.value[0].posLevelName, //ชื่อตำแหน่ง
posExecutiveName: selectedPos.value[0].posExecutiveName,
+ posExecutiveId: selectedPos.value[0].posExecutiveId,
reportingDate: convertDateToAPI(datePos.value),
posmasterId: dataPosMaster.id,
positionExecutiveField: selectedPos.value[0].positionExecutiveField, //ด้านทางการบริหาร
@@ -290,7 +293,10 @@ watch(
if (modal.value) {
await fetchPositionUes();
if (props?.dataRow?.node !== null && props?.dataRow?.nodeId !== null) {
- await fetchPosFind(props?.dataRow?.node ?? 0, props?.dataRow?.nodeId ?? "");
+ await fetchPosFind(
+ props?.dataRow?.node ?? 0,
+ props?.dataRow?.nodeId ?? ""
+ );
} else {
expanded.value = [];
}
@@ -345,7 +351,7 @@ function onPosType() {
watch(
[isAll, isBlank, () => isPosition.value],
([newAll, newBlank, newPos], [oldAll, oldBlank, oldPos]) => {
- const shouldFetch = (newAll !== oldAll) || (newBlank !== oldBlank);
+ const shouldFetch = newAll !== oldAll || newBlank !== oldBlank;
const isSelectMode = newPos === "select" && oldPos !== "select";
if (shouldFetch || isSelectMode) {
diff --git a/src/modules/05_placement/components/PersonalList/Table.vue b/src/modules/05_placement/components/PersonalList/Table.vue
index 1d43085e9..1e151ee01 100644
--- a/src/modules/05_placement/components/PersonalList/Table.vue
+++ b/src/modules/05_placement/components/PersonalList/Table.vue
@@ -1,5 +1,5 @@
+
@@ -249,6 +280,33 @@ watch(
+
filterSelector(inputValue, doneFn
+ ) "
+ >
+
+
+
+ ไม่มีข้อมูล
+
+
+
+
@@ -341,7 +399,7 @@ watch(
diff --git a/src/modules/06_retirement/components/02_resign/ResignByid.vue b/src/modules/06_retirement/components/02_resign/ResignByid.vue
index 4d4dac874..b17345bea 100644
--- a/src/modules/06_retirement/components/02_resign/ResignByid.vue
+++ b/src/modules/06_retirement/components/02_resign/ResignByid.vue
@@ -47,6 +47,7 @@ const {
success,
dialogConfirm,
dialogRemove,
+ convertDateToAPI,
} = mixin;
/** ตัวแปร */
@@ -477,9 +478,8 @@ function onSubmitConditions() {
function onSubmitAttached() {
dialogConfirm($q, async () => {
const formData = new FormData();
- const send = date.value !== null ? new Date(date.value).toUTCString() : "";
- const activeDate =
- dateLeave.value !== null ? new Date(dateLeave.value).toUTCString() : "";
+ const send: string = convertDateToAPI(date.value) ?? "";
+ const activeDate: string = convertDateToAPI(dateLeave.value) ?? "";
formData.append("Location", location.value);
formData.append("SendDate", send);
formData.append("ActiveDate", activeDate);
@@ -771,10 +771,13 @@ onMounted(async () => {
(route.name == "resignDetailreject");
@@ -313,9 +314,8 @@ async function clickCancel() {
function onSubmitAttached() {
dialogConfirm($q, () => {
const formData = new FormData();
- const send = date.value !== null ? new Date(date.value).toUTCString() : "";
- const activeDate =
- dateLeave.value !== null ? new Date(dateLeave.value).toUTCString() : "";
+ const send: string = convertDateToAPI(date.value) ?? "";
+ const activeDate: string = convertDateToAPI(dateLeave.value) ?? "";
formData.append("Location", location.value);
formData.append("SendDate", send);
formData.append("ActiveDate", activeDate);
@@ -439,7 +439,7 @@ onMounted(async () => {
class="q-mr-sm"
@click="router.push('/retirement/resign')"
/>
- รายละเอียดการยกเลิกลาออก
+ รายละเอียดการยกเลิกลาออก
{{
dataDetail.prefix + dataDetail.firstName + " " + dataDetail.lastName
}}
diff --git a/src/modules/06_retirement/components/02_resign/Table.vue b/src/modules/06_retirement/components/02_resign/Table.vue
index b5769dc33..c4a1001b8 100644
--- a/src/modules/06_retirement/components/02_resign/Table.vue
+++ b/src/modules/06_retirement/components/02_resign/Table.vue
@@ -33,7 +33,8 @@ const {
showLoader,
hideLoader,
onSearchDataTable,
- findOrgName,
+ dialogRemove,
+ success,
} = mixin;
/** Table */
@@ -257,6 +258,21 @@ function onSearch() {
);
}
+function handleDelete(id: string) {
+ dialogRemove($q, async () => {
+ try {
+ showLoader();
+ await http.delete(config.API.listResign() + `/admin/${id}`);
+ await fecthlist();
+ success($q, "ลบข้อมูลสำเร็จ");
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+ });
+}
+
/**Hook */
onMounted(async () => {
status.value = stroeResign.formQurey.status;
@@ -308,7 +324,11 @@ onMounted(async () => {
color="primary"
icon="mdi-account-arrow-right"
>
- {{ `ส่งไปออกคำสั่ง${stroeResign.mainTabs == '2'?"ยกเลิกการ":''}ลาออก` }}
+ {{
+ `ส่งไปออกคำสั่ง${
+ stroeResign.mainTabs == "2" ? "ยกเลิกการ" : ""
+ }ลาออก`
+ }}
@@ -393,6 +413,26 @@ onMounted(async () => {
>
แก้ไขข้อมูล
+
+
+ ลบข้อมูล
+
{
{
const formData = new FormData();
- const send = date.value !== null ? new Date(date.value).toUTCString() : "";
- const activeDate =
- dateLeave.value !== null ? new Date(dateLeave.value).toUTCString() : "";
+ const send: string = convertDateToAPI(date.value) ?? "";
+ const activeDate: string = convertDateToAPI(dateLeave.value) ?? "";
+
formData.append("Location", location.value);
formData.append("SendDate", send);
formData.append("ActiveDate", activeDate);
diff --git a/src/modules/06_retirement/components/03_resignEmp/Table.vue b/src/modules/06_retirement/components/03_resignEmp/Table.vue
index 89a181576..7eeee2f80 100644
--- a/src/modules/06_retirement/components/03_resignEmp/Table.vue
+++ b/src/modules/06_retirement/components/03_resignEmp/Table.vue
@@ -27,8 +27,15 @@ const stroeResign = useDataStore();
const { statusText } = stroe;
const router = useRouter();
const mixin = useCounterMixin();
-const { messageError, date2Thai, showLoader, hideLoader, onSearchDataTable } =
- mixin;
+const {
+ messageError,
+ date2Thai,
+ showLoader,
+ hideLoader,
+ onSearchDataTable,
+ dialogRemove,
+ success,
+} = mixin;
/** Table */
const rows = ref([]);
@@ -129,7 +136,7 @@ const columns = ref([
sortable: true,
field: "status",
format(val, row) {
- return stroeResign.mainTabs === "1"
+ return stroeResign.mainTabsEMP === "1"
? statusText(row.status)
: statusText(row.status, "อนุญาต");
},
@@ -252,6 +259,21 @@ function onSearch() {
);
}
+function handleDelete(id: string) {
+ dialogRemove($q, async () => {
+ try {
+ showLoader();
+ await http.delete(config.API.listResignEMP() + `/admin/${id}`);
+ await fecthlist();
+ success($q, "ลบข้อมูลสำเร็จ");
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+ });
+}
+
/**Hook */
onMounted(async () => {
statusEMP.value = stroeResign.formQureyEMP.status;
@@ -391,6 +413,26 @@ onMounted(async () => {
>
แก้ไขข้อมูล
+
+
+ ลบข้อมูล
+
-
{{
- getColumnLabel(col, isAct)
- }}
+
{{ col.label }}
diff --git a/src/modules/08_registryEmployee/components/DialogSelectPos.vue b/src/modules/08_registryEmployee/components/DialogSelectPos.vue
index 7602cb043..222890238 100644
--- a/src/modules/08_registryEmployee/components/DialogSelectPos.vue
+++ b/src/modules/08_registryEmployee/components/DialogSelectPos.vue
@@ -5,6 +5,7 @@ import { useQuasar } from "quasar";
import { useRoute } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { useStructureTree } from "@/stores/structureTree";
+import { formatPosmasterNo } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -74,7 +75,12 @@ const columns = ref
([
sortable: true,
field: "posMasterNo",
format(val, row) {
- return `${row.orgShortname} ${row.posMasterNo}`;
+ return formatPosmasterNo(
+ row.orgShortname,
+ row.posMasterNoPrefix,
+ row.posMasterNo.toString(),
+ row.posMasterNoSuffix
+ );
},
headerStyle: "font-size: 14px",
style: "font-size: 14px",
diff --git a/src/modules/09_leave/components/01_RoundTime/DialogForm.vue b/src/modules/09_leave/components/01_RoundTime/DialogForm.vue
index c6883cb11..8eaf9c6b5 100644
--- a/src/modules/09_leave/components/01_RoundTime/DialogForm.vue
+++ b/src/modules/09_leave/components/01_RoundTime/DialogForm.vue
@@ -212,7 +212,7 @@ watch(
:close="close"
/>
-
+
@@ -362,6 +362,7 @@ watch(
+
@@ -513,6 +514,7 @@ watch(
+
+ />
+
@@ -541,6 +544,7 @@ watch(
+
@@ -559,6 +563,7 @@ watch(
+
diff --git a/src/modules/09_leave/components/02_WorkList/Tab4_Pending.vue b/src/modules/09_leave/components/02_WorkList/Tab4_Pending.vue
new file mode 100644
index 000000000..60637c6b6
--- /dev/null
+++ b/src/modules/09_leave/components/02_WorkList/Tab4_Pending.vue
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+ ไม่มีข้อมูล
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/09_leave/components/04_SpecialTime/DialogApprove.vue b/src/modules/09_leave/components/04_SpecialTime/DialogApprove.vue
index 2eb7b2cd0..af47e1dcf 100644
--- a/src/modules/09_leave/components/04_SpecialTime/DialogApprove.vue
+++ b/src/modules/09_leave/components/04_SpecialTime/DialogApprove.vue
@@ -96,8 +96,8 @@ watch(
formData.checkOut = "";
formData.note = "";
} else if (props.editCheck === "PENDING") {
- if (props.detailData) {
- if (props.detailData.checkInEdit) {
+ if (props.detailData) {
+ if (props.detailData.checkInEdit && props.detailData.checkOutEdit) {
formData.checkIn = props.detailData.startTimeMorning;
formData.checkOut = props.detailData.endTimeAfternoon;
} else if (
diff --git a/src/modules/09_leave/components/04_SpecialTime/DialogMultipleApprove.vue b/src/modules/09_leave/components/04_SpecialTime/DialogMultipleApprove.vue
new file mode 100644
index 000000000..0caf9f339
--- /dev/null
+++ b/src/modules/09_leave/components/04_SpecialTime/DialogMultipleApprove.vue
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ year + 543 }}
+
+
+ {{ parseInt(value + 543) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ *หมายเหตุเลือกทั้งหมดเฉพาะรายการที่แสดงเท่านั้น
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ props.rowIndex + 1 }}
+
+
+ {{ col.value ?? "-" }}
+
+
+ {{ col.value ?? "-" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ บันทึก
+
+
+
+
+
+
+
+
diff --git a/src/modules/09_leave/components/05_Leave/Calendar.vue b/src/modules/09_leave/components/05_Leave/Calendar.vue
index 14665b235..eff336884 100644
--- a/src/modules/09_leave/components/05_Leave/Calendar.vue
+++ b/src/modules/09_leave/components/05_Leave/Calendar.vue
@@ -228,8 +228,12 @@ onMounted(async () => {
-
-
+
-
+
+
+ ผู้มีอำนาจยังไม่ได้พิจารณา ใบลานี้ถูกยกเลิกแล้ว
+
+
+
+
diff --git a/src/modules/09_leave/components/05_Leave/DetailLeaveReject.vue b/src/modules/09_leave/components/05_Leave/DetailLeaveReject.vue
index 6653eed35..51b2f5a29 100644
--- a/src/modules/09_leave/components/05_Leave/DetailLeaveReject.vue
+++ b/src/modules/09_leave/components/05_Leave/DetailLeaveReject.vue
@@ -1,5 +1,5 @@
@@ -46,6 +51,7 @@ const isPermissionTab3 = computed(() => {
name="3"
label="ประมวลผลการขาดราชการ/มาสาย"
/>
+
@@ -62,6 +68,9 @@ const isPermissionTab3 = computed(() => {
+
+
+
diff --git a/src/modules/09_leave/views/04_SpecialTimeMain.vue b/src/modules/09_leave/views/04_SpecialTimeMain.vue
index 1ea9ec44b..5c7890cdf 100644
--- a/src/modules/09_leave/views/04_SpecialTimeMain.vue
+++ b/src/modules/09_leave/views/04_SpecialTimeMain.vue
@@ -17,6 +17,7 @@ import type {
import DialogReason from "@/components/Dialogs/PopupReason.vue";
import DialogApprove from "@/modules/09_leave/components/04_SpecialTime/DialogApprove.vue";
+import DialogMultipleApprove from "@/modules/09_leave/components/04_SpecialTime/DialogMultipleApprove.vue";
const $q = useQuasar(); // show dialog
const mixin = useCounterMixin();
@@ -47,6 +48,7 @@ const name = ref
("");
const id = ref("");
const dateDialog = ref("");
const dateFixDialog = ref("");
+const modalMultiple = ref(false);
// ค้นหาในตาราง
const filterKeyword = ref("");
@@ -54,7 +56,7 @@ const filterStatus = ref("PENDING");
const filterDate = ref<[Date, Date] | null>([new Date(), new Date()]); //วันที่ประกาศ
const optionStatus = ref(store.optionStatusMain);
const rows = ref([]);
-const visibleColumns = ref([
+const visibleColumns = ref([
"no",
"fullName",
"createdAt",
@@ -283,6 +285,20 @@ onMounted(async () => {
รายการลงเวลากรณีพิเศษ
+
+
+ อนุมัติแบบหลายรายการ
+
@@ -492,6 +508,14 @@ onMounted(async () => {
:detailData="detailData"
:fetch-data="fetchData"
/>
+
+
diff --git a/src/modules/12_evaluatePersonal/components/Detail/Tab1.vue b/src/modules/12_evaluatePersonal/components/Detail/Tab1.vue
index 854f43546..db954abf1 100644
--- a/src/modules/12_evaluatePersonal/components/Detail/Tab1.vue
+++ b/src/modules/12_evaluatePersonal/components/Detail/Tab1.vue
@@ -50,7 +50,7 @@ const id = ref(route.params.id as string); // id รายการป
const isLoadView = ref(false); //แสดง view
const modalHistory = ref(false); //แสดง popup ประวัติการประเมิน
// ข้อมูลผู้เซ็นเอกสาร
-const formCommand = reactive({
+const formCommand = reactive({
elementaryFullName: "", //ชื่อผู้บังคับบัญชาชั้นต้น
elementaryPosition: "", //ตำแหน่งผู้บังคับบัญชาชั้นต้น
abovelevelFullname: "", //ชื่อผู้บังคับบัญชาเหนือขึ้นไป 1 ระดับ
diff --git a/src/modules/12_evaluatePersonal/store/Evaluate.ts b/src/modules/12_evaluatePersonal/store/Evaluate.ts
index 96e37b202..e0c57c316 100644
--- a/src/modules/12_evaluatePersonal/store/Evaluate.ts
+++ b/src/modules/12_evaluatePersonal/store/Evaluate.ts
@@ -58,6 +58,7 @@ export const useEvalutuonStore = defineStore("EvalutuonStore", () => {
const dataList: EvaluateList[] = data.map(
(data: EvaluateRes) =>
({
+ ...data,
id: data.id,
citizenId: data.citizenId,
fullName: data.fullName,
@@ -133,7 +134,7 @@ export const useEvalutuonStore = defineStore("EvalutuonStore", () => {
align: "left",
label: "เลขที่ตำแหน่ง",
sortable: true,
- field: "positionNumber",
+ field: "posNo",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
diff --git a/src/modules/12_evaluatePersonal/views/MainPage.vue b/src/modules/12_evaluatePersonal/views/MainPage.vue
index 98676a9fa..c58d47d0f 100644
--- a/src/modules/12_evaluatePersonal/views/MainPage.vue
+++ b/src/modules/12_evaluatePersonal/views/MainPage.vue
@@ -351,7 +351,7 @@ onMounted(async () => {
- {{ !col.value ? "-" : col.value }}
+ {{ col.value ? col.value : "-" }}
diff --git a/src/modules/13_salary/components/04_salaryLists/DialogAddPerson.vue b/src/modules/13_salary/components/04_salaryLists/DialogAddPerson.vue
index 7804d91fc..77f843078 100644
--- a/src/modules/13_salary/components/04_salaryLists/DialogAddPerson.vue
+++ b/src/modules/13_salary/components/04_salaryLists/DialogAddPerson.vue
@@ -5,6 +5,7 @@ import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
import { usePagination } from "@/composables/usePagination";
+import { formatPosmasterNo } from "@/utils/function";
import config from "@/app.config";
import http from "@/plugins/http";
@@ -72,9 +73,12 @@ const columns = ref
([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
- return row.orgShortName && row.posMasterNo
- ? `${row.orgShortName} ${row.posMasterNo}`
- : "-";
+ return formatPosmasterNo(
+ row.orgShortName,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
},
},
{
diff --git a/src/modules/13_salary/components/04_salaryLists/TableTypeOther.vue b/src/modules/13_salary/components/04_salaryLists/TableTypeOther.vue
index 2de930508..fadcd0acc 100644
--- a/src/modules/13_salary/components/04_salaryLists/TableTypeOther.vue
+++ b/src/modules/13_salary/components/04_salaryLists/TableTypeOther.vue
@@ -19,6 +19,7 @@ import DialogMoveLevel from "@/modules/13_salary/components/04_salaryLists/Dialo
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
+import { formatPosmasterNo } from "@/utils/function";
/** use*/
const $q = useQuasar();
@@ -87,9 +88,12 @@ const baseColumns = ref([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
- return row.orgShortName && row.posMasterNo
- ? `${row.orgShortName} ${row.posMasterNo}`
- : "-";
+ return formatPosmasterNo(
+ row.orgShortName,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
},
},
{
diff --git a/src/modules/13_salary/components/04_salaryLists/TableTypePending.vue b/src/modules/13_salary/components/04_salaryLists/TableTypePending.vue
index dde372515..c6b5fd7d2 100644
--- a/src/modules/13_salary/components/04_salaryLists/TableTypePending.vue
+++ b/src/modules/13_salary/components/04_salaryLists/TableTypePending.vue
@@ -19,6 +19,7 @@ import DialogInfo from "@/modules/13_salary/components/DialogInfoMain.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
+import { formatPosmasterNo } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -98,9 +99,12 @@ const columns = ref([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
- return row.orgShortName && row.posMasterNo
- ? `${row.orgShortName} ${row.posMasterNo}`
- : "-";
+ return formatPosmasterNo(
+ row.orgShortName,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
},
},
{
diff --git a/src/modules/13_salary/components/05_salaryListsEmployee/DialogAddPerson.vue b/src/modules/13_salary/components/05_salaryListsEmployee/DialogAddPerson.vue
index e39563a7e..82f7ef43e 100644
--- a/src/modules/13_salary/components/05_salaryListsEmployee/DialogAddPerson.vue
+++ b/src/modules/13_salary/components/05_salaryListsEmployee/DialogAddPerson.vue
@@ -5,6 +5,7 @@ import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryEmployeeListSDataStore } from "@/modules/13_salary/store/SalaryEmployeeListsStore";
import { usePagination } from "@/composables/usePagination";
+import { formatPosmasterNo } from "@/utils/function";
import config from "@/app.config";
import http from "@/plugins/http";
@@ -71,9 +72,12 @@ const columns = ref([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
- return row.orgShortName && row.posMasterNo
- ? `${row.orgShortName} ${row.posMasterNo}`
- : "-";
+ return formatPosmasterNo(
+ row.orgShortName,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
},
},
{
diff --git a/src/modules/13_salary/components/05_salaryListsEmployee/TableTypeOther.vue b/src/modules/13_salary/components/05_salaryListsEmployee/TableTypeOther.vue
index b2e24205c..db57d2c78 100644
--- a/src/modules/13_salary/components/05_salaryListsEmployee/TableTypeOther.vue
+++ b/src/modules/13_salary/components/05_salaryListsEmployee/TableTypeOther.vue
@@ -5,6 +5,7 @@ import { useQuasar } from "quasar";
import { checkPermission } from "@/utils/permissions";
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryEmployeeListSDataStore } from "@/modules/13_salary/store/SalaryEmployeeListsStore";
+import { formatPosmasterNo } from "@/utils/function";
import config from "@/app.config";
import http from "@/plugins/http";
@@ -84,6 +85,14 @@ const baseColumns = ref([
field: "orgShortName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
+ format(val, row) {
+ return formatPosmasterNo(
+ row.orgShortName,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
+ },
},
{
name: "position",
diff --git a/src/modules/13_salary/components/05_salaryListsEmployee/TableTypePending.vue b/src/modules/13_salary/components/05_salaryListsEmployee/TableTypePending.vue
index addcdb8e8..a9559193f 100644
--- a/src/modules/13_salary/components/05_salaryListsEmployee/TableTypePending.vue
+++ b/src/modules/13_salary/components/05_salaryListsEmployee/TableTypePending.vue
@@ -6,6 +6,7 @@ import { checkPermission } from "@/utils/permissions";
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryEmployeeListSDataStore } from "@/modules/13_salary/store/SalaryEmployeeListsStore";
+import { formatPosmasterNo } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -98,9 +99,12 @@ const columns = ref([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
- return row.orgShortName && row.posMasterNo
- ? `${row.orgShortName} ${row.posMasterNo}`
- : "-";
+ return formatPosmasterNo(
+ row.orgShortName,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
},
},
diff --git a/src/modules/13_salary/components/DialogInfoMain.vue b/src/modules/13_salary/components/DialogInfoMain.vue
index 3da947277..c5bfc6762 100644
--- a/src/modules/13_salary/components/DialogInfoMain.vue
+++ b/src/modules/13_salary/components/DialogInfoMain.vue
@@ -52,7 +52,7 @@ function fetchInformation() {
citizenId.value = data.citizenId;
if (data.avatarName) {
- await fetchProfile(data.id as string, data.avatarName);
+ fetchProfile(data.id as string, data.avatarName);
} else {
avatar.value = avatarMain;
}
@@ -70,11 +70,14 @@ function fetchInformation() {
* @param id profileId
* @param avatarName ชื้อไฟล์
*/
-async function fetchProfile(id: string, avatarName: string) {
+function fetchProfile(id: string, avatarName: string) {
http
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, avatarName))
- .then(async (res) => {
+ .then((res) => {
avatar.value = res.data.downloadUrl;
+ })
+ .catch(() => {
+ avatar.value = avatarMain;
});
}
diff --git a/src/modules/14_KPI/views/detail.vue b/src/modules/14_KPI/views/detail.vue
index aede8c187..81d3df41a 100644
--- a/src/modules/14_KPI/views/detail.vue
+++ b/src/modules/14_KPI/views/detail.vue
@@ -8,6 +8,7 @@ import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import { useKpiDataStore } from "@/modules/14_KPI/store";
+import avatar from "@/assets/avatar_user.jpg";
import DialogHeader from "@/components/DialogHeader.vue";
import type { FormProfile } from "@/modules/14_KPI/interface/request/index";
@@ -65,7 +66,7 @@ async function fetchEvaluation() {
await store.checkCompetency();
await store.checkCompetencyDefaultCompetencyLevel();
- await fetchProfile(data.profileId);
+ fetchProfile(data.profileId);
plannedPoint.value = data.plannedPoint == null ? "" : data.plannedPoint;
rolePoint.value = data.rolePoint == null ? "" : data.rolePoint;
@@ -81,8 +82,8 @@ async function fetchEvaluation() {
// });
}
-async function fetchProfile(id: string) {
- await http
+function fetchProfile(id: string) {
+ http
.get(
config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, `profile-${id}`)
)
@@ -90,6 +91,7 @@ async function fetchProfile(id: string) {
store.dataEvaluation.avartar = res.data.downloadUrl;
})
.catch(() => {
+ store.dataEvaluation.avartar = avatar;
// profilePicture.value = avatar;
});
}
diff --git a/src/modules/16_positionEmployee/components/DialogMovePos.vue b/src/modules/16_positionEmployee/components/DialogMovePos.vue
index 97fd67813..96539fc61 100644
--- a/src/modules/16_positionEmployee/components/DialogMovePos.vue
+++ b/src/modules/16_positionEmployee/components/DialogMovePos.vue
@@ -50,7 +50,7 @@ const modal = defineModel("modal", { required: true });
let reqMaster = defineModel("reqMaster", { required: true });
const totalPage = defineModel("totalPage", { required: true });
const nodeTree = defineModel("nodeTree", { required: true });
-const columns = defineModel("columns", {});
+const columns = defineModel("columns", { required: true });
const rows = defineModel("rows", { required: true });
const props = defineProps({
fetchDataTree: {
diff --git a/src/modules/16_positionEmployee/components/DialogSuccession.vue b/src/modules/16_positionEmployee/components/DialogSuccession.vue
index 7674c2df8..ab23c6dd1 100644
--- a/src/modules/16_positionEmployee/components/DialogSuccession.vue
+++ b/src/modules/16_positionEmployee/components/DialogSuccession.vue
@@ -5,6 +5,7 @@ import { useQuasar } from "quasar";
import { useRoute } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { usePositionEmp } from "@/modules/16_positionEmployee/store/organizational";
+import { formatPosmasterNo } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -135,11 +136,12 @@ async function fetchTable() {
const data = res.data.result.data;
const list = data.map((e: PosMaster) => ({
...e,
- posMasterNo:
- (e.orgShortname !== null ? e.orgShortname : "") +
- (e.posMasterNoPrefix ? e.posMasterNoPrefix : "") +
- (e.posMasterNo !== null ? e.posMasterNo : "") +
- (e.posMasterNoSuffix !== null ? e.posMasterNoPrefix : ""),
+ posMasterNo: formatPosmasterNo(
+ e.orgShortname,
+ e.posMasterNoPrefix,
+ e.posMasterNo.toString(),
+ e.posMasterNoSuffix ?? ""
+ ),
}));
rows.value = list;
})
@@ -157,7 +159,7 @@ function updatePagination(newPagination: NewPagination) {
reqMaster.page = 1;
}
-/**
+/**
funcion ค้นหาข้อมูลใน Table
*/
async function filterKeyword() {
diff --git a/src/modules/16_positionEmployee/components/TableMain.vue b/src/modules/16_positionEmployee/components/TableMain.vue
index f56a0ab4e..cd8e93380 100644
--- a/src/modules/16_positionEmployee/components/TableMain.vue
+++ b/src/modules/16_positionEmployee/components/TableMain.vue
@@ -5,7 +5,7 @@ import { useQuasar } from "quasar";
import { usePositionEmp } from "@/modules/16_positionEmployee/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
import { checkPermission } from "@/utils/permissions";
-import { updateCurrentPage } from "@/utils/function";
+import { updateCurrentPage, formatPosmasterNo } from "@/utils/function";
import genreport from "@/plugins/genreportxlsx";
import config from "@/app.config";
import http from "@/plugins/http";
@@ -145,6 +145,13 @@ const columns = ref([
label: "ตำแหน่งเลขที่",
sortable: false,
field: "posMasterNo",
+ format: (val: any, row: any) =>
+ formatPosmasterNo(
+ row.orgShortname,
+ row.posMasterNoPrefix,
+ row.posMasterNoMain,
+ row.posMasterNoSuffix
+ ),
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
@@ -777,7 +784,7 @@ watch(
{
posLevelName: e.isSit ? e.profilePoslevel : e.posLevelName,
posExecutiveName: e.posExecutiveName,
isSit: e.isSit,
+ orgShortname: e.orgShortname,
+ posMasterNoPrefix: e.posMasterNoPrefix,
+ posMasterNoMain: e.posMasterNo,
+ posMasterNoSuffix: e.posMasterNoSuffix,
}));
return newPosMaster;
diff --git a/src/modules/18_command/components/Step/1_Detail.vue b/src/modules/18_command/components/Step/1_Detail.vue
index 2a3f3b60f..0c3755cfb 100644
--- a/src/modules/18_command/components/Step/1_Detail.vue
+++ b/src/modules/18_command/components/Step/1_Detail.vue
@@ -113,8 +113,6 @@ const visibleColumns = ref>([
const modalAddOperator = ref(false); // แสดงเพิ่มรายชื่อลงนามในแนบท้ายคำสั่ง
-
-
/**
* ฟังก์ชันบันทึกข้อมูลรายละเอียดคำสั่ง
* และกำหนด isChangeData เป็น false
@@ -225,6 +223,8 @@ onMounted(async () => {
formData.commandExcecuteDate = props.formCommandList.commandExcecuteDate;
formData.isBangkok = !store.isIdofficer
? null
+ : props.formCommandList.commandCode === "C-PM-47"
+ ? "BANGKOK"
: props.formCommandList.isBangkok;
commandCode.value = props.formCommandList.commandCode;
const [volume, chapter] = props.formCommandList.commandNo.split("/");
@@ -486,12 +486,9 @@ onMounted(async () => {
/>
-
+
{
/>
{
:key="col.name"
:props="props"
>
- {{
- getColumnLabel(col, isAct)
- }}
+ {{ col.label }}
diff --git a/src/modules/19_condition/view/Main.vue b/src/modules/19_condition/view/Main.vue
index 585e60005..9eb28f71f 100644
--- a/src/modules/19_condition/view/Main.vue
+++ b/src/modules/19_condition/view/Main.vue
@@ -6,6 +6,7 @@ import { storeToRefs } from "pinia";
import { useCounterMixin } from "@/stores/mixin";
import { useRoute } from "vue-router";
import { useStructureTree } from "@/stores/structureTree";
+import { formatPosmasterNo } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -71,8 +72,18 @@ const columns = ref([
field: "posMasterNo",
format(val, row) {
return row.isSit
- ? `${row.orgShortname} ${row.posMasterNo}(นั่งทับตำแหน่ง)`
- : `${row.orgShortname} ${row.posMasterNo}`;
+ ? formatPosmasterNo(
+ row.orgShortname,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ ) + " (นั่งทับตำแหน่ง)"
+ : formatPosmasterNo(
+ row.orgShortname,
+ row.posMasterNoPrefix,
+ row.posMasterNo,
+ row.posMasterNoSuffix
+ );
},
headerStyle: "font-size: 14px",
style: "font-size: 14px",
@@ -207,7 +218,7 @@ async function fetchDataTree() {
function onSelectedOrgTree(data: OrgTree) {
orgTreeId.value = data.orgTreeId;
orgLevel.value = data.orgLevel;
- fetchDataTable();
+ onSearchDataTable();
}
/**
diff --git a/src/modules/20_positionTemp/components/DialogMovePos.vue b/src/modules/20_positionTemp/components/DialogMovePos.vue
index c3815f1c3..e00d143b8 100644
--- a/src/modules/20_positionTemp/components/DialogMovePos.vue
+++ b/src/modules/20_positionTemp/components/DialogMovePos.vue
@@ -50,7 +50,7 @@ const modal = defineModel("modal", { required: true });
let reqMaster = defineModel("reqMaster", { required: true });
const totalPage = defineModel("totalPage", { required: true });
const nodeTree = defineModel("nodeTree", { required: true });
-const columns = defineModel("columns", {});
+const columns = defineModel("columns", {});
const rows = defineModel("rows", { required: true });
const props = defineProps({
fetchDataTree: {
diff --git a/src/modules/20_positionTemp/components/DialogSelectPerson.vue b/src/modules/20_positionTemp/components/DialogSelectPerson.vue
index 6498094be..0c6ca2dac 100644
--- a/src/modules/20_positionTemp/components/DialogSelectPerson.vue
+++ b/src/modules/20_positionTemp/components/DialogSelectPerson.vue
@@ -706,7 +706,7 @@ watch(
-
+
diff --git a/src/modules/20_positionTemp/components/DialogSuccession.vue b/src/modules/20_positionTemp/components/DialogSuccession.vue
index ae11d089c..7bd6d3868 100644
--- a/src/modules/20_positionTemp/components/DialogSuccession.vue
+++ b/src/modules/20_positionTemp/components/DialogSuccession.vue
@@ -5,6 +5,7 @@ import { useQuasar } from "quasar";
import { useRoute } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { usePositionEmp } from "@/modules/20_positionTemp/store/organizational";
+import { formatPosmasterNo } from "@/utils/function";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -135,11 +136,12 @@ async function fetchTable() {
const data = res.data.result.data;
const list = data.map((e: PosMaster) => ({
...e,
- posMasterNo:
- (e.orgShortname !== null ? e.orgShortname : "") +
- (e.posMasterNoPrefix ? e.posMasterNoPrefix : "") +
- (e.posMasterNo !== null ? e.posMasterNo : "") +
- (e.posMasterNoSuffix !== null ? e.posMasterNoPrefix : ""),
+ posMasterNo: formatPosmasterNo(
+ e.orgShortname,
+ e.posMasterNoPrefix,
+ e.posMasterNo.toString(),
+ e.posMasterNoSuffix ?? ""
+ ),
}));
rows.value = list;
})
diff --git a/src/modules/20_positionTemp/components/TableMain.vue b/src/modules/20_positionTemp/components/TableMain.vue
index 8de8c9db3..f19377051 100644
--- a/src/modules/20_positionTemp/components/TableMain.vue
+++ b/src/modules/20_positionTemp/components/TableMain.vue
@@ -719,7 +719,7 @@ watch(
+import { onMounted, reactive, ref } from "vue";
+import { useQuasar } from "quasar";
+
+import http from "@/plugins/http";
+import config from "@/app.config";
+import { useCounterMixin } from "@/stores/mixin";
+import { usePersonsStore } from "@/modules/23_persons/stores/PersonsStore";
+import { usePagination } from "@/composables/usePagination";
+
+import type { QTableProps } from "quasar";
+import type {
+ DataOptions,
+ PosTypes,
+ PosLevels,
+ Person,
+} from "@/modules/23_persons/interface/Main";
+
+const $q = useQuasar();
+const { showLoader, hideLoader, messageError } = useCounterMixin();
+const { pagination, params, onRequest } = usePagination("", fetchData);
+const store = usePersonsStore();
+
+const props = defineProps<{ type: "current" | "draft" }>();
+
+const options = reactive({
+ posType: [] as DataOptions[],
+ posLevel: [] as DataOptions[],
+});
+
+const filters = reactive({
+ keyword: "",
+ position: "",
+ posTypeId: "",
+ posLevelId: "",
+});
+
+const rows = ref([]);
+const visibleColumns = ref([
+ "citizenId",
+ "fullName",
+ "position",
+ "posType",
+ "posLevel",
+]);
+const columns = ref([
+ {
+ name: "citizenId",
+ align: "left",
+ label: "เลขบัตรประชาชน",
+ sortable: false,
+ field: "citizenId",
+ headerStyle: "font-size: 14px",
+ style: "font-size: 14px",
+ },
+ {
+ name: "fullName",
+ align: "left",
+ label: "ชื่อ-นามสกุล",
+ sortable: false,
+ field: "fullName",
+ format(val, row) {
+ return `${row.prefix || ""}${row.firstName || ""} ${
+ row.lastName || ""
+ }`.trim();
+ },
+ headerStyle: "font-size: 14px",
+ style: "font-size: 14px",
+ },
+ {
+ name: "position",
+ align: "left",
+ label: "ตำแหน่งในสายงาน",
+ sortable: false,
+ field: "position",
+ headerStyle: "font-size: 14px",
+ style: "font-size: 14px",
+ },
+ {
+ name: "posType",
+ align: "left",
+ label: "ประเภทตำแหน่ง",
+ sortable: false,
+ field: "posType",
+ headerStyle: "font-size: 14px",
+ style: "font-size: 14px",
+ },
+ {
+ name: "posLevel",
+ align: "left",
+ label: "ระดับตำแหน่ง",
+ sortable: false,
+ field: "posLevel",
+ headerStyle: "font-size: 14px",
+ style: "font-size: 14px",
+ },
+]);
+
+/** ฟังก์ชันดึงข้อมูลรายชื่อขรก. ที่ไม่อยู่ในโครงสร้าง */
+async function fetchData() {
+ try {
+ showLoader();
+ const payload = {
+ ...params.value,
+ posTypeId: filters.posTypeId,
+ posLevelId: filters.posLevelId,
+ position: filters.position.trim(),
+ keyword: filters.keyword.trim(),
+ };
+ const endpoint =
+ props.type === "current"
+ ? config.API.orgSearchCurrentProfile
+ : config.API.orgSearchProfile;
+
+ const res = await http.post(endpoint, payload);
+ const result = res.data.result;
+
+ pagination.value.rowsNumber = result?.total || 0;
+ rows.value = result?.data || [];
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+}
+
+/** ฟังก์ชันดึงข้อมูลประเภทตำแหน่ง */
+async function getPosType() {
+ try {
+ options.posType = await store.fetchPosType();
+ } catch (error) {
+ messageError($q, error);
+ }
+}
+
+/**
+ * ฟังก์ชันอัปเดตตัวเลือกระดับตำแหน่งเมื่อเลือกประเภทตำแหน่ง
+ * @param val ID เภทตำแหน่ง
+ */
+function updateSelectType(val: string) {
+ const listLevel: PosTypes | undefined = store.optionsData.dataType.find(
+ (e: PosTypes) => e.id === val
+ );
+
+ store.optionsData.posLevel =
+ listLevel?.posLevels?.map((e: PosLevels) => ({
+ id: e.id,
+ name: e.posLevelName,
+ })) || [];
+
+ options.posLevel = store.optionsData.posLevel;
+
+ filters.posLevelId = "";
+ searchData();
+}
+
+/** ฟังก์ชันค้นหาข้อมูล*/
+function searchData() {
+ pagination.value.page = 1;
+ fetchData();
+}
+
+/**
+ * ฟังก์ชันเปิดหน้าทะเบียนขรก. ในแท็บใหม่
+ * @param personId ID ของขรก.
+ */
+function handleRedirect(personId: string) {
+ window.open(`/registry-officer/${personId}`, "_blank");
+}
+
+onMounted(() => {
+ fetchData();
+ getPosType();
+});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/23_persons/interface/Main.ts b/src/modules/23_persons/interface/Main.ts
new file mode 100644
index 000000000..b92ae3cd2
--- /dev/null
+++ b/src/modules/23_persons/interface/Main.ts
@@ -0,0 +1,38 @@
+interface DataOptions {
+ id: string;
+ name: string;
+}
+
+interface PosTypes {
+ createdAt: Date;
+ id: string;
+ lastUpdateFullName: string;
+ lastUpdatedAt: Date;
+ posTypeName: string;
+ posTypeRank: number;
+ posLevels: PosLevels[];
+}
+
+interface PosLevels {
+ createdAt: Date;
+ id: string;
+ lastUpdateFullName: string;
+ lastUpdatedAt: Date;
+ posLevelAuthority: string;
+ posLevelName: string;
+ posLevelRank: number;
+}
+
+interface Person {
+ citizenId: string;
+ firstName: string;
+ id: string;
+ lastName: string;
+ posLevel: string;
+ posType: string;
+ position: string;
+ prefix: string;
+ rank: string;
+}
+
+export type { DataOptions, PosTypes, PosLevels, Person };
diff --git a/src/modules/23_persons/router.ts b/src/modules/23_persons/router.ts
new file mode 100644
index 000000000..0ad543b53
--- /dev/null
+++ b/src/modules/23_persons/router.ts
@@ -0,0 +1,14 @@
+const Main = () => import("@/modules/23_persons/views/Main.vue");
+
+export default [
+ {
+ path: "/persons",
+ name: "personsMain",
+ component: Main,
+ meta: {
+ Auth: true,
+ Key: "PERSONS",
+ Role: "PERSONS",
+ },
+ },
+];
diff --git a/src/modules/23_persons/stores/PersonsStore.ts b/src/modules/23_persons/stores/PersonsStore.ts
new file mode 100644
index 000000000..e19b5e29f
--- /dev/null
+++ b/src/modules/23_persons/stores/PersonsStore.ts
@@ -0,0 +1,45 @@
+import { defineStore } from "pinia";
+import { reactive } from "vue";
+
+import http from "@/plugins/http";
+import config from "@/app.config";
+
+import type {
+ DataOptions,
+ PosTypes,
+} from "@/modules/23_persons/interface/Main";
+
+export const usePersonsStore = defineStore("personsStore", () => {
+ const routeCheck = {
+ registry: {
+ meta: { Auth: true, Key: "SYS_REGISTRY_OFFICER", Role: "OWNER" },
+ },
+ org: {
+ meta: { Auth: true, Key: "SYS_ORG", Role: "OWNER" },
+ },
+ };
+
+ const optionsData = reactive({
+ posType: [] as DataOptions[],
+ posLevel: [] as DataOptions[],
+ dataType: [] as PosTypes[],
+ });
+
+ /** ฟังก์ชันดึงข้อมูลประเภทตำแหน่ง */
+ async function fetchPosType() {
+ if (optionsData.posType.length > 0) {
+ return optionsData.posType;
+ }
+
+ const res = await http.get(config.API.orgPosType);
+ optionsData.dataType = res.data.result;
+ optionsData.posType = res.data.result.map((e: PosTypes) => ({
+ id: e.id,
+ name: e.posTypeName,
+ }));
+
+ return optionsData.posType;
+ }
+
+ return { routeCheck, optionsData, fetchPosType };
+});
diff --git a/src/modules/23_persons/views/Main.vue b/src/modules/23_persons/views/Main.vue
new file mode 100644
index 000000000..ce5c336d8
--- /dev/null
+++ b/src/modules/23_persons/views/Main.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+ รายชื่อขรก. ที่ไม่อยู่ในโครงสร้าง
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/router/index.ts b/src/router/index.ts
index f570ed6ce..565174cf3 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -29,6 +29,7 @@ import ModulePositionCondition from "@/modules/19_condition/router";
import ModulePositionTemp from "@/modules/20_positionTemp/router";
import ModuleReport from "@/modules/21_report/router";
import ModuleIssues from "@/modules/22_issues/router";
+import ModulePersons from "@/modules/23_persons/router";
// TODO: ใช้หรือไม่?
import { authenticated, logout } from "@/plugins/auth";
@@ -81,6 +82,7 @@ const router = createRouter({
...ModulePositionTemp,
...ModuleReport,
...ModuleIssues,
+ ...ModulePersons,
],
},
/**
diff --git a/src/stores/mixin.ts b/src/stores/mixin.ts
index 40ea41b3c..8ef179cf0 100644
--- a/src/stores/mixin.ts
+++ b/src/stores/mixin.ts
@@ -362,13 +362,21 @@ export const useCounterMixin = defineStore("mixin", () => {
const messageError = (q: any, e: any = "", msg: string = "") => {
if (e.response !== undefined) {
if (e.response.data.status !== undefined) {
- if (e.response.data.status == 401) {
+ if (
+ e.response.data.status == 401 ||
+ (e.response.data.status == 404 &&
+ e.response.data.message == "ไม่พบข้อมูลสิทธิ์")
+ ) {
//invalid_token
+ const msg =
+ e.response.data.status == 401
+ ? "ล็อกอินหมดอายุ กรุณาล็อกอินใหม่อีกครั้ง"
+ : e.response.data.message;
q.dialog({
component: CustomComponent,
componentProps: {
title: `พบข้อผิดพลาด`,
- message: `ล็อกอินหมดอายุ กรุณาล็อกอินใหม่อีกครั้ง`,
+ message: msg,
icon: "warning",
color: "red",
onlycancel: true,
diff --git a/src/stores/socket.ts b/src/stores/socket.ts
index 0d5ea4c64..b7951a9df 100644
--- a/src/stores/socket.ts
+++ b/src/stores/socket.ts
@@ -3,6 +3,7 @@ import { getToken } from "@/plugins/auth";
import { defineStore } from "pinia";
import { Notify } from "quasar";
import { io, Socket } from "socket.io-client";
+import { ref } from "vue";
interface sockeBackup {
message: string;
success?: boolean;
@@ -10,6 +11,7 @@ interface sockeBackup {
export const useSocketStore = defineStore("socket", () => {
let socket: Socket;
+ const notificationCounter = ref(0);
async function init() {
socket = io(new URL(config.API.socket).origin, {
@@ -43,6 +45,12 @@ export const useSocketStore = defineStore("socket", () => {
notifyStatusOrg("current", body.message, body.success);
}
});
+
+ socket.on("socket-notification", (payload) => {
+ let body: sockeBackup = JSON.parse(payload);
+ notifyStatusWithProgress(body.message, body.success);
+ notificationCounter.value++;
+ });
}
function notifyStatus(message: string, success?: boolean) {
@@ -62,6 +70,27 @@ export const useSocketStore = defineStore("socket", () => {
});
}
+ function notifyStatusWithProgress(message: string, success?: boolean) {
+ Notify.create({
+ group: false,
+ type: success === undefined || success ? "positive" : "negative",
+ message: `${message}`,
+ position: "top",
+ timeout: success === undefined || success ? 3000 : 0,
+ actions:
+ success === undefined || success
+ ? []
+ : [
+ {
+ icon: "close",
+ color: "white",
+ round: true,
+ },
+ ],
+ progress: true,
+ });
+ }
+
function fnStyleNotiOrg() {
if (document.getElementById("notify-link-style")) return;
const style = document.createElement("style");
@@ -84,10 +113,12 @@ export const useSocketStore = defineStore("socket", () => {
`;
document.head.appendChild(style);
}
+
(window as any).resetOrgPage = (type: string) => {
localStorage.setItem("org_type", type);
window.location.reload();
};
+
function notifyStatusOrg(type: string, message: string, success?: boolean) {
fnStyleNotiOrg();
Notify.create({
@@ -111,5 +142,5 @@ export const useSocketStore = defineStore("socket", () => {
init();
- return {};
+ return { notificationCounter };
});
diff --git a/src/stores/structureTree.ts b/src/stores/structureTree.ts
index d509f637c..3d8e4dd72 100644
--- a/src/stores/structureTree.ts
+++ b/src/stores/structureTree.ts
@@ -13,6 +13,27 @@ import type {
const { showLoader, hideLoader } = useCounterMixin();
+/**
+ * ฟังก์ชันแปลงข้อมูลโครงสร้างให้มี children array สำหรับทุกโหนด
+ * เพื่อป้องกันปัญหา q-tree เมื่อ children เป็น undefined
+ */
+function normalizeTreeData(nodes: DataStructureTree[]): DataStructureTree[] {
+ return nodes.map((node) => {
+ // Set children to [] for orgLevel: 4, otherwise recurse if children exist
+ const normalizedChildren =
+ node.orgLevel === 4
+ ? []
+ : node.children
+ ? normalizeTreeData(node.children)
+ : node.children;
+
+ return {
+ ...node,
+ children: normalizedChildren,
+ };
+ });
+}
+
export const useStructureTree = defineStore("structureTree", () => {
const activeId = ref("");
const dataStore = ref<{ [key: string]: DataStructureTree[] }>({});
@@ -27,11 +48,11 @@ export const useStructureTree = defineStore("structureTree", () => {
*/
async function fetchStructureTree(sysKey: string, isLoad: boolean = false) {
if (dataStore.value[sysKey]) {
- return dataStore.value[sysKey] || [];
+ return normalizeTreeData(dataStore.value[sysKey]) || [];
} else {
activeId.value === "" && (await fetchActive());
const data = await fetchData(sysKey, isLoad);
- return data || [];
+ return normalizeTreeData(data || []);
}
}
diff --git a/src/stores/uploadProgress.ts b/src/stores/uploadProgress.ts
new file mode 100644
index 000000000..94fcc7536
--- /dev/null
+++ b/src/stores/uploadProgress.ts
@@ -0,0 +1,46 @@
+import { defineStore } from 'pinia';
+import { ref } from 'vue';
+
+interface PendingUpload {
+ jobId: string;
+ type: 'candidate' | 'score' | 'result' | 'period';
+ periodId: string;
+}
+
+export const useUploadProgressStore = defineStore('uploadProgress', () => {
+ const pendingUploads = ref([]);
+
+ function addUpload(jobId: string, periodId: string, uploadType: 'candidate' | 'score' | 'result' | 'period') {
+ pendingUploads.value.push({
+ jobId,
+ type: uploadType,
+ periodId
+ });
+ }
+
+ function removeUpload(jobId: string) {
+ const index = pendingUploads.value.findIndex(u => u.jobId === jobId);
+ if (index !== -1) {
+ pendingUploads.value.splice(index, 1);
+ }
+ }
+
+ function removeByPeriodAndType(periodId: string, uploadType: string) {
+ const index = pendingUploads.value.findIndex(
+ u => u.periodId === periodId && u.type === uploadType
+ );
+ if (index !== -1) {
+ pendingUploads.value.splice(index, 1);
+ }
+ }
+
+ function isUploading(periodId: string, uploadType: string): boolean {
+ return pendingUploads.value.some(
+ u => u.periodId === periodId && u.type === uploadType
+ );
+ }
+
+ return { pendingUploads, addUpload, removeUpload, removeByPeriodAndType, isUploading };
+}, {
+ persist: true
+});
diff --git a/src/utils/function.ts b/src/utils/function.ts
index e3f5e836f..2427efc4b 100644
--- a/src/utils/function.ts
+++ b/src/utils/function.ts
@@ -94,3 +94,18 @@ export function validateFileSize(
return `ขนาดไฟล์ไม่เกิน ${maxSizeMB}MB`;
}
+
+export function formatPosmasterNo(
+ orgShortname: string,
+ posMasterNoPrefix: string,
+ posMasterNo: string,
+ posMasterNoSuffix: string
+) {
+ if (!orgShortname || !posMasterNo) return "";
+
+ const prefix = posMasterNoPrefix ? `${posMasterNoPrefix} ` : "";
+
+ const suffix = posMasterNoSuffix ? ` ${posMasterNoSuffix}` : "";
+
+ return `${orgShortname} ${prefix}${posMasterNo}${suffix}`.trim();
+}
diff --git a/src/views/MainLayout.vue b/src/views/MainLayout.vue
index 3812a311d..fd4e39a02 100644
--- a/src/views/MainLayout.vue
+++ b/src/views/MainLayout.vue
@@ -532,31 +532,55 @@ async function fetchKeycloakPosition() {
await http
.get(config.API.keycloakPosition())
.then(async (res) => {
- const data = await res.data.result;
+ const data = res.data.result;
usePositionKeycloakStore().setPositionKeycloak(data);
if (data.avatarName) {
- await getImg(data.profileId, data.avatarName);
+ getImg(data.profileId, data.avatarName);
} else {
profileImg.value = avatar;
}
})
.catch((err) => {
messageError($q, err);
+ profileImg.value = avatar;
});
}
const profileImg = ref("");
-async function getImg(id: string, pathName: string) {
- await http
+function getImg(id: string, pathName: string) {
+ http
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, pathName))
.then((res) => {
profileImg.value = res.data.downloadUrl;
+ })
+ .catch((err) => {
+ profileImg.value = avatar;
});
}
function onViewDetailNoti(url: string) {
window.open(url, "_blank");
}
+
+function handleDeleteNotification() {
+ dialogRemove(
+ $q,
+ async () => {
+ try {
+ showLoader();
+ await http.delete(config.API.msgNotificate);
+ await getDataNotification(1, "DEL");
+ success($q, "ล้างการแจ้งสำเร็จ");
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+ },
+ "ยืนยันการล้างการแจ้งเตือนทั้งหมด",
+ `ต้องการล้างการแจ้งเตือนทั้งหมด (${totalInbox.value} รายการ) ใช่หรือไม่? การกระทำนี้ไม่สามารถย้อนกลับได้`
+ );
+}
@@ -638,6 +662,21 @@ function onViewDetailNoti(url: string) {
ทั้งหมด {{ totalInbox }} ข้อความ
+
+ ล้างการแจ้งเตือนทั้งหมด
+