+
+
{
-
+
{
return reportNameVal + employeeClassName;
};
+async function handleDownload() {
+ updateLeaveday();
+ await fetchLeaveday(
+ employeeClass.value,
+ typeReport.value == 3 || typeReport.value == 4
+ ? leaveType.value
+ : yearType.value,
+ dateStart.value,
+ dateEnd.value
+ );
+ await genReportXLSX(detailReport.value, `${reportName()}`);
+}
+
onMounted(() => {
fetchDataTree();
});
@@ -512,7 +526,11 @@ onMounted(() => {
round
color="primary"
icon="download"
- v-if="checkPermission($route)?.attrIsGet && typeReport !== 3"
+ v-if="
+ checkPermission($route)?.attrIsGet &&
+ typeReport !== 3 &&
+ typeReport !== 4
+ "
>
@@ -547,8 +565,11 @@ onMounted(() => {
round
color="primary"
icon="download"
- v-if="checkPermission($route)?.attrIsGet && typeReport == 3"
- @click="getReport()"
+ v-if="
+ checkPermission($route)?.attrIsGet &&
+ (typeReport == 3 || typeReport == 4)
+ "
+ @click="typeReport == 3 ? getReport() : handleDownload()"
>
@@ -957,7 +978,7 @@ onMounted(() => {
{
([
{
name: "leaveDaysUsed",
align: "left",
- label: "ที่ใช้ไป (วัน)",
+ label: "ที่ใช้ไปทั้งหมด (วัน)",
sortable: true,
field: "leaveDaysUsed",
headerStyle: "font-size: 14px",
@@ -92,7 +92,7 @@ const columns = ref([
{
name: "leaveCount",
align: "left",
- label: "ที่ใช้ไป (ครั้ง)",
+ label: "ที่ใช้ไปทั้งหมด (ครั้ง)",
sortable: true,
field: "leaveCount",
headerStyle: "font-size: 14px",
@@ -101,7 +101,7 @@ const columns = ref([
{
name: "beginningLeaveDays",
align: "left",
- label: "ยกมา (วัน)",
+ label: "จำนวนวันลาก่อนใช้งานระบบ",
sortable: true,
field: "beginningLeaveDays",
headerStyle: "font-size: 14px",
@@ -110,7 +110,7 @@ const columns = ref([
{
name: "beginningLeaveCount",
align: "left",
- label: "ยกมา (ครั้ง)",
+ label: "จำนวนครั้งที่ลาก่อนใช้งานระบบ",
sortable: true,
field: "beginningLeaveCount",
headerStyle: "font-size: 14px",
diff --git a/src/modules/11_discipline/components/2_InvestigateFacts/DialogSendTerminate.vue b/src/modules/11_discipline/components/2_InvestigateFacts/DialogSendTerminate.vue
index 16f858475..0605fe50d 100644
--- a/src/modules/11_discipline/components/2_InvestigateFacts/DialogSendTerminate.vue
+++ b/src/modules/11_discipline/components/2_InvestigateFacts/DialogSendTerminate.vue
@@ -2,6 +2,7 @@
import { ref } from "vue";
import { useRoute } from "vue-router";
import { useQuasar } from "quasar";
+import type { QTableColumn } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
@@ -22,21 +23,12 @@ const checkRoutePermisson = ref(
route.name == "disciplineInvestigatefactsDetail"
);
-const props = defineProps({
- rows: {
- type: Array,
- default: [],
- },
- columns: {
- type: Array,
- default: [],
- },
- visibleColumns: {
- type: Array,
- default: [],
- },
- fetchData: Function,
-});
+const props = defineProps<{
+ rows?: any[];
+ columns?: QTableColumn[];
+ visibleColumns?: string[];
+ fetchData?: () => void;
+}>();
const remark = ref("");
const selected = ref([]);
@@ -100,7 +92,7 @@ function onSubmit() {
@@ -271,7 +271,7 @@ watch(
keep-color
color="primary"
dense
- :disable="commandType"
+ :disable="commandType === ''"
v-model="props.selected"
/>
diff --git a/src/modules/11_discipline/components/4_Result/EditPage.vue b/src/modules/11_discipline/components/4_Result/EditPage.vue
index fb8e9ab73..64b2f70d2 100644
--- a/src/modules/11_discipline/components/4_Result/EditPage.vue
+++ b/src/modules/11_discipline/components/4_Result/EditPage.vue
@@ -9,13 +9,13 @@ import { useCounterMixin } from "@/stores/mixin";
import { useDisciplineResultStore } from "@/modules/11_discipline/store/ResultStore";
import { useDisciplineMainStore } from "@/modules/11_discipline/store/Main";
-import type { DataListRow } from "@/modules/11_discipline/interface/request/Result";
+import type { DataListRow } from "@/modules/11_discipline/interface/request/result";
import type {
FormData as FormDataComplaint,
ArrayPerson,
ArrayFileList,
} from "@/modules/11_discipline/interface/request/complaint";
-import type { FormData as FormInvestigateFact } from "@/modules/11_discipline/interface/request/InvestigateFact";
+import type { FormData as FormInvestigateFact } from "@/modules/11_discipline/interface/request/investigateFact";
import DialogSendToCommand from "@/modules/11_discipline/components/4_Result/DialogSendToCommand.vue";
import FormComplaints from "@/modules/11_discipline/components/1_Complaint/Form.vue"; //เรื่องร้องเรียน
diff --git a/src/modules/11_discipline/components/6_BasicInformation/Director/DialogInvestigateTotal.vue b/src/modules/11_discipline/components/6_BasicInformation/Director/DialogInvestigateTotal.vue
index 78027708d..83180daca 100644
--- a/src/modules/11_discipline/components/6_BasicInformation/Director/DialogInvestigateTotal.vue
+++ b/src/modules/11_discipline/components/6_BasicInformation/Director/DialogInvestigateTotal.vue
@@ -98,7 +98,7 @@ watch(props, () => {
v-ripple
:active="listCheck === index"
active-class="my-menu-link"
- @click="clickList(index, item.director)"
+ @click="clickList(Number(index), item.director)"
>
{{ item.title }}
diff --git a/src/modules/11_discipline/components/6_BasicInformation/Director/Form.vue b/src/modules/11_discipline/components/6_BasicInformation/Director/Form.vue
index c5cf71505..940687fe7 100644
--- a/src/modules/11_discipline/components/6_BasicInformation/Director/Form.vue
+++ b/src/modules/11_discipline/components/6_BasicInformation/Director/Form.vue
@@ -294,6 +294,7 @@ watch(
hide-bottom-space
dense
label="คำค้น"
+ @keydown.enter.prevent="searchInput()"
>
{
+ showLoader();
+ try {
+ await http.delete(config.API.evaluationMain() + `/del-director/${id}`);
+ await props.fetchData();
+ await success($q, "ลบสำเร็จ");
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+ });
+}
+
/**
* ทำงานเมื่อ props.data มีการเปลี่ยนแปลง
*/
@@ -268,17 +290,30 @@ watch(
-
+
แก้ไขหน้าที่
+
+
+ ลบ
+
diff --git a/src/modules/12_evaluatePersonal/components/Detail/viewTab2/CardMeet.vue b/src/modules/12_evaluatePersonal/components/Detail/viewTab2/CardMeet.vue
index 28e26a3f8..cf4611de5 100644
--- a/src/modules/12_evaluatePersonal/components/Detail/viewTab2/CardMeet.vue
+++ b/src/modules/12_evaluatePersonal/components/Detail/viewTab2/CardMeet.vue
@@ -27,6 +27,7 @@ const {
dialogConfirm,
date2Thai,
success,
+ dialogRemove,
} = mixin;
/** props*/
@@ -208,6 +209,23 @@ async function getList() {
});
}
+function handleDelete(meetingId: string) {
+ dialogRemove($q, async () => {
+ showLoader();
+ try {
+ await http.delete(
+ config.API.evaluationMain() + `/del-meeting/${id.value}/${meetingId}`
+ );
+ await props.fetchData();
+ await success($q, "ลบสำเร็จ");
+ } catch (error) {
+ messageError($q, error);
+ } finally {
+ hideLoader();
+ }
+ });
+}
+
watch(
() => props.data,
() => {
@@ -265,6 +283,7 @@ watch(
>
+
{{ col.label }}
@@ -272,6 +291,19 @@ watch(
+
+
+ ลบ
+
+
{{ props.rowIndex + 1 }}
diff --git a/src/modules/12_evaluatePersonal/components/Director/Form.vue b/src/modules/12_evaluatePersonal/components/Director/Form.vue
index 884f8d470..3228dfe3a 100644
--- a/src/modules/12_evaluatePersonal/components/Director/Form.vue
+++ b/src/modules/12_evaluatePersonal/components/Director/Form.vue
@@ -280,6 +280,7 @@ onMounted(async () => {
hide-bottom-space
dense
label="คำค้น"
+ @keydown.enter.prevent="(pagination.page = 1), searchInput()"
>
{
@@ -254,6 +255,7 @@ async function fetchDataQuota(id: string) {
* @param id กลุ่ม
*/
async function fetchDataPeriod(id: string, force: boolean = false) {
+ if (!id) return;
force && showLoader();
let formData = {
...params.value,
diff --git a/src/modules/13_salary/components/05_salaryListsEmployee/TabMain.vue b/src/modules/13_salary/components/05_salaryListsEmployee/TabMain.vue
index e4f00a7cc..cc50f45cb 100644
--- a/src/modules/13_salary/components/05_salaryListsEmployee/TabMain.vue
+++ b/src/modules/13_salary/components/05_salaryListsEmployee/TabMain.vue
@@ -215,6 +215,7 @@ const itemsCard = ref([
* @param id กลุ่ม
*/
async function fetchDataQuota(id: string) {
+ if (!id) return;
await http
.get(config.API.salaryListPeriodQuotaEmp(id))
.then((res) => {
@@ -246,6 +247,7 @@ async function fetchDataQuota(id: string) {
* @param id กลุ่ม
*/
async function fetchDataPeriod(id: string, force: boolean = false) {
+ if (!id) return;
force && showLoader();
let formData = {
...params.value,
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/13_salary/views/04_salaryLists.vue b/src/modules/13_salary/views/04_salaryLists.vue
index 6e9a4c4fc..d3f38a61f 100644
--- a/src/modules/13_salary/views/04_salaryLists.vue
+++ b/src/modules/13_salary/views/04_salaryLists.vue
@@ -308,6 +308,7 @@ async function fetchSalalyPeriod(
if (!data.group1id) {
hideLoader();
}
+ isLoad.value = data.group1id ? true : false;
})
.catch((err) => {
messageError($q, err);
diff --git a/src/modules/14_KPI/views/01_kpiRound.vue b/src/modules/14_KPI/views/01_kpiRound.vue
index f6db8904d..46502850b 100644
--- a/src/modules/14_KPI/views/01_kpiRound.vue
+++ b/src/modules/14_KPI/views/01_kpiRound.vue
@@ -44,7 +44,7 @@ const columns = ref([
field: "year",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
- format: (val) => val + 543,
+ format: (val) => (val ? val + 543 : "-"),
},
{
name: "durationKPI",
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/14_KPI/views/report.vue b/src/modules/14_KPI/views/report.vue
index f723dd697..978d5358c 100644
--- a/src/modules/14_KPI/views/report.vue
+++ b/src/modules/14_KPI/views/report.vue
@@ -876,43 +876,6 @@ onMounted(() => {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -942,6 +905,7 @@ onMounted(() => {
hide-bottom-space
dense
label="คำค้น"
+ @keydown.enter.prevent="(formFilter.page = 1), fetchListPerson()"
>
([
field: "year",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
- format: (v) => v + 543,
+ format: (v) => (v ? v + 543 : "-"),
},
{
name: "citizenId",
diff --git a/src/modules/15_development/views/History.vue b/src/modules/15_development/views/History.vue
index 76a8079ea..a9806406c 100644
--- a/src/modules/15_development/views/History.vue
+++ b/src/modules/15_development/views/History.vue
@@ -44,7 +44,7 @@ const columns = ref([
field: "year",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
- format: (v) => v + 543,
+ format: (v) => (v ? v + 543 : "-"),
},
{
name: "citizenId",
diff --git a/src/modules/15_development/views/MainPage.vue b/src/modules/15_development/views/MainPage.vue
index 7db45984f..397fd2b99 100644
--- a/src/modules/15_development/views/MainPage.vue
+++ b/src/modules/15_development/views/MainPage.vue
@@ -75,7 +75,7 @@ const columns = ref([
field: "year",
headerStyle: "font-size: 14px",
style: "font-size: 14px ; width:10%",
- format: (val) => val + 543,
+ format: (val) => (val ? val + 543 : "-"),
},
{
name: "projectName",
diff --git a/src/modules/15_development/views/Scholarship.vue b/src/modules/15_development/views/Scholarship.vue
index 48d94b36c..12e494ddc 100644
--- a/src/modules/15_development/views/Scholarship.vue
+++ b/src/modules/15_development/views/Scholarship.vue
@@ -32,7 +32,7 @@ const columns = ref([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val) {
- return val + 543;
+ return val ? val + 543 : "-";
},
},
{
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/TableMain.vue b/src/modules/16_positionEmployee/components/TableMain.vue
index f56a0ab4e..8943c2423 100644
--- a/src/modules/16_positionEmployee/components/TableMain.vue
+++ b/src/modules/16_positionEmployee/components/TableMain.vue
@@ -777,7 +777,7 @@ watch(
({
});
const commandVolume = ref(""); //เล่มที่
const commandChapter = ref(""); //ตอนที่
-const isIdofficer = ref(false); //เช็ค สกจ.
const rows = ref>([]);
const columns = ref([
@@ -113,23 +113,22 @@ const visibleColumns = ref>([
const modalAddOperator = ref(false); // แสดงเพิ่มรายชื่อลงนามในแนบท้ายคำสั่ง
-/** ฟังก์ชันเช็ค สกจ.*/
-async function fetchCheckIdofficer() {
- await http
- .get(config.API.checkIdofficer)
- .then((res) => {
- isIdofficer.value = res.data.result;
- })
- .catch((err) => {
- messageError($q, err);
- });
-}
+
/**
* ฟังก์ชันบันทึกข้อมูลรายละเอียดคำสั่ง
* และกำหนด isChangeData เป็น false
*/
async function onSubmit() {
+ //ถ้าเป็น สกจ. ต้องเลือกประเภทคำสั่งด้วย
+ if (
+ store.isIdofficer &&
+ formData.isBangkok !== "BANGKOK" &&
+ formData.isBangkok !== "OFFICE"
+ ) {
+ dialogMessageNotify($q, "กรุณาเลือกคำสั่ง");
+ return;
+ }
dialogConfirm($q, async () => {
showLoader();
await http
@@ -156,7 +155,7 @@ async function onSubmit() {
});
}
-/** ฟังกชันดึงข้อมูลรายชื่อเจ้าหน้าที่ดำเนินการ */
+/** ฟังก์ชันดึงข้อมูลรายชื่อเจ้าหน้าที่ดำเนินการ */
async function fetchDataOperatorList() {
try {
const res = await http.get(
@@ -215,7 +214,6 @@ function onDeleteData(id: string) {
onMounted(async () => {
try {
showLoader();
- await fetchCheckIdofficer();
await fetchDataOperatorList();
formData.commandNo = props.formCommandList.commandNo;
formData.commandYear = props.formCommandList.commandYear;
@@ -225,7 +223,7 @@ onMounted(async () => {
formData.issue = props.formCommandList.issue;
formData.commandAffectDate = props.formCommandList.commandAffectDate;
formData.commandExcecuteDate = props.formCommandList.commandExcecuteDate;
- formData.isBangkok = !isIdofficer.value
+ formData.isBangkok = !store.isIdofficer
? null
: props.formCommandList.isBangkok;
commandCode.value = props.formCommandList.commandCode;
@@ -490,7 +488,7 @@ onMounted(async () => {
{
:key="col.name"
:props="props"
>
- {{
- getColumnLabel(col, isAct)
- }}
+ {{ col.label }}
diff --git a/src/modules/18_command/components/Step/View0_Digital.vue b/src/modules/18_command/components/Step/View0_Digital.vue
index 8cc2469f8..1601a21b6 100644
--- a/src/modules/18_command/components/Step/View0_Digital.vue
+++ b/src/modules/18_command/components/Step/View0_Digital.vue
@@ -719,6 +719,7 @@ onMounted(async () => {
dense
label="คำค้น"
@clear="search = ''"
+ @keydown.enter.prevent="onSearchData"
/>
{
const readonly = ref(false);
const dataCommand = ref();
const status = ref("");
- const isSalary = ref(false)
+ const isSalary = ref(false);
+ const isIdofficer = ref(false);
function checkStep(val: string) {
status.value = val;
switch (val) {
@@ -39,6 +40,7 @@ export const useCommandDetail = defineStore("commandDetailStore", () => {
readonly,
status,
dataCommand,
- isSalary
+ isSalary,
+ isIdofficer,
};
});
diff --git a/src/modules/18_command/views/detail.vue b/src/modules/18_command/views/detail.vue
index 37ab3326f..e9020037e 100644
--- a/src/modules/18_command/views/detail.vue
+++ b/src/modules/18_command/views/detail.vue
@@ -92,11 +92,24 @@ async function fetchDataCommandList() {
});
}
+/** ฟังก์ชันเช็ค สกจ.*/
+async function fetchCheckIdofficer() {
+ await http
+ .get(config.API.checkIdofficer)
+ .then((res) => {
+ store.isIdofficer = res.data.result;
+ })
+ .catch((err) => {
+ messageError($q, err);
+ });
+}
+
/**
* ทำงานเมื่อ Components ถูกเรียกใช้งาน
* กำหนดค่า `store.readonly` เมื่อ route.name เป็น "commandViewDetailPage" จะอ่านข้อมูลได้อย่างเดียว
*/
onMounted(async () => {
+ await fetchCheckIdofficer();
await fetchDataCommandList();
store.readonly =
route.name === "commandViewDetailPage" ||
diff --git a/src/modules/19_condition/view/Main.vue b/src/modules/19_condition/view/Main.vue
index 9fc3ec703..585e60005 100644
--- a/src/modules/19_condition/view/Main.vue
+++ b/src/modules/19_condition/view/Main.vue
@@ -454,7 +454,6 @@ onMounted(async () => {
table-class="text-grey-9"
row-key="id"
dense
- hide-bottom
bordered
separator="vertical"
class="custom-header-table-expand"
diff --git a/src/modules/21_report/components/01_org/MainReport.vue b/src/modules/21_report/components/01_org/MainReport.vue
index 19119313d..5afa2e63d 100644
--- a/src/modules/21_report/components/01_org/MainReport.vue
+++ b/src/modules/21_report/components/01_org/MainReport.vue
@@ -111,17 +111,16 @@ async function fetchSummary() {
* ฟังก์ชัน DownloadReport
* @param list รายงานที่ต้องการดาวน์โหลด
*/
-async function getReport(list: string) {
- const listFind = baseDocument.value.find(
- (item: DataDocument) => item.val == list
- )?.val;
- const newReport = listFind === "report2" ? "report2-history" : listFind;
+async function getReport(valReport: string) {
pdfSrc.value = undefined;
page.value = 1;
isLoadPDF.value = true;
- if (newReport) {
+ if (valReport) {
await http
- .get(config.API.orgReport(newReport) + `/${organizationId.value}`)
+ .post(config.API.orgReport(valReport), {
+ node: 0,
+ nodeId: organizationId.value,
+ })
.then(async (res) => {
const data = res.data.result;
detailReport.value = data;
@@ -414,10 +413,8 @@ onMounted(async () => {
color="primary"
icon="download"
>
-
- ดาวน์โหลดรายงาน
-
-
+ ดาวน์โหลดรายงาน
+
{
-
-
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/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/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 43d08e0b8..e3f5e836f 100644
--- a/src/utils/function.ts
+++ b/src/utils/function.ts
@@ -73,3 +73,24 @@ export function getColumnLabel(col: any, isAct: boolean) {
}
return col.label;
}
+
+/**
+ * ตรวจสอบขนาดไฟล์
+ * @param val ไฟล์หรืออาร์เรย์ของไฟล์ที่ต้องการตรวจสอบ
+ * @param maxSizeMB ขนาดจำกัดในหน่วย MB (ค่าเริ่มต้นคือ 10MB)
+ * @returns true หากไฟล์ทั้งหมดมีขนาดไม่เกินที่กำหนด, หรือข้อความแจ้งเตือนหากมีไฟล์ที่เกินขนาด
+ */
+export function validateFileSize(
+ val: File | File[],
+ maxSizeMB: number = 10
+): string | true {
+ if (!val) return true;
+
+ const filesArray = Array.isArray(val) ? val : [val];
+ const limit = maxSizeMB * 1024 * 1024;
+
+ const isAllValid = filesArray.every((file: File) => file.size <= limit);
+ if (isAllValid) return true;
+
+ return `ขนาดไฟล์ไม่เกิน ${maxSizeMB}MB`;
+}
diff --git a/src/views/Error404NotFound.vue b/src/views/Error404NotFound.vue
index e521ddd28..b1e69ea96 100644
--- a/src/views/Error404NotFound.vue
+++ b/src/views/Error404NotFound.vue
@@ -22,6 +22,12 @@ export default defineComponent({
label="กลับไปหน้าหลัก"
no-caps
/>
+
+
+
+ พบปัญหาการใช้งานกรุณาติดต่อผู้ดูแลระบบ
+ 088-264-9800
+