Merge branch 'nice_dev' into develop

# Conflicts:
#	src/modules/13_salary/components/SalaryEmployeeLists/TabMain.vue
#	src/modules/13_salary/views/salaryEmployeeLists.vue
This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-03-14 13:27:59 +07:00
commit 95e4abc6e8
12 changed files with 1157 additions and 331 deletions

View file

@ -0,0 +1,492 @@
<script setup lang="ts">
import { ref, onMounted, reactive, computed } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import genReportXLSX from "@/plugins/genreportxlsx";
/** importType*/
import type { DataOption } from "@/modules/13_salary/interface/index/Main";
import type { DataFilter } from "@/modules/13_salary/interface/index/SalaryList";
import type {
DataPeriodLatest,
DataPeriod,
} from "@/modules/13_salary/interface/response/SalaryList";
/** importComponents*/
import TableTabType1 from "@/modules/13_salary/components/SalaryEmployeeLists/TableTypePending.vue";
import TableTabType2 from "@/modules/13_salary/components/SalaryEmployeeLists/TableTypeOther.vue";
import DialogInfoCriteria from "@/modules/13_salary/components/SalaryEmployeeLists/DialogInfoCriteria.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryEmployeeListSDataStore } from "@/modules/13_salary/store/SalaryEmployeeListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryEmployeeListSDataStore();
const { messageError, showLoader, hideLoader } = useCounterMixin();
/** props*/
const props = defineProps({
periodLatest: { type: Object as () => DataPeriodLatest, require: true },
});
const total = ref<number>();
const splitterModel = ref<number>(13);
const rows = ref<DataPeriod[]>([]);
/** itemsTab กลุ่ม*/
const itemsTabGroup = ref([
{
lable: "กลุ่ม 1",
name: "group1",
},
{
lable: "กลุ่ม 2",
name: "group2",
},
]);
/** itemsTab ขั้น*/
const itemsTabType = computed(() => {
return store.roundMainCode === "OCT"
? [
{
lable: "รายชื่อคนครอง",
name: "tab1",
type: "PENDING",
},
{
lable: "รายชื่อผู้เกษียณอายุราชการ",
name: "tab5",
type: "RETIRE",
},
{
lable: "1 ขั้น",
name: "tab2",
type: "FULL",
},
{
lable: "0.5 ขั้น",
name: "tab3",
type: "HAFT",
},
{
lable: "1.5 ขั้น",
name: "tab4",
type: "FULLHAFT",
},
{
lable: "ไม่ได้เลื่อน",
name: "tab4",
type: "NONE",
},
]
: [
{
lable: "รายชื่อคนครอง",
name: "tab1",
type: "PENDING",
},
{
lable: "1 ขั้น",
name: "tab2",
type: "FULL",
},
{
lable: "0.5 ขั้น",
name: "tab3",
type: "HAFT",
},
{
lable: "ไม่ได้เลื่อน",
name: "tab4",
type: "NONE",
},
];
});
/** itemsCard*/
const itemsCard = ref([
{
lable: "จำนวนคนทั้งหมด",
name: "group1",
color: "secondary",
total: 0,
},
{
lable: "15% ของจำนวนคน",
name: "group2",
color: "light-blue-4",
total: 0,
},
{
lable: "เลือกไปแล้ว",
name: "group2",
color: "primary",
total: 0,
},
{
lable: "คงเหลือโควตา",
name: "group2",
color: "indigo-6",
total: 0,
},
{
lable: "สำรอง",
name: "group2",
color: "red-6",
total: 0,
},
{
lable: "จำนวนเงินคนครองปัจจุบัน",
name: "group1",
color: "secondary",
total: 0,
},
{
lable: "วงเงิน 6%",
name: "group2",
color: "light-blue-4",
total: 0,
},
{
lable: "ยอดเงินที่ใช้ไป",
name: "group2",
color: "primary",
total: 0,
},
{
lable: "วงเงิน 6%-ยอดเงินที่ใช้ไป",
name: "group2",
color: "indigo-6",
total: 0,
},
{
lable: "ใช้ไปเท่าไหร่",
name: "group2",
color: "blue-6",
total: 0,
},
{
lable: "เหลือเท่าไหร่",
name: "group2",
color: "green-6",
total: 0,
},
{
lable: "สำรอง",
name: "group2",
color: "red-6",
total: 0,
},
]);
/** ข้อมูลค้นหารายชื่อคยขึ้นเงินเดือน*/
const formFilter = reactive<DataFilter>({
page: 1,
pageSize: 10,
keyword: "",
type: store.tabType,
});
const maxPage = ref<number>(1);
/**
* function เรยกขอมลจำนวนโควต
* @param id กล
*/
function fetchDataQuota(id: string) {
// showLoader();
http
.get(config.API.salaryListPeriodQuota(id))
.then((res) => {
const data = res.data.result;
store.remaining = data.remaining;
itemsCard.value[0].total = data.total;
itemsCard.value[1].total = data.fifteenPercent;
itemsCard.value[2].total = data.chosen;
itemsCard.value[3].total = data.remaining;
itemsCard.value[4].total = data.totalBackup;
itemsCard.value[5].total = data.currentAmount;
itemsCard.value[6].total = data.sixPercentAmount;
itemsCard.value[7].total = data.spentAmount;
itemsCard.value[8].total = data.sixPercentSpentAmount;
itemsCard.value[9].total = data.useAmount;
itemsCard.value[10].total = data.remainingAmount;
itemsCard.value[11].total = data.totalBackup;
})
.catch((err) => {
messageError($q, err);
});
// .finally(() => {
// hideLoader();
// });
}
/**
* function เรยกขอมลรายช
* @param id กล
*/
function fetchDataPeriod(id: string) {
rows.value = [];
const formData = {
page: formFilter.page.toString(),
pageSize: formFilter.pageSize.toString(),
keyword: formFilter.keyword,
type: store.tabType === "RETIRE" ? "" : store.tabType,
isRetire: store.tabType === "RETIRE" ? true : null,
};
http
.put(config.API.salaryListPeriodORG(id), formData)
.then((res) => {
rows.value = res.data.result.data;
total.value = res.data.result.total;
maxPage.value = Math.ceil(res.data.result.total / formFilter.pageSize);
})
.catch((err) => {
messageError($q, err);
});
}
/**function เปลี่ยนกลุ่ม*/
function changeTabGroup() {
formFilter.page = 1;
formFilter.pageSize = 10;
formFilter.keyword = "";
store.tabType = "PENDING";
props.periodLatest &&
store.fetchPeriodLatest(props?.periodLatest, store.tabGroup);
store.groupId && fetchDataQuota(store.groupId);
store.groupId && fetchDataPeriod(store.groupId);
splitterModel.value = store.roundMainCode === "APR" ? 13 : 16;
}
/**function เปลี่ยนขั้น*/
function changeTabType() {
formFilter.page = 1;
formFilter.pageSize = 10;
formFilter.keyword = "";
store.groupId && fetchDataPeriod(store.groupId);
}
/** function เรียกข้อมูลรายชื่ออีกครั้ง*/
function fetchDataPeriodNew() {
store.groupId && fetchDataPeriod(store.groupId);
store.groupId && fetchDataQuota(store.groupId);
}
function onClickDownload(data: DataOption) {
console.log(data);
// showLoader();
// http
// .get(config.API.salaryReportByid(salaryId.value))
// .then((res) => {
// const dataList = res.data.result;
// genReportXLSX(dataList, "");
// })
// .catch((e) => {
// messageError($q, e);
// })
// .finally(() => {
// hideLoader();
// });
}
const modalDialogInfoCriteria = ref<boolean>(false);
onMounted(async () => {
await fetchDataQuota(store.groupId);
await fetchDataPeriod(store.groupId);
splitterModel.value = store.roundMainCode === "APR" ? 13 : 16;
});
</script>
<template>
<!-- Tab กล -->
<!-- <q-tabs
v-model="store.tabGroup"
dense
class="text-grey"
active-color="primary"
active-class="bg-teal-1"
indicator-color="primary"
align="left"
>
<div
v-for="(item, index) in itemsTabGroup"
:key="index"
@click="changeTabGroup"
>
<q-tab :name="item.name" :label="item.lable" />
</div>
<q-space />
<q-btn
dense
flat
icon="info"
class="q-mr-sm"
label="หลักเกณฑ์การพิจารณาเลื่อนขั้นเงินข้าราชการ"
@click="() => (modalDialogInfoCriteria = true)"
/>
</q-tabs> -->
<!-- <q-separator /> -->
<q-tab-panels v-model="store.tabGroup" animated class="bg-grey-1">
<q-tab-panel
style="padding: 0px"
v-for="(item, index) in itemsTabGroup"
:key="index"
:name="item.name"
>
<!-- Card โควต -->
<div class="row col-12 q-pa-md">
<div
:class="`row col-12 ${
store.roundMainCode === 'APR' ? `q-col-gutter-md` : `q-gutter-md`
} items-start`"
>
<div
v-for="(item, index) in store.roundMainCode === 'APR'
? itemsCard.slice(0, 5)
: store.roundMainCode === 'OCT'
? itemsCard.slice(5, 12)
: itemsCard"
:key="index"
:class="
store.roundMainCode === 'APR'
? 'col-6 col-sm-4 col-md-3 col-lg-2'
: 'col-3'
"
>
<q-card>
<q-card-section>
<div class="row items-center no-wrap">
<div class="col">
<div class="">{{ item.lable }}</div>
</div>
<div :class="`text-${item.color} text-bold`">
{{ item.total ? item.total.toLocaleString() : 0 }}
</div>
</div>
</q-card-section>
</q-card>
</div>
<div class="row col justify-end self-center">
<q-btn-dropdown color="blue-5" label="ดาวน์โหลด">
<q-list>
<q-item
v-for="(item, index) in store.roundMainCode === 'APR'
? store.itemDownloadApr
: store.roundMainCode === 'OCT'
? store.itemDownloadOct
: []"
:key="index"
clickable
v-close-popup
@click="onClickDownload(item)"
>
<q-item-section>
<q-item-label>{{ item.name }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<!-- <q-btn color="blue-5" icon="download" label="ดาวน์โหลด" /> -->
</div>
</div>
</div>
<q-separator />
<!-- Tab -->
<q-card flat bordered>
<q-splitter v-model="splitterModel" disable>
<template v-slot:before>
<q-tabs
v-model="store.tabType"
vertical
dense
class="text-grey-black"
active-color="blue-5"
active-class="bg-blue-1"
indicator-color="blue-5"
align="left"
>
<div
v-for="(item, index) in itemsTabType"
:key="index"
class="row"
:style="
store.roundMainCode === 'OCT'
? index === 1
? 'border-bottom: 1px solid #c8d3db;'
: ''
: ''
"
>
<q-tab
class="col-12"
style="justify-content: left"
:name="item.type"
:label="item.lable"
@click="changeTabType()"
/>
</div>
</q-tabs>
</template>
<template v-slot:after>
<q-tab-panels
v-model="store.tabType"
animated
swipeable
vertical
transition-prev="jump-up"
transition-next="jump-up"
>
<q-tab-panel
class="q-pa-md"
v-for="(item, index) in itemsTabType"
:key="index"
:name="item.type"
>
<TableTabType1
v-if="index === 0"
:rows="rows"
v-model:maxPage="maxPage"
v-model:formFilter="formFilter"
:fetchDataTable="fetchDataPeriodNew"
:total="total"
/>
<TableTabType2
v-else
:rows="rows"
v-model:maxPage="maxPage"
v-model:formFilter="formFilter"
:fetchDataTable="fetchDataPeriodNew"
:total="total"
/>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-card>
</q-tab-panel>
</q-tab-panels>
<DialogInfoCriteria v-model:modal="modalDialogInfoCriteria" />
</template>
<style scoped>
.my-card {
width: 100%;
max-width: 200px;
}
.q-tabs--vertical .q-tab {
padding: 0 20px;
}
</style>