fix(director):sort

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-10-09 14:50:02 +07:00
parent 629efe5abf
commit 0bec7d1dbc
5 changed files with 270 additions and 368 deletions

View file

@ -7,6 +7,7 @@ const appeal = `${env.API_URI}/discipline/complaint_appeal`;
const disciplineReport = `${env.API_URI}/discipline/report`;
export default {
directorListMain: `${disciplineMain}/director/`,
directorList: (
page: number,
pageSize: number,

View file

@ -19,32 +19,31 @@ const router = useRouter();
* @param id ระบ คคล
*/
function onSubmit(formData: FormDataPost) {
dialogConfirm($q, () => addData(formData));
}
function addData(formData: FormDataPost) {
showLoader();
http
.post(config.API.director(), {
personalId: formData.personalId ?? "",
prefix: formData.prefix,
firstName: formData.firstname,
lastName: formData.lastname,
position: formData.position,
email: formData.email,
phone: formData.phone,
qualification: formData.qualification,
rootDnaId: formData.rootDnaId,
})
.then((res) => {
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
router.push(`/discipline/director`);
});
dialogConfirm($q, async () => {
showLoader();
await http
.post(config.API.director(), {
personalId: formData.personalId ?? "",
prefix: formData.prefix,
firstName: formData.firstname,
lastName: formData.lastname,
position: formData.position,
email: formData.email,
phone: formData.phone,
qualification: formData.qualification,
rootDnaId: formData.rootDnaId,
})
.then(async () => {
await success($q, "บันทึกข้อมูลสำเร็จ");
await router.push(`/discipline/director`);
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
}
</script>
<template>

View file

@ -7,6 +7,7 @@ import { useRoute } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { usePagination } from "@/composables/usePagination";
import type {
FormData,
@ -18,15 +19,6 @@ import type {
import PopupPersonal from "@/components/Dialogs/PopupPersonalNew.vue";
const total = ref<number>(0);
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
});
const route = useRoute();
const modalPersonal = ref<boolean>(false);
const personId = ref<string>("");
@ -36,6 +28,7 @@ const search = ref<string>("");
const $q = useQuasar();
const mixin = useCounterMixin();
const { messageError, showLoader, hideLoader } = mixin;
const { pagination, params, onRequest } = usePagination("", getSearch);
/** รับ props มาจาก page หลัก */
const props = defineProps({
@ -56,16 +49,8 @@ const typeOps = ref<typeOp[]>([
]);
const isReadonly = ref<boolean>(false); //
const emit = defineEmits(["formDataReturn"]);
/**
* อมลเลขประจำตวประชาชน
*/
//
const idCard = ref<string>("");
const idCardRef = ref<any>(null);
/**
* อมลทงกอน form
*/
/** ข้อมูลทั้งก้อน form*/
const formData = reactive<FormData>({
personalId: "",
prefix: "",
@ -78,9 +63,7 @@ const formData = reactive<FormData>({
rootDnaId: "",
});
/**
* ตรวจสอบขอมลกอนสงไปย api
*/
/** ตรวจสอบข้อมูลก่อนส่งไปยัง api*/
const prefixRef = ref<object | null>(null);
const firstnameRef = ref<object | null>(null);
const lastnameRef = ref<object | null>(null);
@ -183,11 +166,8 @@ function updateSelect() {
/** ค้าหาข้อมูล */
async function searchInput() {
searchRef.value.validate();
if (!searchRef.value.hasError) {
pagination.value.page = 1;
await getSearch();
}
pagination.value.page = 1;
await getSearch();
}
/** ดึงข้อมูล */
@ -195,44 +175,40 @@ async function getSearch() {
showLoader();
const body = {
fieldName: type.value,
keyword: search.value,
keyword: search.value ? search.value.trim() : "",
system: (route.meta?.Key as string) || undefined,
};
await http
.post(
config.API.orgSearchPersonal() +
`?page=${pagination.value.page}&pageSize=${pagination.value.rowsPerPage}&searchKeyword=${search.value}`,
body
)
.post(config.API.orgSearchPersonal(), body, { params: params.value })
.then((res) => {
totalList.value = Math.ceil(
res.data.result.total / pagination.value.rowsPerPage
);
total.value = res.data.result.total;
const data = res.data.result.data;
const list = data.map((e: ResponsePreson) => ({
personId: e.id,
idcard: e.citizenId,
prefix: e.prefix,
firstName: e.firstName,
lastName: e.lastName,
name: `${e.prefix ? e.prefix : ""}${e.firstName ? e.firstName : ""} ${
e.lastName ? e.lastName : ""
}`,
posNo: e.posNo ?? "-",
position: e.position ?? "-",
positionLevel: e.positionLevel ?? "-",
salary: e.salaries ?? "-",
organization: e.organization ?? "-",
phone: e.phone ?? "-",
email: e.email ?? "-",
rootDnaId: e.rootDnaId ?? "-",
}));
rows.value = list;
const result = res.data.result;
pagination.value.rowsNumber = result.total;
if (result.data.length > 0) {
rows.value = result.data.map((e: ResponsePreson) => ({
personId: e.id,
idcard: e.citizenId,
prefix: e.prefix,
firstName: e.firstName,
lastName: e.lastName,
name: `${e.prefix ? e.prefix : ""}${
e.firstName ? e.firstName : ""
} ${e.lastName ? e.lastName : ""}`,
posNo: e.posNo ?? "-",
position: e.position ?? "-",
positionLevel: e.positionLevel ?? "-",
salary: e.salaries ?? "-",
organization: e.organization ?? "-",
phone: e.phone ?? "-",
email: e.email ?? "-",
rootDnaId: e.rootDnaId ?? "-",
}));
} else {
rows.value = [];
}
})
.catch((err) => {
messageError($q, err);
rows.value = [];
})
.finally(() => {
hideLoader();
@ -267,31 +243,23 @@ function updatemodalPersonal(modal: boolean) {
modalPersonal.value = modal;
}
function updatePagination(newPagination: any) {
pagination.value.page = 1;
pagination.value.rowsPerPage = newPagination.rowsPerPage;
}
/**
* เชคขอมลจาก props
* เมอมอม
* เกบขอมลลง formData
*/
watch(props.data, async () => {
formData.prefix = props.data.prefix;
formData.firstname = props.data.firstname;
formData.lastname = props.data.lastname;
formData.position = props.data.position;
formData.phone = props.data.phone;
formData.email = props.data.email;
formData.qualification = props.data.qualification;
});
watch(
() => pagination.value.rowsPerPage,
() => props.data,
async () => {
await getSearch();
}
formData.prefix = props.data.prefix;
formData.firstname = props.data.firstname;
formData.lastname = props.data.lastname;
formData.position = props.data.position;
formData.phone = props.data.phone;
formData.email = props.data.email;
formData.qualification = props.data.qualification;
},
{ deep: true }
);
</script>
@ -343,7 +311,7 @@ watch(
</div>
<div class="col-12 q-pt-sm">
<d-table
<p-table
ref="table"
:columns="columnsRespondent"
:rows="rows"
@ -352,26 +320,11 @@ watch(
bordered
:paging="true"
dense
class="custom-header-table"
:visible-columns="visibleColumnsRespondent"
:rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination"
v-model:pagination="pagination"
@request="onRequest"
>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="getSearch"
></q-pagination>
</template>
<template v-slot:header="props">
<q-tr :props="props">
<q-th
@ -393,11 +346,7 @@ watch(
@click="returnDetail(props.row)"
>
<div v-if="col.name == 'no'">
{{
(pagination.page - 1) * pagination.rowsPerPage +
props.rowIndex +
1
}}
{{ props.rowIndex + 1 }}
</div>
<div v-else-if="col.name == 'info'">
<q-btn
@ -413,12 +362,12 @@ watch(
</div>
<div v-else>
{{ col.value }}
{{ col.value ?? "-" }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
</p-table>
</div>
</div>

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import config from "@/app.config";
@ -9,6 +9,7 @@ import { checkPermission } from "@/utils/permissions";
import { useCounterMixin } from "@/stores/mixin";
import { useDisciplineDirectorDataStore } from "@/modules/11_discipline/store/DirectorStore";
import { useDisciplineMainStore } from "@/modules/11_discipline/store/Main";
import { usePagination } from "@/composables/usePagination";
import type { DirectorRowsResponse } from "@/modules/11_discipline/interface/response/director";
@ -21,6 +22,7 @@ const mainStore = useDisciplineMainStore();
const route = useRoute();
const mixin = useCounterMixin();
const { messageError, showLoader, hideLoader, dialogRemove, success } = mixin;
const { pagination, params, onRequest } = usePagination("", getList);
const titleInvestigate = ref<string>("");
const personalId = ref<string>("");
@ -36,33 +38,23 @@ const dataPopUp = ref<DirectorRowsResponse>();
const filterKeyword = ref<string>("");
const filterRef = ref<HTMLInputElement | null>(null);
const total = ref<number>(0);
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
});
async function getList() {
showLoader();
await http
.get(
config.API.directorList(
pagination.value.page,
pagination.value.rowsPerPage,
filterKeyword.value.trim(),
mainStore.pathDirector(route.name as string)
)
config.API.directorListMain +
`${mainStore.pathDirector(route.name as string)}`,
{
params: {
...params.value,
keyword: filterKeyword.value.trim(),
},
}
)
.then((res) => {
const data = res.data.result.data;
totalList.value = Math.ceil(
res.data.result.total / pagination.value.rowsPerPage
);
total.value = res.data.result.total;
dataStore.fetchData(data);
const result = res.data.result;
pagination.value.rowsNumber = result.total;
dataStore.fetchData(result.data);
})
.catch((e) => {
messageError($q, e);
@ -77,38 +69,21 @@ async function getList() {
* @param id ไอดของขอม
*/
function clickDelete(id: string) {
dialogRemove($q, async () => deleteData(id), `ลบข้อมูล`);
}
/**
* ลบขอม
* @param id type
*/
async function deleteData(id: string) {
showLoader();
await http
.delete(config.API.directorbyId(id))
.then((res) => {
success($q, "ลบข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
await getList();
});
}
function resetFilter() {
filterKeyword.value = "";
if (filterRef.value) {
filterRef.value.focus();
getSearch();
}
}
function filterFn() {
getSearch();
dialogRemove($q, async () => {
showLoader();
await http
.delete(config.API.directorbyId(id))
.then(async () => {
await getList();
success($q, "ลบข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
});
});
}
function openDetail(data: DirectorRowsResponse, typeChange: string) {
@ -132,210 +107,188 @@ function onEdit(id: string, check: boolean) {
isEdit.value = check;
}
function updatePagination(newPagination: any) {
pagination.value.page = 1;
pagination.value.rowsPerPage = newPagination.rowsPerPage;
}
function getSearch() {
pagination.value.page = 1;
getList();
}
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/**
* งขอมลจำลองไปย store
*/
onMounted(() => {
getList();
// get store
});
</script>
<template>
<div class="toptitle text-dark col-12 row items-center">
รายการชอกรรมการ
</div>
<q-card flat bordered class="col-12 q-mt-sm q-pa-md">
<div class="row col-12 q-col-gutter-sm q-mb-sm">
<div>
<q-btn
v-if="checkPermission($route)?.attrIsCreate"
@click="$router.push(`/discipline/director/add`)"
flat
dense
round
color="primary"
icon="mdi-plus"
>
<q-tooltip>เพมรายชอกรรมการ</q-tooltip>
</q-btn>
<q-card flat bordered>
<div class="col-12 q-pa-md q-col-gutter-sm">
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-xs-12 col-sm-3 col-md-4 col-lg-2">
<div class="row items-center">
<q-btn
v-if="checkPermission($route)?.attrIsCreate"
@click="$router.push(`/discipline/director/add`)"
flat
dense
round
color="primary"
icon="mdi-plus"
>
<q-tooltip>เพมรายชอกรรมการ</q-tooltip>
</q-btn>
</div>
</div>
<q-space />
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
<div class="row q-col-gutter-sm items-center">
<div class="col-7">
<q-input
standout
dense
v-model="filterKeyword"
ref="filterRef"
outlined
placeholder="ค้นหา"
@keydown.enter.prevent="getSearch"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
</div>
<div class="col-5">
<q-select
v-model="dataStore.visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="dataStore.columns"
option-value="name"
/>
</div>
</div>
</div>
</div>
</div>
<q-space />
<q-input
class="col-xs-12 col-sm-3 col-md-2"
standout
dense
v-model="filterKeyword"
ref="filterRef"
outlined
placeholder="ค้นหา"
@keydown.enter.prevent="filterFn"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<q-select
v-model="dataStore.visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="dataStore.columns"
option-value="name"
style="min-width: 140px"
class="col-xs-12 col-sm-3 col-md-2"
/>
</div>
<div class="col-12">
<d-table
:columns="dataStore.columns"
:rows="dataStore.rows"
row-key="tb-list"
flat
bordered
:paging="true"
dense
:rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination"
:visible-columns="dataStore.visibleColumns"
>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="getList"
></q-pagination>
</template>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width />
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td auto-width>
<q-btn
v-if="checkPermission($route)?.attrIsGet"
dense
flat
round
color="info"
@click="onEdit(props.row.id, false)"
icon="mdi-eye"
>
<q-tooltip>รายละเอยด</q-tooltip>
</q-btn>
<q-btn
v-if="
checkPermission($route)?.attrIsUpdate &&
checkPermission($route)?.attrIsGet
"
dense
flat
round
color="edit"
@click="onEdit(props.row.id, true)"
icon="edit"
>
<q-tooltip>แกไขขอม</q-tooltip>
</q-btn>
<q-btn
v-if="checkPermission($route)?.attrIsDelete"
dense
flat
round
color="red"
@click="clickDelete(props.row.id)"
icon="mdi-delete"
>
<q-tooltip>ลบขอม</q-tooltip>
</q-btn>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div v-if="col.name == 'no'">
{{
(pagination.page - 1) * pagination.rowsPerPage +
props.rowIndex +
1
}}
</div>
<div
v-else-if="
col.name == 'totalInvestigate' &&
props.row.totalInvestigate > 0
"
:class="
checkPermission($route)?.attrIsGet
? 'text-blue cursor-pointer'
: ''
"
@click="
checkPermission($route)?.attrIsGet
? openDetail(props.row, 'investigate')
: ''
"
>
{{ props.row.totalInvestigate }}
</div>
<div
v-else-if="
col.name == 'totalDisciplinary' &&
props.row.totalDisciplinary > 0
"
:class="
checkPermission($route)?.attrIsGet
? 'text-blue cursor-pointer'
: ''
"
@click="
checkPermission($route)?.attrIsGet
? openDetail(props.row, 'disciplinary')
: ''
"
>
{{ props.row.totalDisciplinary }}
</div>
<div v-else>
{{ col.value ?? "-" }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
<div class="col-12">
<p-table
:columns="dataStore.columns"
:rows="dataStore.rows"
row-key="tb-list"
flat
bordered
:paging="true"
dense
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="dataStore.visibleColumns"
v-model:pagination="pagination"
@request="onRequest"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width />
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td auto-width>
<q-btn
v-if="checkPermission($route)?.attrIsGet"
dense
flat
round
color="info"
@click="onEdit(props.row.id, false)"
icon="mdi-eye"
>
<q-tooltip>รายละเอยด</q-tooltip>
</q-btn>
<q-btn
v-if="
checkPermission($route)?.attrIsUpdate &&
checkPermission($route)?.attrIsGet
"
dense
flat
round
color="edit"
@click="onEdit(props.row.id, true)"
icon="edit"
>
<q-tooltip>แกไขขอม</q-tooltip>
</q-btn>
<q-btn
v-if="checkPermission($route)?.attrIsDelete"
dense
flat
round
color="red"
@click="clickDelete(props.row.id)"
icon="mdi-delete"
>
<q-tooltip>ลบขอม</q-tooltip>
</q-btn>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div
v-else-if="
col.name == 'totalInvestigate' &&
props.row.totalInvestigate > 0
"
:class="
checkPermission($route)?.attrIsGet
? 'text-blue cursor-pointer'
: ''
"
@click="
checkPermission($route)?.attrIsGet
? openDetail(props.row, 'investigate')
: ''
"
>
{{ props.row.totalInvestigate }}
</div>
<div
v-else-if="
col.name == 'totalDisciplinary' &&
props.row.totalDisciplinary > 0
"
:class="
checkPermission($route)?.attrIsGet
? 'text-blue cursor-pointer'
: ''
"
@click="
checkPermission($route)?.attrIsGet
? openDetail(props.row, 'disciplinary')
: ''
"
>
{{ props.row.totalDisciplinary }}
</div>
<div v-else>
{{ col.value ?? "-" }}
</div>
</q-td>
</q-tr>
</template>
</p-table>
</div>
</div>
</q-card>

View file

@ -14,7 +14,7 @@ export const useDisciplineDirectorDataStore = defineStore(
const rows = ref<DirectorRowsResponse[]>([]);
const visibleColumns = ref<string[]>([
"no",
"fullName",
"firstName",
"position",
"email",
"phone",
@ -34,7 +34,7 @@ export const useDisciplineDirectorDataStore = defineStore(
style: "font-size: 14px",
},
{
name: "fullName",
name: "firstName",
align: "left",
label: "ชื่อ-นามสกุล",
sortable: true,