Merge branch 'develop' into devTee

# Conflicts:
#	src/api/15_development/api.development.ts
#	src/modules/15_development/interface/index/Main.ts
#	src/modules/15_development/interface/request/Main.ts
This commit is contained in:
STW_TTTY\stwtt 2024-04-03 17:13:53 +07:00
commit 5c1747262f
12 changed files with 210 additions and 98 deletions

View file

@ -9,4 +9,6 @@ export default {
developmentHistoryList: (type:string) => `${development}/history/${type}/`, developmentHistoryList: (type:string) => `${development}/history/${type}/`,
developmentHistoryAdd: (type:string) => `${development}/history/${type}`, developmentHistoryAdd: (type:string) => `${development}/history/${type}`,
developmentProjectSearch: () => `${development}/main/search`, developmentProjectSearch: () => `${development}/main/search`,
/** รายการโครงการ*/
developmentMain: `${development}/main`,
}; };

View file

@ -14,8 +14,8 @@
:pagination-label="paginationLabel" :pagination-label="paginationLabel"
v-model:pagination="pagination" v-model:pagination="pagination"
> >
<template v-slot:pagination="scope"> <template v-slot:pagination="scope">
งหมด {{ props.total }} รายการ งหมด {{ props.total }} รายการ
<q-pagination <q-pagination
v-model="currentPage" v-model="currentPage"
active-color="primary" active-color="primary"
@ -24,7 +24,8 @@
size="sm" size="sm"
boundary-links boundary-links
direction-links direction-links
></q-pagination> :max-pages="5"
></q-pagination>
</template> </template>
<template v-slot:top="props"> <template v-slot:top="props">
@ -450,7 +451,7 @@
<PopupADdEmployee v-model:modal="modalEmployee" /> <PopupADdEmployee v-model:modal="modalEmployee" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, reactive,watch } from "vue"; import { ref, useAttrs, reactive, watch } from "vue";
import type { Pagination } from "@/modules/04_registry/interface/index/Main"; import type { Pagination } from "@/modules/04_registry/interface/index/Main";
import type { DataOption } from "@/modules/04_registry/components/profileType"; import type { DataOption } from "@/modules/04_registry/components/profileType";
import PopupHistory from "./PopupHistory.vue"; import PopupHistory from "./PopupHistory.vue";
@ -461,7 +462,6 @@ const maxPage = ref<number>(1);
const page = ref<number>(1); const page = ref<number>(1);
const rowsPerPage = ref<number>(50); const rowsPerPage = ref<number>(50);
const attrs = ref<any>(useAttrs()); const attrs = ref<any>(useAttrs());
const table = ref<any>(null); const table = ref<any>(null);
const filterRef = ref<any>(null); const filterRef = ref<any>(null);
@ -470,7 +470,7 @@ const searchPanel = ref<boolean>(true);
/** /**
*pagination ของตาราง *pagination ของตาราง
*/ */
const pagination = ref({ const pagination = ref({
descending: false, descending: false,
page: page.value, page: page.value,
rowsPerPage: rowsPerPage.value, rowsPerPage: rowsPerPage.value,
@ -681,11 +681,14 @@ watch(
} }
); );
watch(()=>props.page,()=>{ watch(
if(props.page){ () => props.page,
currentPage.value = props.page () => {
if (props.page) {
currentPage.value = props.page;
}
} }
}) );
</script> </script>
<style lang="scss"> <style lang="scss">
.icon-color { .icon-color {

View file

@ -22,6 +22,7 @@ const props = defineProps({
rows: { type: Array }, rows: { type: Array },
fetchData: { type: Function }, fetchData: { type: Function },
fetchType: { type: Function }, fetchType: { type: Function },
total: { type: Number },
}); });
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
@ -74,7 +75,7 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "สายงาน", label: "สายงาน",
sortable: true, sortable: true,
field: (v) => (v.posType ? v.posType.posTypeName : "-"), field: "posType",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) => sort: (a: string, b: string) =>
@ -85,7 +86,7 @@ const columns = ref<QTableProps["columns"]>([
align: "left", align: "left",
label: "ระดับตำแหน่ง", label: "ระดับตำแหน่ง",
sortable: true, sortable: true,
field: (v) => (v.posLevel ? v.posLevel.posLevelName : "-"), field: "posLevel",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
sort: (a: string, b: string) => sort: (a: string, b: string) =>
@ -282,12 +283,8 @@ watch(
</q-tr> </q-tr>
</template> </template>
<template v-slot:body="props" v-if="store.mode === 'table'"> <template v-slot:body="props" v-if="store.mode === 'table'">
<q-tr :props="props" class="cursor-pointer"> <q-tr :props="props">
<q-td <q-td v-for="col in props.cols" :key="col.id">
v-for="col in props.cols"
:key="col.id"
@click="onClickViewDetail(props.row.id)"
>
<div v-if="col.name === 'no'"> <div v-if="col.name === 'no'">
{{ {{
(formFilter.page - 1) * formFilter.pageSize + props.rowIndex + 1 (formFilter.page - 1) * formFilter.pageSize + props.rowIndex + 1
@ -311,7 +308,11 @@ watch(
</q-avatar> </q-avatar>
</q-item-section> </q-item-section>
<q-item-section> <q-item-section>
<div class="text-weight-medium"> <div
class="text-weight-medium text-primary cursor-pointer"
@click="onClickViewDetail(props.row.id)"
>
<q-tooltip>ทะเบยนประว</q-tooltip>
{{ {{
`${props.row.prefix}${props.row.firstName} ${props.row.lastName}` `${props.row.prefix}${props.row.firstName} ${props.row.lastName}`
}} }}
@ -329,18 +330,13 @@ watch(
</template> </template>
<template v-slot:item="props" v-else> <template v-slot:item="props" v-else>
<div class="col-xs-12 col-sm-4 col-md-3"> <div class="col-xs-12 col-sm-4 col-md-3">
<q-card <q-card flat bordered class="">
flat
bordered
class="cardRO"
@click="onClickViewDetail(props.row.id)"
>
<q-card-section class="text-center q-pb-none"> <q-card-section class="text-center q-pb-none">
<q-avatar size="80px"> <q-avatar size="80px">
<img src="@/assets/avatar_user.jpg" /> <img src="@/assets/avatar_user.jpg" />
</q-avatar> </q-avatar>
<div class="text-weight-medium q-mt-md textName"> <div class="text-weight-medium q-mt-md">
{{ {{
`${props.row.prefix}${props.row.firstName} ${props.row.lastName}` `${props.row.prefix}${props.row.firstName} ${props.row.lastName}`
}} }}
@ -384,7 +380,7 @@ watch(
<q-item-section> <q-item-section>
<q-item-label caption class="text-black"> <q-item-label caption class="text-black">
{{ {{
props.row.posType ? props.row.posType.posTypeName : "-" props.row.posType ? props.row.posType : "-"
}}</q-item-label }}</q-item-label
> >
</q-item-section> </q-item-section>
@ -397,9 +393,7 @@ watch(
<q-item-section> <q-item-section>
<q-item-label caption class="text-black"> <q-item-label caption class="text-black">
{{ {{
props.row.posLevel props.row.posLevel ? props.row.posLevel : "-"
? props.row.posLevel.posLevelName
: "-"
}}</q-item-label }}</q-item-label
> >
</q-item-section> </q-item-section>
@ -407,18 +401,19 @@ watch(
</q-list> </q-list>
</q-card> </q-card>
</q-card-section> </q-card-section>
<!-- <q-separator inset /> <q-separator inset />
<q-btn <q-btn
flat flat
color="black" color="black"
label="ดูเพิ่มเติม" label="ดูเพิ่มเติม"
class="hover-button full-width q-pa-md" class="hover-button full-width q-pa-md"
@click="onClickViewDetail(props.row.id)" @click="onClickViewDetail(props.row.id)"
/> --> />
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:pagination="scope"> <template v-slot:pagination="scope">
งหมด {{ props.total }} รายการ
<q-pagination <q-pagination
v-model="formFilter.page" v-model="formFilter.page"
active-color="primary" active-color="primary"

View file

@ -109,6 +109,7 @@ function fetchYearOption() {
} }
} }
const total = ref<number>(0);
async function fetchDataPerson(search: boolean = false) { async function fetchDataPerson(search: boolean = false) {
showLoader(); showLoader();
@ -150,6 +151,7 @@ async function fetchDataPerson(search: boolean = false) {
.then((res) => { .then((res) => {
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize); maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
dataPersonMain.value = res.data.result.data; dataPersonMain.value = res.data.result.data;
total.value = res.data.result.total;
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
@ -603,6 +605,7 @@ onMounted(async () => {
v-model:maxPage="maxPage" v-model:maxPage="maxPage"
:fetchData="fetchDataPerson" :fetchData="fetchDataPerson"
:fetchType="fetchType" :fetchType="fetchType"
:total="total"
/> />
</q-card-section> </q-card-section>
</q-card> </q-card>

View file

@ -94,6 +94,27 @@ const columns = ref<QTableProps["columns"]>([
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },
{
name: "group",
align: "left",
label: "ผังค่าจ้าง(เดิม)",
sortable: false,
field: "group",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
return val ? "กลุ่ม" + val : "-";
},
},
{
name: "salaryLevel",
align: "left",
label: "ขั้น(เดิม)",
sortable: false,
field: "salaryLevel",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{ {
name: "amount", name: "amount",
align: "left", align: "left",
@ -140,6 +161,8 @@ const visibleColumns = ref<string[]>([
"position", "position",
"posType", "posType",
"posLevel", "posLevel",
"group",
"salaryLevel",
"amount", "amount",
"amountUse", "amountUse",
"positionSalaryAmount", "positionSalaryAmount",
@ -283,7 +306,7 @@ watch(
store.roundMainCode === 'OCT' store.roundMainCode === 'OCT'
? columns ? columns
: columns : columns
? columns.slice(0, 10) ? columns.slice(0, 11)
: [] : []
" "
option-value="name" option-value="name"
@ -299,7 +322,7 @@ watch(
store.roundMainCode === 'OCT' store.roundMainCode === 'OCT'
? columns ? columns
: columns : columns
? columns.slice(0, 10) ? columns.slice(0, 11)
: [] : []
" "
:rows="props.rows" :rows="props.rows"
@ -382,16 +405,12 @@ watch(
}} }}
</div> </div>
<div <div v-else-if="col.name === 'isRetired'">
v-else-if="
col.name === 'isRetired' && store.roundMainCode === 'OCT'
"
>
<q-icon <q-icon
name="check" name="check"
color="primary" color="primary"
size="24px" size="24px"
v-if="props.row.isRetired" v-if="props.row.isRetired && store.roundMainCode === 'OCT'"
/> />
</div> </div>

View file

@ -89,6 +89,27 @@ const columns = ref<QTableProps["columns"]>([
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
}, },
{
name: "group",
align: "left",
label: "ผังค่าจ้าง(เดิม)",
sortable: false,
field: "group",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val, row) {
return val ? "กลุ่ม" + val : "-";
},
},
{
name: "salaryLevel",
align: "left",
label: "ขั้น(เดิม)",
sortable: false,
field: "salaryLevel",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{ {
name: "amount", name: "amount",
align: "left", align: "left",
@ -176,6 +197,8 @@ const visibleColumns = ref<string[]>([
"isSuspension", "isSuspension",
"isAbsent", "isAbsent",
"isLeave", "isLeave",
"group",
"salaryLevel",
]); ]);
/** modalDialog*/ /** modalDialog*/

View file

@ -392,16 +392,12 @@ watch(
}} }}
</div> </div>
<div <div v-else-if="col.name === 'isRetired'">
v-else-if="
col.name === 'isRetired' && store.roundMainCode === 'OCT'
"
>
<q-icon <q-icon
name="check" name="check"
color="primary" color="primary"
size="24px" size="24px"
v-if="props.row.isRetired" v-if="props.row.isRetired && store.roundMainCode === 'OCT'"
/> />
</div> </div>

View file

@ -22,4 +22,18 @@ interface FormFilter {
isProbation: boolean | null; isProbation: boolean | null;
} }
export type { DataOption, DataOptionCheckBox,FormFilter }; interface ItemsMenu {
label: string;
value: string;
icon: string;
color: string;
}
interface NewPagination {
descending: boolean;
page: number;
rowsPerPage: number;
sortBy: string;
}
export type { DataOption, DataOptionCheckBox, ItemsMenu, NewPagination ,FormFilter};

View file

@ -1,5 +1,7 @@
interface FormQueryProject { interface FormQueryListProject {
year: number; year: number;
page: number;
pageSize: number;
keyword: string; keyword: string;
} }
@ -94,7 +96,7 @@ interface FormAddHistoryProject {
} }
export type { export type {
FormQueryProject, FormQueryListProject,
FormBasicinfo, FormBasicinfo,
FormGroupTarget, FormGroupTarget,
FormGroupRelate, FormGroupRelate,

View file

@ -14,4 +14,10 @@ interface ResLevel {
posLevelAuthority: string; posLevelAuthority: string;
} }
export type { ResGroup, ResLevel }; interface ResListProject {
id: string;
projectName: string;
year: number;
}
export type { ResGroup, ResLevel, ResListProject };

View file

@ -1,23 +1,16 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { reactive } from "vue"; import { ref } from "vue";
import { ref } from 'vue'
import type { FormQueryProject } from "@/modules/15_development/interface/request/Main";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
// store // store
export const useDevelopmentDataStore = defineStore( export const useDevelopmentDataStore = defineStore(
"developmentDataStore", "developmentDataStore",
() => { () => {
const formFilter = reactive<FormQueryProject>({
year: new Date().getFullYear(),
keyword: "",
});
const visibleColumns = ref<string[]>([]); const visibleColumns = ref<string[]>([]);
const columns = ref<QTableProps["columns"]>([]); const columns = ref<QTableProps["columns"]>([]);
const rows = ref<any[]>([]) const rows = ref<any[]>([]);
return { return {
formFilter,
visibleColumns, visibleColumns,
columns, columns,
rows, rows,

View file

@ -1,20 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from "vue"; import { ref, onMounted, reactive, watch } from "vue";
import { useQuasar, type QTableProps } from "quasar"; import { useQuasar, type QTableProps } from "quasar";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
/**importType*/
import type {
ItemsMenu,
NewPagination,
} from "@/modules/15_development/interface/index/Main";
import type { FormQueryListProject } from "@/modules/15_development/interface/request/Main";
import type { ResListProject } from "@/modules/15_development/interface/response/Main";
/** importStore*/ /** importStore*/
import { useDevelopmentDataStore } from "@/modules/15_development/store/developmentStore";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
/** use*/ /** use*/
const store = useDevelopmentDataStore();
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const { showLoader, hideLoader } = useCounterMixin(); const { showLoader, hideLoader, messageError } = useCounterMixin();
/** หัวตาราง */ /** หัวตาราง */
const rows = ref<any>([]);
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "year", name: "year",
@ -23,16 +30,17 @@ const columns = ref<QTableProps["columns"]>([
sortable: true, sortable: true,
field: "year", field: "year",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px ;width: 10%",
format: (val) => val + 543,
}, },
{ {
name: "name", name: "projectName",
align: "left", align: "left",
label: "ชื่อโครงการ/กิจกรรม/หลักสูตร", label: "ชื่อโครงการ/กิจกรรม/หลักสูตร",
sortable: true, sortable: true,
field: "name", field: "projectName",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px;width: 45%",
}, },
{ {
@ -42,12 +50,13 @@ const columns = ref<QTableProps["columns"]>([
sortable: true, sortable: true,
field: "org", field: "org",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px ;width: 45%",
}, },
]); ]);
const visibleColumns = ref<string[]>(["year", "name", "org"]); const visibleColumns = ref<string[]>(["year", "projectName", "org"]);
const itemDownload = ref<any>([ /** เมนูดาวน์โหลด*/
const itemDownload = ref<ItemsMenu[]>([
{ {
label: "ดาวน์โหลด 1", label: "ดาวน์โหลด 1",
value: "", value: "",
@ -68,32 +77,63 @@ const itemDownload = ref<any>([
}, },
]); ]);
/** formQuery*/
const formQuery = reactive<FormQueryListProject>({
year: new Date().getFullYear(),
page: 1,
pageSize: 10,
keyword: "",
});
const totalList = ref<number>(1); //
const rows = ref<ResListProject[]>([]); //
/** funciton fetch รายการโครงการ*/
function fetchListProject() { function fetchListProject() {
showLoader(); showLoader();
const data = [ http
{ .get(
id: "1", config.API.developmentMain +
year: 2567, `?page=${formQuery.page}&pageSize=${formQuery.pageSize}&keyword=${formQuery.keyword}&year=${formQuery.year}`
name: "โครงการฝึกอบรมสำนักงานข้าราชการ", )
org: "สำนักงานข้าราชการ/กองบริหารทั่วไป/กลุ่มงานช่วยนักบริหาร", .then((res) => {
}, const data = res.data.result.data;
{ totalList.value = Math.ceil(res.data.result.total / formQuery.pageSize);
id: "2", rows.value = data;
year: 2567, })
name: "โครงการฝึกอบรม", .catch((err) => {
org: "สำนักงานข้าราชการ/กองบริหารทั่วไป/กลุ่มงานช่วยนักบริหาร", messageError($q, err);
}, })
]; .finally(() => {
rows.value = data; hideLoader();
setTimeout(() => { });
hideLoader();
}, 500);
} }
/**
* funciotn redirect to page เพมหรอแกไข รายการโครงการ
* @param status สถานะแกไข
* @param id รายการโครงการ
*/
function onClickAddOrView(status: boolean = false, id: string = "") { function onClickAddOrView(status: boolean = false, id: string = "") {
status ? router.push(`development/${id}`) : router.push("development/add"); status ? router.push(`development/${id}`) : router.push("development/add");
} }
/**
* function updatePagination
* @param newPagination อม Pagination ใหม
*/
function updatePagination(newPagination: NewPagination) {
formQuery.page = 1;
formQuery.pageSize = newPagination.rowsPerPage;
}
/** callbackFunction ทำเมื่อมีการอัปเดท pageSize*/
watch(
() => formQuery.pageSize,
() => {
fetchListProject();
}
);
onMounted(() => { onMounted(() => {
fetchListProject(); fetchListProject();
}); });
@ -107,11 +147,12 @@ onMounted(() => {
<q-toolbar style="padding: 0px"> <q-toolbar style="padding: 0px">
<datepicker <datepicker
menu-class-name="modalfix" menu-class-name="modalfix"
v-model="store.formFilter.year" v-model="formQuery.year"
:locale="'th'" :locale="'th'"
autoApply autoApply
year-picker year-picker
:enableTimePicker="false" :enableTimePicker="false"
@update:model-value="fetchListProject"
> >
<template #year="{ year }">{{ year + 543 }}</template> <template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{ <template #year-overlay-value="{ value }">{{
@ -122,7 +163,7 @@ onMounted(() => {
dense dense
lazy-rules lazy-rules
outlined outlined
:model-value="Number(store.formFilter.year) + 543" :model-value="Number(formQuery.year) + 543"
:label="`${'ปีงบประมาณ'}`" :label="`${'ปีงบประมาณ'}`"
> >
<template v-slot:prepend> <template v-slot:prepend>
@ -172,19 +213,19 @@ onMounted(() => {
<q-input <q-input
standout standout
dense dense
v-model="store.formFilter.keyword" v-model="formQuery.keyword"
ref="filterRef" ref="filterRef"
outlined outlined
debounce="300"
placeholder="ค้นหา" placeholder="ค้นหา"
@keyup.enter="fetchListProject"
> >
<template v-slot:append> <template v-slot:append>
<q-icon v-if="store.formFilter.keyword == ''" name="search" /> <q-icon v-if="formQuery.keyword == ''" name="search" />
<q-icon <q-icon
v-if="store.formFilter.keyword !== ''" v-if="formQuery.keyword !== ''"
name="clear" name="clear"
class="cursor-pointer" class="cursor-pointer"
@click="store.formFilter.keyword = ''" @click="(formQuery.keyword = ''), fetchListProject()"
/> />
</template> </template>
</q-input> </q-input>
@ -212,12 +253,14 @@ onMounted(() => {
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
row-key="subject" row-key="id"
flat flat
bordered bordered
dense dense
class="custom-header-table" class="custom-header-table"
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
@update:pagination="updatePagination"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -240,6 +283,19 @@ onMounted(() => {
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<template v-slot:pagination="scope">
<q-pagination
v-model="formQuery.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="fetchListProject"
></q-pagination>
</template>
</d-table> </d-table>
</div> </div>
</q-card> </q-card>