fix(discipline-appealcomplain):sort

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-10-09 14:10:40 +07:00
parent dc3989acae
commit 629efe5abf
4 changed files with 286 additions and 355 deletions

View file

@ -96,15 +96,7 @@ export default {
deleteFileResult: (id: string, docId: string) => deleteFileResult: (id: string, docId: string) =>
`${disciplineMain}/result/file/${id}/${docId}`, `${disciplineMain}/result/file/${id}/${docId}`,
appealMainList: ( appealMainList: `${appeal}/admin?`,
status: string,
type: string,
year: number,
page: number,
pageSize: number,
keyword: string
) =>
`${appeal}/admin?status=${status}&type=${type}&year=${year}&page=${page}&pageSize=${pageSize}&keyword=${keyword}`,
appealAdd: () => `${appeal}`, appealAdd: () => `${appeal}`,
appealByID: (id: string) => `${appeal}/${id}`, appealByID: (id: string) => `${appeal}/${id}`,
appealByIDGet: (id: string) => `${appeal}/admin/${id}`, appealByIDGet: (id: string) => `${appeal}/admin/${id}`,

View file

@ -94,7 +94,7 @@ function filterFn() {
function filterOptionFn(val: string, update: Function) { function filterOptionFn(val: string, update: Function) {
update(() => { update(() => {
option.value = store.statusOptions.filter( option.value = store.statusOptions.filter(
(e: any) => e.name.search(val) !== -1 (e: DataOption) => e.name.search(val) !== -1
); );
}); });
} }

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch, reactive } from "vue"; import { ref, onMounted, reactive } from "vue";
import http from "@/plugins/http"; import http from "@/plugins/http";
import config from "@/app.config"; import config from "@/app.config";
@ -9,6 +9,7 @@ import { useCounterMixin } from "@/stores/mixin";
import { useAppealComplainStore } from "@/modules/11_discipline/store/AppealComplainStore"; import { useAppealComplainStore } from "@/modules/11_discipline/store/AppealComplainStore";
import { checkPermission } from "@/utils/permissions"; import { checkPermission } from "@/utils/permissions";
import { calculateFiscalYear } from "@/utils/function"; import { calculateFiscalYear } from "@/utils/function";
import { usePagination } from "@/composables/usePagination";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import type { RowList } from "@/modules/11_discipline/interface/response/appealComplain"; import type { RowList } from "@/modules/11_discipline/interface/response/appealComplain";
@ -20,35 +21,26 @@ import { useDisciplineMainStore } from "@/modules/11_discipline/store/Main";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { showLoader, messageError, hideLoader, dialogConfirm } = mixin; const { showLoader, messageError, hideLoader } = mixin;
const mainStore = useDisciplineMainStore(); const mainStore = useDisciplineMainStore();
const modalStatusEdit = ref<boolean>(false);
/** stoer */
const dataStore = useAppealComplainStore(); const dataStore = useAppealComplainStore();
const { pagination, params, onRequest } = usePagination("", getData);
const { fetchAppealComplain } = dataStore; const { fetchAppealComplain } = dataStore;
/** store */
const modalStatusEdit = ref<boolean>(false);
const type = ref<DataOption[]>([ const type = ref<DataOption[]>([
{ id: "ALL", name: "ทั้งหมด" }, { id: "ALL", name: "ทั้งหมด" },
...dataStore.typeOptions, ...dataStore.typeOptions,
]); ]);
const filterKeyword = ref<string>(""); const filterKeyword = ref<string>("");
const dataRow = ref<RowList[]>([]); const dataRow = ref<RowList[]>([]);
const formData = reactive<any>({ const formData = reactive<any>({
type: "ALL", type: "ALL",
status: "NEW", status: "NEW",
year: calculateFiscalYear(new Date()).toString(), year: calculateFiscalYear(new Date()).toString(),
}); });
const total = ref<number>(0);
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
});
const visibleColumns = ref<string[]>([ const visibleColumns = ref<string[]>([
"no", "no",
"profileType", "profileType",
@ -63,8 +55,6 @@ const visibleColumns = ref<string[]>([
"lastUpdatedAt", "lastUpdatedAt",
"status", "status",
]); ]);
//
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "no", name: "no",
@ -79,7 +69,7 @@ const columns = ref<QTableProps["columns"]>([
name: "profileType", name: "profileType",
align: "left", align: "left",
label: "ประเภทตำแหน่ง", label: "ประเภทตำแหน่ง",
sortable: true, sortable: false,
field: "profileType", field: "profileType",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
@ -88,7 +78,7 @@ const columns = ref<QTableProps["columns"]>([
name: "type", name: "type",
align: "left", align: "left",
label: "ประเภท", label: "ประเภท",
sortable: true, sortable: false,
field: "type", field: "type",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px", style: "font-size: 14px",
@ -110,8 +100,6 @@ const columns = ref<QTableProps["columns"]>([
field: "fullname", field: "fullname",
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: "citizenId", name: "citizenId",
@ -121,8 +109,6 @@ const columns = ref<QTableProps["columns"]>([
field: "citizenId", field: "citizenId",
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: "year", name: "year",
@ -132,8 +118,6 @@ const columns = ref<QTableProps["columns"]>([
field: "year", field: "year",
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: "caseType", name: "caseType",
@ -143,8 +127,6 @@ const columns = ref<QTableProps["columns"]>([
field: "caseType", field: "caseType",
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: "caseNumber", name: "caseNumber",
@ -154,8 +136,6 @@ const columns = ref<QTableProps["columns"]>([
field: "caseNumber", field: "caseNumber",
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: "description", name: "description",
@ -165,8 +145,6 @@ const columns = ref<QTableProps["columns"]>([
field: "description", field: "description",
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: "lastUpdatedAt", name: "lastUpdatedAt",
@ -176,8 +154,6 @@ const columns = ref<QTableProps["columns"]>([
field: "lastUpdatedAt", field: "lastUpdatedAt",
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: "status", name: "status",
@ -207,11 +183,6 @@ function editPage(id: string) {
router.push(`/discipline-appealcomplain/${id}`); router.push(`/discipline-appealcomplain/${id}`);
} }
/** ดึงข้อมูลเมื่อ กด enter */
function filterFn() {
getSearch();
}
/** ปิด pop up */ /** ปิด pop up */
function close() { function close() {
modalStatusEdit.value = false; modalStatusEdit.value = false;
@ -221,22 +192,19 @@ function close() {
async function getData() { async function getData() {
showLoader(); showLoader();
await http await http
.get( .get(config.API.appealMainList, {
config.API.appealMainList( params: {
formData.status, ...params.value,
formData.type, status: formData.status,
formData.year, type: formData.type,
pagination.value.page, year: formData.year,
pagination.value.rowsPerPage, keyword: filterKeyword.value,
filterKeyword.value },
) })
) .then(async (res) => {
.then((res) => { const result = res.data.result;
totalList.value = Math.ceil( pagination.value.rowsNumber = result.total;
res.data.result.total / pagination.value.rowsPerPage await fetchAppealComplain(result.data);
);
total.value = res.data.result.total;
fetchAppealComplain(res.data.result.data);
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -257,13 +225,8 @@ function yearAll() {
getSearch(); getSearch();
} }
/** ฟังชั่น เคลียฟิลเตอร์ */ const option = ref<DataOption[]>(dataStore.statusOptions);
function resetFilter() { const optionType = ref<DataOption[]>(type.value);
filterKeyword.value = "";
getSearch();
}
const option = ref<any[]>(dataStore.statusOptions);
const optionType = ref<any[]>(type.value);
/** /**
* function นหาขอมลใน option * function นหาขอมลใน option
* @param val คำคนหา * @param val คำคนหา
@ -272,7 +235,7 @@ const optionType = ref<any[]>(type.value);
function filterOptionFn(val: string, update: Function) { function filterOptionFn(val: string, update: Function) {
update(() => { update(() => {
option.value = dataStore.statusOptions.filter( option.value = dataStore.statusOptions.filter(
(e: any) => e.name.search(val) !== -1 (e: DataOption) => e.name.search(val) !== -1
); );
}); });
} }
@ -284,27 +247,17 @@ function filterOptionFn(val: string, update: Function) {
*/ */
function filterOptionFnType(val: string, update: Function) { function filterOptionFnType(val: string, update: Function) {
update(() => { update(() => {
optionType.value = type.value.filter((e: any) => e.name.search(val) !== -1); optionType.value = type.value.filter(
(e: DataOption) => e.name.search(val) !== -1
);
}); });
} }
function updatePagination(newPagination: any) {
pagination.value.page = 1;
pagination.value.rowsPerPage = newPagination.rowsPerPage;
}
function getSearch() { function getSearch() {
pagination.value.page = 1; pagination.value.page = 1;
getData(); getData();
} }
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/** เรียกใช้งาน ฟังชั่น ตอนเริ่มโหลดหน้า */ /** เรียกใช้งาน ฟังชั่น ตอนเริ่มโหลดหน้า */
onMounted(async () => { onMounted(async () => {
getData(); getData();
@ -317,283 +270,269 @@ onMounted(async () => {
<div class="toptitle text-dark col-12 row items-center"> <div class="toptitle text-dark col-12 row items-center">
รายการอทธรณ/องทกข รายการอทธรณ/องทกข
</div> </div>
<q-card flat bordered class="col-12 q-mt-sm q-pa-md">
<div class="row q-mb-sm q-col-gutter-sm">
<div>
<q-btn
v-if="checkPermission($route)?.attrIsCreate"
id="addComplaints"
for="addComplaints"
dense
flat
round
color="primary"
icon="mdi-plus"
@click="redirectToPageadd()"
><q-tooltip>เพมการอทธรณ/องทกข</q-tooltip></q-btn
>
</div>
<q-space />
<q-input
for="#search"
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 <q-card flat bordered>
id="visibleColumns" <div class="col-12 q-pa-md q-col-gutter-sm">
for="visibleColumns" <div class="row q-col-gutter-sm">
v-model="dataStore.visibleColumns" <div>
multiple <q-btn
outlined v-if="checkPermission($route)?.attrIsCreate"
dense id="addComplaints"
options-dense for="addComplaints"
:display-value="$q.lang.table.columns" dense
emit-value flat
map-options round
:options="dataStore.columns" color="primary"
option-value="name" icon="mdi-plus"
style="min-width: 140px" @click="redirectToPageadd()"
class="col-xs-12 col-sm-3 col-md-2" ><q-tooltip>เพมการอทธรณ/องทกข</q-tooltip></q-btn
/> >
</div>
<div class="col-12 row q-mb-sm">
<q-card bordered class="col-12 filter-card q-pa-sm">
<div class="row col-12 q-col-gutter-sm">
<div class="col-2">
<datepicker
v-model="formData.year"
class="col-2"
:locale="'th'"
autoApply
year-picker
:enableTimePicker="false"
@update:model-value="dataUpdate"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
outlined
:model-value="
formData.year === 0
? 'ทั้งหมด'
: Number(formData.year) + 543
"
:label="`${'ปีงบประมาณ'}`"
>
<template v-if="formData.year" v-slot:append>
<q-icon
name="cancel"
@click.stop.prevent="yearAll"
class="cursor-pointer"
/>
</template>
<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-2">
<q-select
v-model="formData.type"
label="ประเภท"
dense
outlined
emit-value
map-options
hide-selected
fill-input
option-label="name"
option-value="id"
:options="optionType"
@update:model-value="dataUpdate"
use-input
@filter="filterOptionFnType"
>
<template v-if="formData.type !== 'ALL'" v-slot:append>
<q-icon
name="cancel"
@click.stop.prevent="
(optionType = type), (formData.type = 'ALL'), dataUpdate()
"
class="cursor-pointer"
/>
</template>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
ไมอม
</q-item-section>
</q-item>
</template>
</q-select>
</div>
<div class="col-3">
<q-select
v-model="formData.status"
label="สถานะ"
dense
outlined
emit-value
hide-selected
fill-input
map-options
option-label="name"
option-value="id"
:options="option"
@update:model-value="dataUpdate"
use-input
@filter="filterOptionFn"
>
<template v-if="formData.status !== 'ALL'" v-slot:append>
<q-icon
name="cancel"
@click.stop.prevent="
(option = dataStore.statusOptions),
(formData.status = 'ALL'),
dataUpdate()
"
class="cursor-pointer"
/>
</template>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
ไมอม
</q-item-section>
</q-item>
</template>
</q-select>
</div>
</div> </div>
</q-card> <q-space />
</div> <q-input
for="#search"
class="col-xs-12 col-sm-3 col-md-2"
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 class="col-12"> <q-select
<d-table id="visibleColumns"
ref="table" for="visibleColumns"
:columns="dataStore.columns" v-model="dataStore.visibleColumns"
:rows="dataStore.rows" multiple
row-key="id" outlined
flat dense
bordered options-dense
:paging="true" :display-value="$q.lang.table.columns"
dense emit-value
class="custom-header-table" map-options
:visible-columns="dataStore.visibleColumns" :options="dataStore.columns"
:rows-per-page-options="[10, 25, 50, 100]" option-value="name"
@update:pagination="updatePagination" style="min-width: 140px"
> class="col-xs-12 col-sm-3 col-md-2"
<template v-slot:pagination="scope"> />
งหมด {{ total }} รายการ </div>
<q-pagination <div class="col-12 row">
v-model="pagination.page" <q-card bordered class="col-12 filter-card q-pa-sm">
active-color="primary" <div class="row col-12 q-col-gutter-sm">
color="dark" <div class="col-xs-12 col-sm-4 col-md-4 col-lg-2">
:max="Number(totalList)" <datepicker
size="sm" v-model="formData.year"
boundary-links class="col-2"
direction-links :locale="'th'"
:max-pages="5" autoApply
@update:model-value="getData" year-picker
></q-pagination> :enableTimePicker="false"
</template> @update:model-value="dataUpdate"
<template v-slot:header="props"> >
<q-tr :props="props"> <template #year="{ year }">{{ year + 543 }}</template>
<q-th auto-width></q-th> <template #year-overlay-value="{ value }">{{
<q-th parseInt(value + 543)
v-for="col in props.cols" }}</template>
:key="col.name" <template #trigger>
:props="props" <q-input
style="color: #000000; font-weight: 500" dense
> outlined
<span class="text-weight-medium">{{ col.label }}</span> :model-value="
</q-th> formData.year === 0
</q-tr> ? 'ทั้งหมด'
</template> : Number(formData.year) + 543
<template v-slot:body="props"> "
<q-tr :props="props"> :label="`${'ปีงบประมาณ'}`"
<q-td auto-width> >
<q-btn <template v-if="formData.year" v-slot:append>
v-if="checkPermission($route)?.attrIsGet" <q-icon
id="addComplaints" name="cancel"
for="addComplaints" @click.stop.prevent="yearAll"
class="cursor-pointer"
/>
</template>
<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-xs-12 col-sm-4 col-md-4 col-lg-2">
<q-select
v-model="formData.type"
label="ประเภท"
dense dense
flat outlined
round emit-value
color="info" map-options
icon="mdi-eye" hide-selected
@click="redirectToPageDetail(props.row.id)" fill-input
><q-tooltip>รายละเอยดการอทธรณ/องทกข</q-tooltip></q-btn option-label="name"
option-value="id"
:options="optionType"
@update:model-value="dataUpdate"
use-input
@filter="filterOptionFnType"
> >
<q-btn <template v-if="formData.type !== 'ALL'" v-slot:append>
v-if=" <q-icon
checkPermission($route)?.attrIsUpdate && name="cancel"
checkPermission($route)?.attrIsGet @click.stop.prevent="
" (optionType = type), (formData.type = 'ALL'), dataUpdate()
id="addComplaints" "
for="addComplaints" class="cursor-pointer"
flat />
</template>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
ไมอม
</q-item-section>
</q-item>
</template>
</q-select>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-2">
<q-select
v-model="formData.status"
label="สถานะ"
dense dense
round outlined
color="edit" emit-value
icon="edit" hide-selected
@click="editPage(props.row.id)" fill-input
><q-tooltip>แกไขการอทธรณ/องทกข</q-tooltip></q-btn map-options
option-label="name"
option-value="id"
:options="option"
@update:model-value="dataUpdate"
use-input
@filter="filterOptionFn"
> >
</q-td> <template v-if="formData.status !== 'ALL'" v-slot:append>
<q-td v-for="col in props.cols" :key="col.name" :props="props"> <q-icon
<div v-if="col.name == 'no'"> name="cancel"
{{ @click.stop.prevent="
(pagination.page - 1) * pagination.rowsPerPage + (option = dataStore.statusOptions),
props.rowIndex + (formData.status = 'ALL'),
1 dataUpdate()
}} "
</div> class="cursor-pointer"
<div v-else-if="col.name === 'title'" class="table_ellipsis"> />
{{ props.row.title }} </template>
</div> <template v-slot:no-option>
<div v-else-if="col.name === 'profileType'"> <q-item>
{{ <q-item-section class="text-grey">
props.row.profileType ไมอม
? mainStore.convertType(props.row.profileType) </q-item-section>
: "-" </q-item>
}} </template>
</div> </q-select>
<div </div>
v-else-if="col.name === 'description'" </div>
class="table_ellipsis" </q-card>
</div>
<div class="col-12">
<p-table
ref="table"
:columns="dataStore.columns"
:rows="dataStore.rows"
row-key="id"
flat
bordered
:paging="true"
dense
class="custom-header-table"
:visible-columns="dataStore.visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]"
v-model:pagination="pagination"
@request="onRequest"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width></q-th>
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
style="color: #000000; font-weight: 500"
> >
{{ props.row.description ? props.row.description : "-" }} <span class="text-weight-medium">{{ col.label }}</span>
</div> </q-th>
<div v-else> </q-tr>
{{ col.value ?? "-" }} </template>
</div> <template v-slot:body="props">
</q-td> <q-tr :props="props">
</q-tr> <q-td auto-width>
</template> <q-btn
</d-table> v-if="checkPermission($route)?.attrIsGet"
id="addComplaints"
for="addComplaints"
dense
flat
round
color="info"
icon="mdi-eye"
@click="redirectToPageDetail(props.row.id)"
><q-tooltip>รายละเอยดการอทธรณ/องทกข</q-tooltip></q-btn
>
<q-btn
v-if="
checkPermission($route)?.attrIsUpdate &&
checkPermission($route)?.attrIsGet
"
id="addComplaints"
for="addComplaints"
flat
dense
round
color="edit"
icon="edit"
@click="editPage(props.row.id)"
><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 === 'title'" class="table_ellipsis">
{{ props.row.title }}
</div>
<div v-else-if="col.name === 'profileType'">
{{
props.row.profileType
? mainStore.convertType(props.row.profileType)
: "-"
}}
</div>
<div
v-else-if="col.name === 'description'"
class="table_ellipsis"
>
{{ props.row.description ? props.row.description : "-" }}
</div>
<div v-else>
{{ col.value ?? "-" }}
</div>
</q-td>
</q-tr>
</template>
</p-table>
</div>
</div> </div>
</q-card> </q-card>

View file

@ -63,7 +63,7 @@ export const useAppealComplainStore = defineStore("AppealComplainStore", () => {
* *
* @param data API * @param data API
*/ */
function fetchAppealComplain(data: MainList[]) { async function fetchAppealComplain(data: MainList[]) {
let dataList: RowList[] = data.map((e: MainList) => ({ let dataList: RowList[] = data.map((e: MainList) => ({
id: e.id, id: e.id,
profileId: e.profileId, profileId: e.profileId,