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) =>
`${disciplineMain}/result/file/${id}/${docId}`,
appealMainList: (
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}`,
appealMainList: `${appeal}/admin?`,
appealAdd: () => `${appeal}`,
appealByID: (id: string) => `${appeal}/${id}`,
appealByIDGet: (id: string) => `${appeal}/admin/${id}`,

View file

@ -94,7 +94,7 @@ function filterFn() {
function filterOptionFn(val: string, update: Function) {
update(() => {
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">
import { ref, onMounted, watch, reactive } from "vue";
import { ref, onMounted, reactive } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
@ -9,6 +9,7 @@ import { useCounterMixin } from "@/stores/mixin";
import { useAppealComplainStore } from "@/modules/11_discipline/store/AppealComplainStore";
import { checkPermission } from "@/utils/permissions";
import { calculateFiscalYear } from "@/utils/function";
import { usePagination } from "@/composables/usePagination";
import type { QTableProps } from "quasar";
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 router = useRouter();
const mixin = useCounterMixin();
const { showLoader, messageError, hideLoader, dialogConfirm } = mixin;
const { showLoader, messageError, hideLoader } = mixin;
const mainStore = useDisciplineMainStore();
const modalStatusEdit = ref<boolean>(false);
/** stoer */
const dataStore = useAppealComplainStore();
const { pagination, params, onRequest } = usePagination("", getData);
const { fetchAppealComplain } = dataStore;
/** store */
const modalStatusEdit = ref<boolean>(false);
const type = ref<DataOption[]>([
{ id: "ALL", name: "ทั้งหมด" },
...dataStore.typeOptions,
]);
const filterKeyword = ref<string>("");
const dataRow = ref<RowList[]>([]);
const formData = reactive<any>({
type: "ALL",
status: "NEW",
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[]>([
"no",
"profileType",
@ -63,8 +55,6 @@ const visibleColumns = ref<string[]>([
"lastUpdatedAt",
"status",
]);
//
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -79,7 +69,7 @@ const columns = ref<QTableProps["columns"]>([
name: "profileType",
align: "left",
label: "ประเภทตำแหน่ง",
sortable: true,
sortable: false,
field: "profileType",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
@ -88,7 +78,7 @@ const columns = ref<QTableProps["columns"]>([
name: "type",
align: "left",
label: "ประเภท",
sortable: true,
sortable: false,
field: "type",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
@ -110,8 +100,6 @@ const columns = ref<QTableProps["columns"]>([
field: "fullname",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "citizenId",
@ -121,8 +109,6 @@ const columns = ref<QTableProps["columns"]>([
field: "citizenId",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "year",
@ -132,8 +118,6 @@ const columns = ref<QTableProps["columns"]>([
field: "year",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "caseType",
@ -143,8 +127,6 @@ const columns = ref<QTableProps["columns"]>([
field: "caseType",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "caseNumber",
@ -154,8 +136,6 @@ const columns = ref<QTableProps["columns"]>([
field: "caseNumber",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "description",
@ -165,8 +145,6 @@ const columns = ref<QTableProps["columns"]>([
field: "description",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "lastUpdatedAt",
@ -176,8 +154,6 @@ const columns = ref<QTableProps["columns"]>([
field: "lastUpdatedAt",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "status",
@ -207,11 +183,6 @@ function editPage(id: string) {
router.push(`/discipline-appealcomplain/${id}`);
}
/** ดึงข้อมูลเมื่อ กด enter */
function filterFn() {
getSearch();
}
/** ปิด pop up */
function close() {
modalStatusEdit.value = false;
@ -221,22 +192,19 @@ function close() {
async function getData() {
showLoader();
await http
.get(
config.API.appealMainList(
formData.status,
formData.type,
formData.year,
pagination.value.page,
pagination.value.rowsPerPage,
filterKeyword.value
)
)
.then((res) => {
totalList.value = Math.ceil(
res.data.result.total / pagination.value.rowsPerPage
);
total.value = res.data.result.total;
fetchAppealComplain(res.data.result.data);
.get(config.API.appealMainList, {
params: {
...params.value,
status: formData.status,
type: formData.type,
year: formData.year,
keyword: filterKeyword.value,
},
})
.then(async (res) => {
const result = res.data.result;
pagination.value.rowsNumber = result.total;
await fetchAppealComplain(result.data);
})
.catch((e) => {
messageError($q, e);
@ -257,13 +225,8 @@ function yearAll() {
getSearch();
}
/** ฟังชั่น เคลียฟิลเตอร์ */
function resetFilter() {
filterKeyword.value = "";
getSearch();
}
const option = ref<any[]>(dataStore.statusOptions);
const optionType = ref<any[]>(type.value);
const option = ref<DataOption[]>(dataStore.statusOptions);
const optionType = ref<DataOption[]>(type.value);
/**
* function นหาขอมลใน option
* @param val คำคนหา
@ -272,7 +235,7 @@ const optionType = ref<any[]>(type.value);
function filterOptionFn(val: string, update: Function) {
update(() => {
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) {
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() {
pagination.value.page = 1;
getData();
}
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/** เรียกใช้งาน ฟังชั่น ตอนเริ่มโหลดหน้า */
onMounted(async () => {
getData();
@ -317,283 +270,269 @@ onMounted(async () => {
<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 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
id="visibleColumns"
for="visibleColumns"
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 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>
<q-card flat bordered>
<div class="col-12 q-pa-md q-col-gutter-sm">
<div class="row 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-card>
</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="getSearch"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<div class="col-12">
<d-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]"
@update:pagination="updatePagination"
>
<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="getData"
></q-pagination>
</template>
<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"
>
<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"
id="addComplaints"
for="addComplaints"
<q-select
id="visibleColumns"
for="visibleColumns"
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 row">
<q-card bordered class="col-12 filter-card q-pa-sm">
<div class="row col-12 q-col-gutter-sm">
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-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-xs-12 col-sm-4 col-md-4 col-lg-2">
<q-select
v-model="formData.type"
label="ประเภท"
dense
flat
round
color="info"
icon="mdi-eye"
@click="redirectToPageDetail(props.row.id)"
><q-tooltip>รายละเอยดการอทธรณ/องทกข</q-tooltip></q-btn
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"
>
<q-btn
v-if="
checkPermission($route)?.attrIsUpdate &&
checkPermission($route)?.attrIsGet
"
id="addComplaints"
for="addComplaints"
flat
<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-xs-12 col-sm-4 col-md-4 col-lg-2">
<q-select
v-model="formData.status"
label="สถานะ"
dense
round
color="edit"
icon="edit"
@click="editPage(props.row.id)"
><q-tooltip>แกไขการอทธรณ/องทกข</q-tooltip></q-btn
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"
>
</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 === '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"
<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>
</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 : "-" }}
</div>
<div v-else>
{{ col.value ?? "-" }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
<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"
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>
</q-card>

View file

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