Merge branch 'develop' into devTee

This commit is contained in:
STW_TTTY\stwtt 2024-04-03 10:55:23 +07:00
commit 92914dfdda
9 changed files with 611 additions and 34 deletions

View file

@ -1,6 +1 @@
interface DataOption {
id: string;
name: string;
}
export type { DataOption };
export type {};

View file

@ -0,0 +1 @@
export type {};

View file

@ -1,6 +1 @@
interface DataOption {
id: string;
name: string;
}
export type { DataOption };
export type {};

View file

@ -1,12 +1,489 @@
<script setup lang="ts">
import { useQuasar } from "quasar";
import { ref, reactive, onMounted } from "vue";
import { useQuasar, type QTableProps } from "quasar";
import { useRouter } from "vue-router";
import DialogHeader from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
/** use*/
const $q = useQuasar();
const router = useRouter();
const { showLoader, hideLoader, date2Thai, dialogConfirm, dialogRemove } =
useCounterMixin();
/** หัวตาราง */
const rows = ref<any>([]);
const columns = ref<QTableProps["columns"]>([
{
name: "round",
align: "left",
label: "รอบการประเมิน ",
sortable: true,
field: "round",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "dateStart",
align: "left",
label: "วันเริ่มต้น",
sortable: true,
field: "dateStart",
format: (val) => date2Thai(val),
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "dateEnd",
align: "left",
label: "วันสิ้นสุด",
sortable: true,
field: "dateEnd",
format: (val) => date2Thai(val),
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
const visibleColumns = ref<string[]>(["round", "dateStart", "dateEnd"]);
const options = ref<any>([
"การศึกษาในประเทศ",
"ฝึกอบรมในประเทศที่ส่งไปพัฒนากับหน่วยวงานภายนอก (หลักสูตรที่ไม่มีการไปต่างประเทศ)",
"ฝึกอบรมในประเทศที่ส่งไปพัฒนากับหน่วยวงานภายนอก (หลักสูตรที่มีการไปต่างประเทศ)",
"ฝึกอบรมในประเทศที่ส่งไปพัฒนากับหน่วยวงานภายนอก (หลักสูตรประเภทนักบริหาร)",
]);
const itemMenu = ref<any>([
{
label: "เปิดรอบ",
value: "open",
icon: "mdi-check",
color: "primary",
},
{
label: "ปิดรอบ",
value: "close",
icon: "mdi-close",
color: "orange",
},
{
label: "ลบรอบ",
value: "delete",
icon: "delete",
color: "red",
},
]);
const roundOp = ref<any>([
{ id: "1", label: "รอบเมษา" },
{
id: "2",
label: "รอบตุลา",
},
]);
const formFilter = reactive({
page: 1,
pageSize: 10,
year: new Date().getFullYear(),
keyword: "",
});
const formData = reactive({
round: "",
dateStart: null,
dateEnd: null,
});
function fetchList() {
showLoader();
const data = [
{
id: "1",
round: "รอบเมษายน",
dateStart: new Date("2024-4-12"),
dateEnd: new Date("2024-4-12"),
},
{
id: "2",
round: "รอบตุลาคม",
dateStart: new Date("2024-4-12"),
dateEnd: new Date("2024-4-12"),
},
];
rows.value = data;
setTimeout(() => {
hideLoader();
}, 500);
}
const modalDialog = ref<boolean>(false);
const isStatusEdit = ref<boolean>(false);
function onClickAddOrView(status: boolean = false, id: string = "") {
isStatusEdit.value = status;
modalDialog.value = true;
}
function closeDialog() {
modalDialog.value = false;
clearFormData();
}
function changeDateStart() {
if (formData?.dateStart !== null && formData?.dateEnd !== null) {
const startDate = new Date(formData.dateStart);
const endDate = new Date(formData?.dateEnd);
if (startDate > endDate) {
formData.dateEnd = null;
}
}
}
function clearFormData() {
formData.round = "";
formData.dateStart = null;
formData.dateEnd = null;
}
function onSubmit() {
dialogConfirm($q, () => {
closeDialog();
});
}
function onClickAction(action: string) {
switch (action) {
case "open":
onOpenRounde();
break;
case "close":
onCloseRounde();
break;
case "delete":
onDeleteRound();
break;
default:
break;
}
}
function onOpenRounde() {
dialogConfirm(
$q,
() => {},
"ยืนยันการเปิดรอบ",
"ต้องการยืนยันการเปิดรอบนี้หรือไม่ ?"
);
}
function onCloseRounde() {
dialogConfirm(
$q,
() => {},
"ยืนยันการปิดรอบ",
"ต้องการยืนยันการปิดรอบนี้หรือไม่ ?"
);
}
function onDeleteRound() {
dialogRemove($q, () => {});
}
onMounted(() => {
fetchList();
});
</script>
<template>KPI Page</template>
<template>
<div class="toptitle text-dark col-12 row items-center">
รายการรอบการประเมนผลการปฏหนาทราชการ
</div>
<q-card flat bordered class="q-pa-md">
<q-toolbar style="padding: 0px">
<div class="row q-gutter-sm">
<datepicker
menu-class-name="modalfix"
v-model="formFilter.year"
:locale="'th'"
autoApply
year-picker
:enableTimePicker="false"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
lazy-rules
outlined
:model-value="Number(formFilter.year) + 543"
:label="`${'ปีงบประมาณ'}`"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
<q-btn
flat
round
dense
icon="add"
color="primary"
@click="onClickAddOrView()"
>
<q-tooltip>เพ</q-tooltip>
</q-btn>
</div>
<q-space />
<div class="row q-gutter-sm">
<!-- <q-btn
flat
round
color="blue"
icon="mdi-arrow-down-bold-circle-outline"
>
<q-menu>
<q-list style="min-width: 100px" dense>
<q-item clickable v-close-popup v-for="items in itemDownload">
<q-item-section avatar>
<q-icon :color="items.color" :name="items.icon" />
</q-item-section>
<q-item-section :class="`text-${items.color}`">{{
items.label
}}</q-item-section>
</q-item>
</q-list>
</q-menu>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn> -->
<q-input
standout
dense
v-model="formFilter.keyword"
ref="filterRef"
outlined
debounce="300"
placeholder="ค้นหา"
>
<template v-slot:append>
<q-icon v-if="formFilter.keyword == ''" name="search" />
<q-icon
v-if="formFilter.keyword !== ''"
name="clear"
class="cursor-pointer"
@click="formFilter.keyword = ''"
/>
</template>
</q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
/>
</div>
</q-toolbar>
<div class="col-12">
<d-table
for="table"
ref="table"
:columns="columns"
:rows="rows"
row-key="subject"
flat
bordered
dense
class="custom-header-table"
:visible-columns="visibleColumns"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div class="table_ellipsis">
{{ col.value ? col.value : "-" }}
</div>
</q-td>
<q-td>
<q-btn flat round color="grey" icon="mdi-dots-vertical">
<q-menu>
<q-list style="min-width: 150px" dense>
<q-item
clickable
v-close-popup
v-for="items in itemMenu"
@click="onClickAction(items.value)"
>
<q-item-section avatar>
<q-icon :color="items.color" :name="items.icon" />
</q-item-section>
<q-item-section>{{ items.label }}</q-item-section>
</q-item>
</q-list>
</q-menu>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
</q-td>
</q-tr>
</template>
</d-table>
</div>
</q-card>
<q-dialog v-model="modalDialog" persistent>
<q-card style="width: 350px">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader
:tittle="'เพิ่มรอบการประเมินผลกานปฏิบัติหน้าที่ราชการ'"
:close="closeDialog"
/>
<q-separator />
<q-card-section class="q-pt-none">
<div class="row col-12 q-pa-md q-col-gutter-md">
<div class="col-12">
<q-select
dense
outlined
hide-bottom-space
lazy-rules
v-model="formData.round"
:options="roundOp"
option-label="label"
option-value="id"
emit-value
map-options
input-class="text-red"
label="รอบการประเมิน"
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกรอบการประเมิน'}`,
]"
/>
</div>
<div class="col-12">
<datepicker
menu-class-name="modalfix"
v-model="formData.dateStart"
:locale="'th'"
autoApply
:enableTimePicker="false"
week-start="0"
@update:model-value="changeDateStart()"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
outlined
:model-value="
formData.dateStart ? date2Thai(formData.dateStart) : null
"
:label="`${'วันเริ่มต้น'}`"
hide-bottom-space
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกวันที่เริ่มต้น'}`,
]"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-12">
<datepicker
menu-class-name="modalfix"
v-model="formData.dateEnd"
:locale="'th'"
autoApply
:enableTimePicker="false"
week-start="0"
:min-date="formData.dateStart"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
outlined
:model-value="
formData.dateEnd ? date2Thai(formData.dateEnd) : null
"
:label="`${'วันสิ้นสุด'}`"
hide-bottom-space
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกวันที่วันสิ้นสุด'}`,
]"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right" class="bg-white text-teal">
<q-btn dense unelevated label="บันทึก" type="submit" color="public">
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<style scoped></style>

View file

@ -1,20 +1,33 @@
<script setup lang="ts">
import { onMounted, ref, reactive } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import type { QTableProps } from "quasar";
import type { DataOption } from "@/modules/15_development/interface/index/Main";
import type {
FormGroupTarget,
FormGroupRelate,
} from "@/modules/15_development/interface/request/Main";
import type {
ResGroup,
ResLevel,
} from "@/modules/15_development/interface/response/Main";
import DialogHeader from "@/components/DialogHeader.vue";
import { useCounterMixin } from "@/stores/mixin";
const $q = useQuasar();
const { showLoader, hideLoader, dialogConfirm, dialogRemove, success } =
useCounterMixin();
const {
showLoader,
hideLoader,
dialogConfirm,
dialogRemove,
success,
messageError,
} = useCounterMixin();
const columnsGroup = ref<QTableProps["columns"]>([
{
@ -85,9 +98,19 @@ const rows3 = ref<any>([
]);
const rows4 = ref<any>([{ related: "เจ้าหน้าที่", amount: 10 }]);
const options = ref<any>([
"ข้าราชการกรุงเทพมหานคร",
"ข้าราชการกรุงเทพมหานครสามัญ",
"เจ้าหน้าที่ดำเนิดการ",
// "",
// "",
// "",
]);
const groupOp = ref<DataOption[]>([
{ id: "1", name: "ข้าราชการกรุงเทพมหานคร" },
{ id: "2", name: "บุคลากรกรุงเทพมหานคร" },
{ id: "3", name: "บุคคลภายนอก" },
]);
const groupSubOp = ref<DataOption[]>([
{ id: "1", name: "ข้าราชการกรุงเทพมหานครสามัญ" },
{ id: "2", name: "ข้าราชการครู" },
]);
const modalGroupTarget = ref<boolean>(false);
@ -108,9 +131,33 @@ const formGroupRelate = reactive<FormGroupRelate>({
amount: null,
});
const posTypeOp = ref<DataOption[]>([]);
const posLevelOp = ref<DataOption[]>([]);
const posTypeMain = ref<ResGroup[]>([]);
/** function เรียกข้อมูลประเภทตำแหน่ง*/
function fetchType() {
if (posTypeMain.value.length === 0) {
http
.get(config.API.orgPosType)
.then((res) => {
const data = res.data.result;
posTypeMain.value = data;
posTypeOp.value = data.map((e: ResGroup) => ({
id: e.id,
name: e.posTypeName,
}));
})
.catch((err) => {
messageError($q, err);
});
}
}
function onClickOpenDialog(type: string) {
if (type === "group") {
modalGroupTarget.value = true;
fetchType();
} else {
modalRelate.value = true;
}
@ -154,6 +201,16 @@ function onClickCloseDialog() {
cleanFormData();
}
function updatePosTypeName(id: string) {
const posLevel = posTypeMain.value.find((e: ResGroup) => e.id === id);
posLevelOp.value =
posLevel?.posLevels.map((e: ResLevel) => ({
id: e.id,
name: e.posLevelName.toString(),
})) ?? [];
formGroupTarget.level = "";
}
onMounted(() => {
console.log("เป้าหมาย");
});
@ -405,9 +462,13 @@ onMounted(() => {
dense
outlined
v-model="formGroupTarget.groupTarget"
:options="options"
:options="groupOp"
label="กลุ่มเป้าหมาย"
hide-bottom-space
option-label="name"
option-value="id"
map-options
emit-value
lazy-rules
:rules="[
(val:string) =>
@ -420,10 +481,14 @@ onMounted(() => {
dense
outlined
v-model="formGroupTarget.groupTargetSub"
:options="options"
:options="groupSubOp"
label="กลุ่มเป้าหมายย่อย"
hide-bottom-space
lazy-rules
option-label="name"
option-value="id"
map-options
emit-value
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกกลุ่มเป้าหมายย่อย'}`,
@ -444,29 +509,44 @@ onMounted(() => {
/>
</div>
<div class="col-xs-6 col-sm-4 col-md-4">
<q-input
outlined
<q-select
dense
outlined
hide-bottom-space
lazy-rules
v-model="formGroupTarget.posType"
:options="posTypeOp"
option-label="name"
option-value="id"
emit-value
map-options
input-class="text-red"
label="ประเภทตำแหน่ง"
@update:model-value="updatePosTypeName"
:rules="[
(val:string) =>
!!val || `${'กรุณากรอกประเภทตำแหน่ง'}`,
]"
(val:string) =>
!!val || `${'กรุณาเลือกประเภทตำแหน่ง'}`,
]"
/>
</div>
<div class="col-xs-6 col-sm-4 col-md-4">
<q-input
outlined
<q-select
dense
outlined
hide-bottom-space
lazy-rules
v-model="formGroupTarget.level"
:options="posLevelOp"
option-label="name"
option-value="id"
emit-value
map-options
input-class="text-red"
label="ระดับ"
:rules="[
(val:string) =>
!!val || `${'กรุณากรอกระดับ'}`,
]"
(val:string) =>
!!val || `${'กรุณาเลือกระดับ'}`,
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-8">

View file

@ -8,4 +8,4 @@ interface DataOptionCheckBox {
value: string;
}
export type { DataOption,DataOptionCheckBox };
export type { DataOption, DataOptionCheckBox };

View file

@ -0,0 +1,17 @@
interface ResGroup {
id: string;
posLevels: ResLevel[];
posTypeName: string;
posTypeRank: number;
posTypeShortName: string;
}
interface ResLevel {
id: string;
posLevelName: number;
posTypeName: string;
posTypeId: string;
posLevelAuthority: string;
}
export type { ResGroup, ResLevel };

View file

@ -148,7 +148,12 @@ onMounted(() => {
</q-btn>
<q-space />
<div class="row q-gutter-sm">
<q-btn flat round color="primary" icon="mdi-download-outline">
<q-btn
flat
round
color="blue"
icon="mdi-arrow-down-bold-circle-outline"
>
<q-menu>
<q-list style="min-width: 100px" dense>
<q-item clickable v-close-popup v-for="items in itemDownload">
@ -161,6 +166,7 @@ onMounted(() => {
</q-item>
</q-list>
</q-menu>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
<q-input

View file

@ -214,7 +214,12 @@ onMounted(() => {
<q-space />
<div class="row q-gutter-sm">
<q-btn flat round color="primary" icon="mdi-download-outline">
<q-btn
flat
round
color="blue"
icon="mdi-arrow-down-bold-circle-outline"
>
<q-menu>
<q-list style="min-width: 100px" dense>
<q-item clickable v-close-popup v-for="items in itemDownload">
@ -227,6 +232,7 @@ onMounted(() => {
</q-item>
</q-list>
</q-menu>
<q-tooltip>ดาวนโหลด</q-tooltip>
</q-btn>
<q-input