Merge branch 'develop' into devTee

This commit is contained in:
setthawutttty 2024-12-18 16:40:05 +07:00
commit 32c608879e
14 changed files with 284 additions and 160 deletions

View file

@ -3,5 +3,7 @@ VITE_QUALIFY_DISABLE_EMAM_PANEL=VITE_QUALIFY_DISABLE_EMAM_PANEL
VITE_QUALIFY_EXAM_PANEL=VITE_QUALIFY_EXAM_PANEL VITE_QUALIFY_EXAM_PANEL=VITE_QUALIFY_EXAM_PANEL
VITE_API_PUBLISH_URL=VITE_API_PUBLISH_URL VITE_API_PUBLISH_URL=VITE_API_PUBLISH_URL
VITE_API_REPORT_URL=VITE_API_REPORT_URL VITE_API_REPORT_URL=VITE_API_REPORT_URL
VITE_MANUAL_URL: VITE_MANUAL_URL VITE_MANUAL_URL=VITE_MANUAL_URL
VITE_URL_SSO: VITE_URL_SSO VITE_URL_SSO=VITE_URL_SSO
VITE_API_URI_CONFIG=VITE_API_URI_CONFIG
VITE_API_URI_REPORT_CONFIG=VITE_API_URI_REPORT_CONFIG

View file

@ -15,6 +15,8 @@ do
sed -i 's|VITE_API_REPORT_URL|'${VITE_API_REPORT_URL}'|g' $file sed -i 's|VITE_API_REPORT_URL|'${VITE_API_REPORT_URL}'|g' $file
sed -i 's|VITE_MANUAL_URL|'${VITE_MANUAL_URL}'|g' $file sed -i 's|VITE_MANUAL_URL|'${VITE_MANUAL_URL}'|g' $file
sed -i 's|VITE_URL_SSO|'${VITE_URL_SSO}'|g' $file sed -i 's|VITE_URL_SSO|'${VITE_URL_SSO}'|g' $file
sed -i 's|VITE_API_URI_CONFIG|'${VITE_API_URI_CONFIG}'|g' $file
sed -i 's|VITE_API_URI_REPORT_CONFIG|'${VITE_API_URI_REPORT_CONFIG}'|g' $file
done done

View file

@ -2,8 +2,10 @@
import { ref } from "vue"; import { ref } from "vue";
const env = ref<string>(process.env.NODE_ENV || "development"); const env = ref<string>(process.env.NODE_ENV || "development");
export const apiUrlConfig = import.meta.env.VITE_API_URI_CONFIG;
export const apiUrlConfigPublish = import.meta.env.VITE_API_PUBLISH_URL; export const apiUrlConfigPublish = import.meta.env.VITE_API_PUBLISH_URL;
export const apiUrlConfigReport = import.meta.env.VITE_API_REPORT_URL; export const apiUrlConfigReport = import.meta.env.VITE_API_REPORT_URL;
export const apiUrlConfigReport2 = import.meta.env.VITE_API_URI_REPORT_CONFIG;
// if (process.env.VUE_APP_TEST) { // if (process.env.VUE_APP_TEST) {
// env = "test"; // env = "test";
// } // }
@ -45,22 +47,22 @@ const config = ref<any>({
}, },
production: { production: {
// API_URI: "https://localhost:5010", // API_URI: "https://localhost:5010",
API_URI: `${window.location.protocol}//${window.location.host}/api/v1`, API_URI: apiUrlConfig,
API_URI_ORG_SERVICE: `${window.location.protocol}//${window.location.host}/api/v1`, //ใช้ชั่วคราว API_URI_ORG_SERVICE: apiUrlConfig, //ใช้ชั่วคราว
API_URI_ORG_EMPLOYEE_SERVICE: `${window.location.protocol}//${window.location.host}/api/v1`, //ใช้ชั่วคราว API_URI_ORG_EMPLOYEE_SERVICE: apiUrlConfig, //ใช้ชั่วคราว
API_URI_PROFILE_SERVICE: `${window.location.protocol}//${window.location.host}/api/v1`, API_URI_PROFILE_SERVICE: apiUrlConfig,
API_CANDIDATE_URI: `${window.location.protocol}//${window.location.host}/api/v1`, API_CANDIDATE_URI: apiUrlConfig,
API_REPORT_URI: `${window.location.protocol}//${window.location.host}/api/v1`, API_REPORT_URI: apiUrlConfig,
API_PLACEMENT_URI: `${window.location.protocol}//${window.location.host}/api/v1`, API_PLACEMENT_URI: apiUrlConfig,
API_URI_ORG_TREE: API_URI_ORG_TREE:
"https://s3cluster.frappet.com/bma-ehr-fpt/organization/strueture/tree_20230707_115124.json", "https://s3cluster.frappet.com/bma-ehr-fpt/organization/strueture/tree_20230707_115124.json",
MEET_URI: "meet.frappet.com", MEET_URI: "meet.frappet.com",
API_RETIREMENT_URI: `${window.location.protocol}//${window.location.host}/api/v1`, API_RETIREMENT_URI: apiUrlConfig,
API_PROBATION_URI: `${window.location.protocol}//${window.location.host}/api/v1/probation`, API_PROBATION_URI: `${apiUrlConfig}/probation`,
API_REPORT2_URI: `${window.location.protocol}//${window.location.host}/api/v2`, API_REPORT2_URI: `${apiUrlConfigReport2}`,
LINK_EVALUATE_PUBLISH: apiUrlConfigPublish, LINK_EVALUATE_PUBLISH: apiUrlConfigPublish,
API_REPORT_TEMPLATE_URI: apiUrlConfigReport, API_REPORT_TEMPLATE_URI: apiUrlConfigReport,
API_SUPPORT_URI: `${window.location.protocol}//${window.location.host}/api/v1/support`, API_SUPPORT_URI: `${apiUrlConfigPublish}/support`,
}, },
}); });

View file

@ -23,18 +23,28 @@ const scrollContainer = ref<HTMLElement | null>(null);
/** function ดาวน์โหลดไฟล์โครงสร้าง PNG*/ /** function ดาวน์โหลดไฟล์โครงสร้าง PNG*/
async function savePNG() { async function savePNG() {
showLoader(); try {
await scrollToCenter(); showLoader();
await chartRef.value.savePNG(); await scrollToCenter();
hideLoader(); await chartRef.value.savePNG();
} catch {
messageError($q);
} finally {
hideLoader();
}
} }
/** function ดาวน์โหลดไฟล์โครงสร้าง PDF*/ /** function ดาวน์โหลดไฟล์โครงสร้าง PDF*/
async function savePDF() { async function savePDF() {
showLoader(); try {
await scrollToCenter(); showLoader();
await chartRef.value.savePDF(); await scrollToCenter();
hideLoader(); await chartRef.value.savePDF();
} catch {
messageError($q);
} finally {
hideLoader();
}
} }
/** /**

View file

@ -98,18 +98,28 @@ async function refreshChart(data: any) {
/** โหลด Chart รูป*/ /** โหลด Chart รูป*/
async function savePNG() { async function savePNG() {
showLoader(); try {
await scrollToCenter(); showLoader();
await chartRef.value.savePNG(); await scrollToCenter();
hideLoader(); await chartRef.value.savePNG();
} catch {
messageError($q);
} finally {
hideLoader();
}
} }
/** โหลด Chart PDF*/ /** โหลด Chart PDF*/
async function savePDF() { async function savePDF() {
showLoader(); try {
await scrollToCenter(); showLoader();
await chartRef.value.savePDF(); await scrollToCenter();
hideLoader(); await chartRef.value.savePDF();
} catch {
messageError($q);
} finally {
hideLoader();
}
} }
watch( watch(

View file

@ -168,11 +168,11 @@ async function fetchlistprofile(id: string) {
prefix: e.prefix, prefix: e.prefix,
firstName: e.firstName, firstName: e.firstName,
lastName: e.lastName, lastName: e.lastName,
name: e.prefix + e.firstName + " " + e.lastName, name: `${e.prefix}${e.firstName} ${e.lastName}`,
organization: e.root, organization: e.root,
position: e.position, position: e.position,
positionNumber: e.posNo, positionNumber: e.posNo,
positionType: e.posTypeName, positionType: `${e.posTypeName} (${e.posLevelName})`,
positionLevel: e.posLevelName, positionLevel: e.posLevelName,
reason: e.reason, reason: e.reason,
remove: e.remove, remove: e.remove,
@ -663,7 +663,13 @@ onMounted(async () => {
><q-tooltip>ลบขอม</q-tooltip></q-btn ><q-tooltip>ลบขอม</q-tooltip></q-btn
> >
</q-td> </q-td>
<q-td key="order" :props="props">{{ props.row.order }} </q-td>
<q-td v-for="col in props.cols" :key="col.id">
<div class="table_ellipsis">
{{ col.value ? col.value : "-" }}
</div>
</q-td>
<!-- <q-td key="order" :props="props">{{ props.row.order }} </q-td>
<q-td key="name" :props="props" <q-td key="name" :props="props"
>{{ props.row.prefix ? props.row.prefix : "" >{{ props.row.prefix ? props.row.prefix : ""
}}{{ props.row.firstName ? props.row.firstName : "" }} }}{{ props.row.firstName ? props.row.firstName : "" }}
@ -688,20 +694,9 @@ onMounted(async () => {
<q-td class="table_ellipsis" key="organization" :props="props">{{ <q-td class="table_ellipsis" key="organization" :props="props">{{
props.row.organization ? props.row.organization : "-" props.row.organization ? props.row.organization : "-"
}}</q-td> }}</q-td> -->
</q-tr> </q-tr>
</template> </template>
<!-- <template v-slot:pagination="scope">
<q-pagination
v-model="pagination.page"
color="primary"
:max="scope.pagesNumber"
:max-pages="5"
size="sm"
boundary-links
direction-links
></q-pagination>
</template> -->
</d-table> </d-table>
</div> </div>
</q-card> </q-card>

View file

@ -23,7 +23,8 @@ const stroeResign = useDataStore();
const { statusText } = stroe; const { statusText } = stroe;
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { messageError, date2Thai, showLoader, hideLoader,onSearchDataTable } = mixin; const { messageError, date2Thai, showLoader, hideLoader, onSearchDataTable } =
mixin;
/** Table */ /** Table */
const rows = ref<ResponseItems[]>([]); const rows = ref<ResponseItems[]>([]);
@ -45,7 +46,10 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "ชื่อ-นามสกุล", label: "ชื่อ-นามสกุล",
sortable: true, sortable: true,
field: (row) => `${row.prefix}${row.firstName} ${row.lastName}`, field: `fullname`,
format(val, row) {
return `${row.prefix}${row.firstName} ${row.lastName}`;
},
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },
@ -101,7 +105,6 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "วันที่ยื่น", label: "วันที่ยื่น",
sortable: true, sortable: true,
// field: (row) => date2Thai(new Date(row.createdAt)),
field: "createdAt", field: "createdAt",
format(val, row) { format(val, row) {
return date2Thai(new Date(val)); return date2Thai(new Date(val));
@ -115,7 +118,10 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "สถานะ", label: "สถานะ",
sortable: true, sortable: true,
field: (row) => statusText(row.status), field: "status",
format(val, row) {
return statusText(row.status);
},
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },
@ -371,7 +377,7 @@ onMounted(async () => {
: '' : ''
" "
> >
{{ col.value ? col.value : "" }} {{ col.value ? col.value : "-" }}
</div> </div>
</q-td> </q-td>
</q-tr> </q-tr>

View file

@ -23,7 +23,8 @@ const stroeResign = useDataStore();
const { statusText } = stroe; const { statusText } = stroe;
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { messageError, date2Thai, showLoader, hideLoader,onSearchDataTable } = mixin; const { messageError, date2Thai, showLoader, hideLoader, onSearchDataTable } =
mixin;
/** Table */ /** Table */
const rows = ref<ResponseItems[]>([]); const rows = ref<ResponseItems[]>([]);
@ -45,7 +46,10 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "ชื่อ-นามสกุล", label: "ชื่อ-นามสกุล",
sortable: true, sortable: true,
field: (row) => `${row.prefix}${row.firstName} ${row.lastName}`, field: "fullname",
format(val, row) {
return `${row.prefix}${row.firstName} ${row.lastName}`;
},
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },
@ -114,7 +118,10 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "สถานะ", label: "สถานะ",
sortable: true, sortable: true,
field: (row) => statusText(row.status), field: "status",
format(val, row) {
return statusText(row.status);
},
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },
@ -374,7 +381,7 @@ onMounted(async () => {
: '' : ''
" "
> >
{{ col.value ? col.value : "" }} {{ col.value ? col.value : "-" }}
</div> </div>
</q-td> </q-td>
</q-tr> </q-tr>

View file

@ -81,7 +81,10 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "ชื่อ-นามสกุล", label: "ชื่อ-นามสกุล",
sortable: true, sortable: true,
field: (row) => `${row.prefix}${row.firstName} ${row.lastName}`, field: "fullname",
format(val, row) {
return `${row.prefix}${row.firstName} ${row.lastName}`;
},
headerStyle: "font-size: 14px; min-width: 200px", headerStyle: "font-size: 14px; min-width: 200px",
style: "font-size: 14px; ", style: "font-size: 14px; ",
}, },
@ -175,7 +178,10 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "สถานะ", label: "สถานะ",
sortable: true, sortable: true,
field: (row) => statusText(row.draftOrgEmployeeStatus), field: "statustext",
format(val, row) {
return statusText(row.draftOrgEmployeeStatus);
},
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },

View file

@ -24,14 +24,8 @@ import LoadView from "@/components/LoadView.vue";
const $q = useQuasar(); const $q = useQuasar();
const route = useRoute(); const route = useRoute();
const { fetchStructureTree } = useStructureTree(); const { fetchStructureTree } = useStructureTree();
const { const { date2Thai, dateToISO, messageError, monthYear2Thai } =
showLoader, useCounterMixin();
hideLoader,
date2Thai,
dateToISO,
messageError,
monthYear2Thai,
} = useCounterMixin();
const year = ref<number>(new Date().getFullYear()); const year = ref<number>(new Date().getFullYear());
const dateStart = ref<Date>(new Date(year.value - 1, 9, 1)); const dateStart = ref<Date>(new Date(year.value - 1, 9, 1));
@ -77,17 +71,26 @@ const nodeLevel = ref<number>(0);
const node = ref<DataStructureTree[]>([]); const node = ref<DataStructureTree[]>([]);
const expanded = ref<string[]>([]); const expanded = ref<string[]>([]);
/** ฟังก์ชันเรียกข้อมูลโครงสร้างหน่วยงาน*/
async function fetchDataTree() { async function fetchDataTree() {
node.value = await fetchStructureTree(route.meta.Key as string, true); node.value = await fetchStructureTree(route.meta.Key as string, true);
} }
/**
* งกนเลอกหนวยงานทองการดอม
* @param id id หนวยงาน
* @param level node ของหนวงงานทเลอก
*/
function onSelectedNode(id: string, level: number) { function onSelectedNode(id: string, level: number) {
nodeId.value = id; nodeId.value = id;
nodeLevel.value = level; nodeLevel.value = level;
updateLeaveday(); updateLeaveday();
} }
/** function อัปเดทบัญชีแสดงวันลา */ /**
* งกนอปเดทบญชแสดงวนลา
* และเรยกขอมลรายงาน
*/
async function updateLeaveday() { async function updateLeaveday() {
switch (yearType.value) { switch (yearType.value) {
case "FULL": case "FULL":
@ -125,23 +128,17 @@ async function updateLeaveday() {
isLoadPDF.value = true; isLoadPDF.value = true;
pdfSrc.value = undefined; pdfSrc.value = undefined;
typeReport.value === "1" // fetchLeaveday
? fetchLeaveday( fetchLeaveday(
employeeClass.value, employeeClass.value,
yearType.value, yearType.value,
dateStart.value, dateStart.value,
dateEnd.value dateEnd.value
) );
: fetchLeaveday2(
employeeClass.value,
yearType.value,
dateStart.value,
dateEnd.value
);
} }
/** /**
* function เรยกขอมลบญชแสดงวนลา * งกนเรยกขอมลรายงาน
* @param type สถานภาพ * @param type สถานภาพ
* @param year * @param year
* @param startDate นเรมต * @param startDate นเรมต
@ -161,38 +158,13 @@ async function fetchLeaveday(
node: nodeLevel.value, node: nodeLevel.value,
}; };
await http const pathAPI =
.post(config.API.leaveReportLeaveday(type), body) typeReport.value === "1"
.then(async (res) => { ? config.API.leaveReportLeaveday(type)
const data = res.data.result; : config.API.leaveReportLeave2(type);
data && (await fetchDocumentTemplate(data));
isReport.value = data ? true : false;
detailReport.value = data;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoadPDF.value = false;
});
}
async function fetchLeaveday2(
type: string,
year: string,
startDate: Date,
endDate: Date
) {
const body = {
type: year === "FULL" ? "FULL" : year === "MONTH" ? "MONTH" : "HAFT",
startDate: dateToISO(startDate),
endDate: dateToISO(endDate),
nodeId: nodeId.value,
node: nodeLevel.value,
};
await http await http
.post(config.API.leaveReportLeave2(type), body) .post(pathAPI, body)
.then(async (res) => { .then(async (res) => {
const data = res.data.result; const data = res.data.result;
data && (await fetchDocumentTemplate(data)); data && (await fetchDocumentTemplate(data));
@ -233,12 +205,10 @@ async function fetchDocumentTemplate(data: any) {
.catch(async (e) => { .catch(async (e) => {
messageError($q, JSON.parse(await e.response.data.text())); messageError($q, JSON.parse(await e.response.data.text()));
}) })
.finally(() => { .finally(() => {});
setTimeout(() => {
hideLoader();
}, 2000);
});
} }
// PDF
const numOfPages = ref<number>(0); const numOfPages = ref<number>(0);
const page = ref<number>(1); const page = ref<number>(1);
const pdfSrc = ref<any>(); const pdfSrc = ref<any>();
@ -366,7 +336,7 @@ onMounted(() => {
<div class="row col-12 q-col-gutter-sm"> <div class="row col-12 q-col-gutter-sm">
<div class="col-md-3 col-xs-12"> <div class="col-md-3 col-xs-12">
<q-select <q-select
class="bg-white" class="bg-white select_ellipsis3"
hide-bottom-space hide-bottom-space
outlined outlined
dense dense

View file

@ -23,6 +23,23 @@ const props = defineProps({
virtual-scroll virtual-scroll
class="row col-12" class="row col-12"
> >
<template v-slot:header="props">
<q-tr :props="props" class="bg-grey-2">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-body2 text-black">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div>
{{ !col.value ? "-" : col.value }}
</div>
</q-td>
</q-tr>
</template>
</q-table> </q-table>
</template> </template>

View file

@ -20,7 +20,7 @@ const {
columnsCertificates, columnsCertificates,
columnSalaries, columnSalaries,
columnTraining, columnTraining,
columnProjectsProposed, columnAssessments,
} = store; } = store;
const { date2Thai, showLoader, hideLoader } = mixin; const { date2Thai, showLoader, hideLoader } = mixin;
@ -42,7 +42,7 @@ const formDetail = reactive({
position: "", // position: "", //
oc: "", // oc: "", //
salary: "", // salary: "", //
positionLevel: "", //, positionLevel: "", //,
posNo: "", // posNo: "", //
birthDate: "", // birthDate: "", //
govAge: "", // govAge: "", //
@ -60,20 +60,20 @@ function formattedNumber(x: number) {
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
showLoader(); showLoader();
formDetail.prefix = props.data.prefix; formDetail.prefix = props.data.prefix ?? "-";
formDetail.fullName = props.data.fullName; formDetail.fullName = props.data.fullName ?? "-";
formDetail.position = props.data.position; formDetail.position = props.data.position ?? "-";
formDetail.oc = props.data.oc; formDetail.oc = props.data.oc ?? "-";
formDetail.salary = props.data.salary formDetail.salary = props.data.salary
? formattedNumber(props.data.salary) ? formattedNumber(props.data.salary)
: "-"; : "-";
formDetail.positionLevel = props.data.positionLevel; formDetail.positionLevel = props.data.positionLevel ?? "-";
formDetail.posNo = props.data.posNo; formDetail.posNo = props.data.posNo ?? "-";
formDetail.birthDate = formDetail.birthDate = props.data.birthDate
props.data.birthDate && date2Thai(props.data.birthDate); ? date2Thai(props.data.birthDate)
formDetail.govAge = props.data.govAge; : "-";
formDetail.govAge = props.data.govAge ?? "-";
formDetail.educations = props.data.educations; formDetail.educations = props.data.educations;
formDetail.certificates = props.data.certificates formDetail.certificates = props.data.certificates
? props.data.certificates.map((e: CertificatesForm) => ({ ? props.data.certificates.map((e: CertificatesForm) => ({
certificateNo: e.certificateNo, certificateNo: e.certificateNo,
@ -255,7 +255,9 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.educationLevel" :model-value="
education.educationLevel ? education.educationLevel : '-'
"
label="ระดับศึกษา" label="ระดับศึกษา"
/> />
</div> </div>
@ -264,7 +266,7 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.institute" :model-value="education.institute ? education.institute : '-'"
label="สถานศึกษา" label="สถานศึกษา"
/> />
</div> </div>
@ -272,7 +274,9 @@ onMounted(() => {
<div class="col-xs-6 col-sm-4 col-md-3"> <div class="col-xs-6 col-sm-4 col-md-3">
<q-input <q-input
borderless borderless
:model-value="date2Thai(education.startDate)" :model-value="
education.startDate ? date2Thai(education.startDate) : '-'
"
readonly readonly
label="ตั้งแต่" label="ตั้งแต่"
> >
@ -282,7 +286,9 @@ onMounted(() => {
<div class="col-xs-6 col-sm-4 col-md-3"> <div class="col-xs-6 col-sm-4 col-md-3">
<q-input <q-input
borderless borderless
:model-value="date2Thai(education.endDate)" :model-value="
education.endDate ? date2Thai(education.endDate) : '-'
"
readonly readonly
label="ถึง" label="ถึง"
> >
@ -291,7 +297,9 @@ onMounted(() => {
<div class="col-xs-6 col-sm-4 col-md-3"> <div class="col-xs-6 col-sm-4 col-md-3">
<q-input <q-input
borderless borderless
:model-value="date2Thai(education.finishDate)" :model-value="
education.finishDate ? date2Thai(education.finishDate) : '-'
"
readonly readonly
label="วันที่สำเร็จการศึกษา" label="วันที่สำเร็จการศึกษา"
> >
@ -311,7 +319,7 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.degree" :model-value="education.degree ? education.degree:'-'"
label="วุฒิการศึกษา" label="วุฒิการศึกษา"
/> />
</div> </div>
@ -320,7 +328,7 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.field" :model-value="education.field ? education.field : '-'"
label="สาขาวิชา/ทาง" label="สาขาวิชา/ทาง"
/> />
</div> </div>
@ -328,7 +336,7 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.fundName" :model-value="education.fundName? education.fundName:'-'"
label="ทุน" label="ทุน"
/> />
</div> </div>
@ -337,7 +345,7 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.gpa" :model-value="education.gpa ? education.gpa :'-'"
label="เกรดเฉลี่ย" label="เกรดเฉลี่ย"
/> />
</div> </div>
@ -346,10 +354,16 @@ onMounted(() => {
<q-input <q-input
borderless borderless
readonly readonly
:model-value="education.country" :model-value="education.country ? education.country : '-'"
label="ประเทศ" label="ประเทศ"
/> />
</div> </div>
<div
v-if="index + 1 !== formDetail.educations.length"
class="col-12"
>
<q-separator size="2px" />
</div>
</div> </div>
</div> </div>
<div v-else class="row col-12 q-pa-md">ไมประวการศกษา</div> <div v-else class="row col-12 q-pa-md">ไมประวการศกษา</div>
@ -403,7 +417,10 @@ onMounted(() => {
</div> </div>
<div class="col-12"><q-separator /></div> <div class="col-12"><q-separator /></div>
<div class="col-10"> <div class="col-10">
<TableData :columns="columnProjectsProposed" /> <TableData
:columns="columnAssessments"
:row="formDetail.assessments"
/>
</div> </div>
</q-card> </q-card>
</div> </div>

View file

@ -1,8 +1,13 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { ref } from "vue"; import { ref } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
const mixin = useCounterMixin();
const { date2Thai } = mixin;
export const useEvaluateDetailStore = defineStore("evaluateDetailStore", () => { export const useEvaluateDetailStore = defineStore("evaluateDetailStore", () => {
const tabMenu = ref<string>("1"); const tabMenu = ref<string>("1");
const step = ref<number>(1); const step = ref<number>(1);
@ -237,54 +242,119 @@ export const useEvaluateDetailStore = defineStore("evaluateDetailStore", () => {
]); ]);
/** คอลัมน์ ผลงานที่เคยเสนอขอประเมิน*/ /** คอลัมน์ ผลงานที่เคยเสนอขอประเมิน*/
const columnProjectsProposed = ref<QTableProps["columns"]>([ const columnAssessments = ref<QTableProps["columns"]>([
{ {
name: "receivedDate", name: "date",
align: "center", align: "left",
label: "วันที่ได้รับ", label: "วันที่ได้รับ",
sortable: true, sortable: true,
field: "receivedDate", field: "date",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
format: (v) => date2Thai(v),
}, },
{ {
name: "authority", name: "point1Total",
align: "left", align: "left",
label: "ผู้มีอำนาจลงนาม", label: "ส่วนที่1 (น้ำหนัก)",
sortable: true, sortable: true,
field: "authority", field: "point1Total",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
}, },
{ {
name: "datail", name: "point1",
align: "left", align: "left",
label: "รายละเอียด", label: "ผลประเมินส่วนที่1 (คะแนน)",
sortable: true, sortable: true,
field: "detail", field: "point1",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
}, },
{ {
name: "orderNumber", name: "point2Total",
align: "left", align: "left",
label: "เลขที่คำสั่ง", label: "ส่วนที่2 (น้ำหนัก)",
sortable: true, sortable: true,
field: "orderNumber", field: "point2Total",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
}, },
{ {
name: "doc", name: "point2",
align: "left", align: "left",
label: "เอกสารอ้างอิง", label: "ผลประเมินส่วนที่2 (คะแนน)",
sortable: true, sortable: true,
field: "doc", field: "point2",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "pointSumTotal",
align: "left",
label: "ผลรวม (น้ำหนัก)",
sortable: true,
field: "pointSumTotal",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "pointSum",
align: "left",
label: "ผลประเมินรวม (คะแนน)",
sortable: true,
field: "pointSum",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "name",
align: "left",
label: "ผลประเมิน",
sortable: true,
field: "name",
format(val, row) {
return `${textPoint(row.pointSum)} ${textRangePoint(row.pointSum)}`;
},
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
}, },
]); ]);
function textRangePoint(val: number | undefined) {
if (val == undefined) val = -1;
if (val < 60.0) return "(คะแนนต่ำกว่าร้อยละ 60.00)";
if (val >= 60.0 && val <= 69.99) return "(คะแนนร้อยละ 60.00 - 69.99)";
if (val >= 70.0 && val <= 79.99) return "(คะแนนร้อยละ 70.00 - 79.99)";
if (val >= 80.0 && val <= 89.99) return " (คะแนนร้อยละ 80.00 - 89.99)";
if (val >= 90.0) return " (คะแนนร้อยละ 90.00 ขึ้นไป)";
else return "";
}
function textPoint(val: number | undefined) {
if (val == undefined) val = -1;
if (val < 60.0) return "ต้องปรับปรุง";
if (val >= 60.0 && val <= 69.99) return "พอใช้";
if (val >= 70.0 && val <= 79.99) return "ดี";
if (val >= 80.0 && val <= 89.99) return "ดีมาก";
if (val >= 90.0) return "ดีเด่น";
else return "-";
}
return { return {
tabMenu, tabMenu,
step, step,
@ -294,7 +364,7 @@ export const useEvaluateDetailStore = defineStore("evaluateDetailStore", () => {
columnsCertificates, columnsCertificates,
columnSalaries, columnSalaries,
columnTraining, columnTraining,
columnProjectsProposed, columnAssessments,
pdfSrcStore, pdfSrcStore,
urlDownloadFile, urlDownloadFile,
numOfPagesStore, numOfPagesStore,

View file

@ -38,7 +38,6 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "ลำดับ", label: "ลำดับ",
sortable: false, sortable: false,
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
field: (row) => rows.value.indexOf(row) + 1, field: (row) => rows.value.indexOf(row) + 1,
@ -48,20 +47,24 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "ประเภทการลา", label: "ประเภทการลา",
sortable: true, sortable: true,
field: "leaveType",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
field: (row) => row.leaveType.name, format(val, row) {
return row.leaveType.name;
},
}, },
{ {
name: "dateLeave", name: "dateLeave",
align: "left", align: "left",
label: "วัน เดือน ปี ที่ลา", label: "วัน เดือน ปี ที่ลา",
sortable: true, sortable: true,
field: "dateLeave",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
field: (row) => dateThaiRange([row.dateLeaveStart, row.dateLeaveEnd]), format(val, row) {
return dateThaiRange([row.dateLeaveStart, row.dateLeaveEnd]);
},
}, },
{ {
name: "leaveDays", name: "leaveDays",
@ -165,7 +168,14 @@ onMounted(() => {
<q-card-section class="q-pt-none"> <q-card-section class="q-pt-none">
<div class="row items-center q-gutter-x-sm q-pb-sm"> <div class="row items-center q-gutter-x-sm q-pb-sm">
<q-space /> <q-space />
<q-input dense outlined v-model="keyword" label="ค้นหา" class="q-mr-sm" @keydown.enter="onSearch"> <q-input
dense
outlined
v-model="keyword"
label="ค้นหา"
class="q-mr-sm"
@keydown.enter="onSearch"
>
<template v-slot:append> <template v-slot:append>
<q-icon name="search" /> <q-icon name="search" />
</template> </template>