Merge branch 'develop' into nice_dev

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-03-08 10:50:09 +07:00
commit 9fda47fb9c
10 changed files with 400 additions and 65 deletions

View file

@ -96,6 +96,7 @@ const formFilter = reactive<DataFilterPerson>({
page: 1,
pageSize: 10,
keyword: "",
rootId: ""
});
const maxPage = ref<number>(1);
@ -108,7 +109,8 @@ function closeModal() {
/** function เรียกรายชื่อ คนเลื่อนเงินเดือน*/
function fetchListPerson() {
showLoader();
showLoader();
formFilter.rootId = store.rootId;
http
.post(config.API.salaryListPerson, formFilter)
.then((res) => {

View file

@ -0,0 +1,176 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useSalaryListSDataStore } from "@/modules/13_salary/store/SalaryListsStore";
/** use*/
const $q = useQuasar();
const store = useSalaryListSDataStore();
const {
dialogConfirm,
success,
messageError,
showLoader,
hideLoader,
dialogMessageNotify,
} = useCounterMixin();
/**porps*/
const modal = defineModel<boolean>("modal", { required: true });
const profileId = defineModel<string>("id", { required: true });
const props = defineProps({
isPunish: { type: Boolean, required: true },
isSuspension: { type: Boolean, required: true },
isAbsent: { type: Boolean, required: true },
isLeave: { type: Boolean, required: true },
fetchData: {
type: Function,
},
});
const type = ref<string>("");
const typeRef = ref<any>(null);
const isReadonly = ref<boolean>(false); //
const isPunish = ref<boolean>(false); //
const isSuspension = ref<boolean>(false); //
const isAbsent = ref<boolean>(false); //
const isLeave = ref<boolean>(false); //
const typeRangeOps = computed(() => {
return store.roundMainCode == "OCT"
? [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
{ id: "FULLHAFT", name: "1.5 ขั้น" },
]
: [
{ id: "NONE", name: "ไม่ได้เลื่อน" },
{ id: "HAFT", name: "0.5 ขั้น" },
{ id: "FULL", name: "1 ขั้น" },
];
});
/*** ฟังก์ชั่นสำหรับ validate ฟอร์ม */
function validateForm() {
onSubmit();
}
/** function ปืด Popup */
function close() {
modal.value = false;
type.value = "";
}
/** function ยืนยันการบันทึกข้อมูล*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
const body = {
isPunish: isPunish.value,
isSuspension: isSuspension.value,
isAbsent: isAbsent.value,
isLeave: isLeave.value,
};
http
.put(config.API.salaryProperty(profileId.value), body)
.then(() => {
success($q, "บันทึกข้อมูลสำเร็จ");
props.fetchData?.();
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
close();
hideLoader();
});
});
}
watch(
() => modal.value,
() => {
isPunish.value = props.isPunish;
isSuspension.value = props.isSuspension;
isAbsent.value = props.isAbsent;
isLeave.value = props.isLeave;
}
);
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 20%">
<Header :tittle="`แก้ไขคุณสมบัติ`" :close="close" />
<q-separator />
<q-card-section class="scroll" style="max-height: 70vh">
<div class="q-gutter-y-sm column">
<q-checkbox
toggle-indeterminate
keep-color
label="ไม่ถูกลงโทษทางวินัย"
dense
v-model="isPunish"
/>
<q-checkbox
toggle-indeterminate
keep-color
label="ไม่ถูกพักราชการ"
dense
v-model="isSuspension"
/>
<q-checkbox
toggle-indeterminate
keep-color
label="ไม่ขาดราชการ"
dense
v-model="isAbsent"
/>
<q-checkbox
toggle-indeterminate
keep-color
label="วันลาไม่เกิน"
dense
v-model="isLeave"
/>
</div>
</q-card-section>
<q-separator />
<form @submit.prevent="validateForm">
<q-card-actions align="right" class="bg-white text-teal">
<!-- <q-btn flat label="OK" v-close-popup /> -->
<q-btn
type="submit"
for="#submitForm"
unelevated
dense
class="q-px-md items-center"
color="light-blue-10"
label="บันทึก"
/>
</q-card-actions>
</form>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped></style>

View file

@ -12,6 +12,7 @@ import DialogAddPerson from "@/modules/13_salary/components/SalaryLists//DialogA
import DialogFormEdit from "@/modules/13_salary/components/SalaryLists/DialogFormEdit.vue";
import DialogMoveGroup from "@/modules/13_salary/components/SalaryLists/DialogMoveGroup.vue";
import DialogMoveLevel from "@/modules/13_salary/components/SalaryLists/DialogMoveLevel.vue";
import DialogProperties from "@/modules/13_salary/components/SalaryLists/DialogProperties.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
@ -61,6 +62,24 @@ const columns = ref<QTableProps["columns"]>([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posType",
align: "left",
label: "ตำแหน่งประเภท",
sortable: true,
field: "posType",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posExecutive",
align: "left",
label: "ตำแหน่งทางการบริหาร",
sortable: true,
field: "posExecutive",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "position",
align: "left",
@ -70,6 +89,24 @@ const columns = ref<QTableProps["columns"]>([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posLevel",
align: "left",
label: "ระดับตำแหน่ง",
field: "posLevel",
sortable: true,
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "amount",
align: "left",
label: "เงินเดือน",
field: "amount",
sortable: true,
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "organization",
align: "left",
@ -98,38 +135,38 @@ const columns = ref<QTableProps["columns"]>([
style: "font-size: 14px",
},
{
name: "punish",
name: "isPunish",
align: "center",
label: "ไม่ถูกลงโทษทางวินัย",
sortable: false,
field: "punish",
field: "isPunish",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "retired",
name: "isSuspension",
align: "center",
label: "ไม่ถูกพักราชการ",
sortable: false,
field: "retired",
field: "isSuspension",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "retired2",
name: "isAbsent",
align: "center",
label: "ไม่ขาดราชการ",
sortable: false,
field: "retired2",
field: "isAbsent",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "leave",
name: "isLeave",
align: "center",
label: "วันลาไม่เกิน",
sortable: false,
field: "leave",
field: "isLeave",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
@ -137,14 +174,18 @@ const columns = ref<QTableProps["columns"]>([
const visibleColumns = ref<string[]>([
"no",
"fullName",
"posType",
"posExecutive",
"position",
"posLevel",
"amount",
"organization",
"result",
"duration",
"punish",
"retired",
"retired2",
"leave",
"isPunish",
"isSuspension",
"isAbsent",
"isLeave",
]);
/** modalDialog*/
@ -152,11 +193,15 @@ const modalDialogAddPerson = ref<boolean>(false);
const modalDialogForm = ref<boolean>(false);
const modalDialogMoveGroup = ref<boolean>(false);
const modalDialogMoveLeve = ref<boolean>(false);
const modalDialogProperties = ref<boolean>(false);
/** ตัวแปร*/
const profileId = ref<string>("");
const amount = ref<number>(0);
const isPunish = ref<boolean>(false)
const isSuspension = ref<boolean>(false)
const isAbsent = ref<boolean>(false)
const isLeave = ref<boolean>(false)
/**
* function นยนการลบรายช
* @param id profileId
@ -237,6 +282,15 @@ function searchData() {
props.fetchDataTable?.();
}
function onProperties(data:any){
console.log(data)
modalDialogProperties.value = true
profileId.value = data.id
isPunish.value = data.isPunish
isSuspension.value = data.isSuspension
isAbsent.value = data.isAbsent
isLeave.value = data.isLeave
}
/** callblack function เรียกข้อมูลรายชื่อใหม่ เมื่อมีการเปลี่ยน PageSize*/
watch(
() => formFilter.value.pageSize,
@ -377,6 +431,54 @@ watch(
false
/>
</div> -->
<div v-else-if="col.name == 'isPunish'">
<q-icon
v-if="props.row.isPunish !== null"
:name="props.row.isPunish ? 'done' : 'close'"
:color="props.row.isPunish ? 'primary' : 'red'"
size="24px"
/>
<div v-else-if="props.row.isPunish == null">
{{ props.row.isPunish == null ? '-':''}}
</div>
</div>
<div v-else-if="col.name == 'isSuspension'">
<q-icon
v-if="props.row.isSuspension !== null"
:name="props.row.isSuspension ? 'done' : 'close'"
:color="props.row.isSuspension ? 'primary' : 'red'"
size="24px"
/>
<div v-else-if="props.row.isSuspension == null">
{{ props.row.isSuspension == null ? '-':''}}
</div>
</div>
<div v-else-if="col.name == 'isAbsent'">
<q-icon
v-if="props.row.isAbsent !== null"
:name="props.row.isAbsent ? 'done' : 'close'"
:color="props.row.isAbsent ? 'primary' : 'red'"
size="24px"
/>
<div v-else-if="props.row.isAbsent == null">
{{ props.row.isAbsent == null ? '-':''}}
</div>
</div>
<div v-else-if="col.name == 'amount'">
{{Number(props.row.amount).toLocaleString()}}
</div>
<div v-else-if="col.name == 'isLeave'">
<q-icon
v-if="props.row.isLeave !== null"
:name="props.row.isLeave ? 'done' : 'close'"
:color="props.row.isLeave ? 'primary' : 'red'"
size="24px"
/>
<div v-else-if="props.row.isLeave == null">
{{ props.row.isLeave == null ? '-':''}}
</div>
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
@ -410,6 +512,8 @@ watch(
)
: item.type === 'delete'
? onClickDelete(props.row.id)
: item.type === 'properties'
? onProperties(props.row)
: null
"
>
@ -470,6 +574,15 @@ watch(
v-model:profileId="profileId"
:fetchData="props.fetchDataTable"
/>
<DialogProperties
v-model:modal="modalDialogProperties"
v-model:id="profileId"
:is-punish="isPunish"
:is-suspension="isSuspension"
:is-absent="isAbsent"
:is-leave="isLeave"
:fetch-data="props.fetchDataTable"
/>
</template>
<style scoped></style>

View file

@ -9,6 +9,7 @@ interface DataFilterPerson {
page: number;
pageSize: number;
keyword: string;
rootId: string;
}
export type { DataFilter, DataFilterPerson };

View file

@ -20,6 +20,7 @@ interface DataRound {
revisionId: string;
status: string;
year: number;
isClose: boolean
}
interface DataAgency {

View file

@ -22,6 +22,7 @@ export const useSalaryListSDataStore = defineStore("salaryListStore", () => {
const rootId = ref<string>("");
const roundMainCode = ref<string>("");
const roundCode = ref<string>("");
const isClosedRound = ref<boolean>(false); // การปิดรอบ
/** List Menu*/
const itemMenu = ref<ItemsMenu[]>([
{
@ -46,7 +47,7 @@ export const useSalaryListSDataStore = defineStore("salaryListStore", () => {
label: "แก้ไขคุณสมบัติ",
icon: "mdi-format-list-checks",
color: "blue-6",
type: "moveLevel",
type: "properties",
},
{
label: "ลบ",
@ -151,5 +152,6 @@ export const useSalaryListSDataStore = defineStore("salaryListStore", () => {
groupOp,
roundMainCode,
remaining,
isClosedRound
};
});

View file

@ -295,13 +295,13 @@ async function filterFn(page: number) {
/>
</div>
<div v-else-if="col.name === 'posList'" class="row">
<div class="column">
<div class="column text-weight-light">
<span>ประเภทตำแหน</span>
<span>ระดบตำแหน</span>
</div>
<div class="column text-weight-light q-ml-sm">
<div class="column q-ml-sm">
<span>{{ props.row.posType }}</span>
<span>{{ props.row.isSpecial ? `${props.row.posLevel} (ฉ)` : `${props.row.posLevel}` }}</span>

View file

@ -62,6 +62,7 @@ function getRound() {
id: x.id,
revisionId: x.revisionId,
shortCode: x.period,
isClose: x.isClose,
name:
(x.period === "OCT"
? "รอบตุลาคม "
@ -77,6 +78,7 @@ function getRound() {
: "");
store.roundMainCode = roundFilter.value.shortCode;
store.isClosedRound = roundFilter.value.isClose;
await getSnap(roundFilter.value.shortCode);
await getAgency(roundFilter.value.revisionId);
@ -168,6 +170,7 @@ async function getAgencyPosition(id: string) {
.then(async (res) => {
const data = await res.data.result;
store.rootId = data.rootId;
const position = agencyOptions.value?.find(
(e: DataOption) => e.id === data.rootId
);
@ -227,6 +230,9 @@ function fetchSalalyPeriod(rootId: string, periodId: string, snap: string) {
/** function เปลี่ยนรอบการขั้นเงินเดือน*/
async function onChangeRound() {
// isClosedRound
store.isClosedRound = roundFilter.value.isClose;
await getSnap(roundFilter.value.shortCode);
await getAgency(roundFilter.value.revisionId);
await getAgencyPosition(roundFilter.value.revisionId);
@ -256,6 +262,8 @@ async function onChangeSnap() {
/** function เปลี่ยนหน่วยงาน*/
async function onChangeAgency() {
store.rootId = agencyFilter.value;
if (agencyFilter.value && roundFilter.value.id && snapFilter.value) {
await fetchSalalyPeriod(
agencyFilter.value,
@ -388,7 +396,7 @@ onMounted(async () => {
</q-card>
</q-card>
<q-card v-if="isLoad" flat bordered class="row col-12 q-mt-xs">
<q-card v-if="isLoad && !store.isClosedRound" flat bordered class="row col-12 q-mt-xs">
<ProcessStep />
</q-card>

View file

@ -161,13 +161,11 @@ function deleteData(id: string) {
}
function editPopup(data: RowList, status: string) {
console.log(data);
if (status == "read") {
isRead.value = true;
}
editCheck.value = true;
dialog.value = true;
console.log(dialog.value);
idRound.value = data.id;
period.value = data.period ? data.period : "";
yearData.value = data.year ? data.year : 0;
@ -382,58 +380,90 @@ onMounted(async () => {
{{ col.value }}
</div>
</q-td>
<q-td auto-width>
<q-td>
<q-btn
color="edit"
flat
dense
round
class="q-mr-xs"
icon="mdi-dots-vertical"
class="q-pa-none q-ml-xs"
color="grey-13"
size="12px"
:icon="
dateToISO(new Date()) >= dateToISO(props.row.effectiveDate)
? 'mdi-eye-outline'
: 'edit'
>
<q-menu>
<q-list dense style="min-width: 200px">
<q-item
clickable
v-close-popup
@click.stop="
dateToISO(new Date()) >=
dateToISO(props.row.effectiveDate)
? editPopup(props.row, 'read')
: editPopup(props.row, 'edit')
"
>
<q-item-section>
<div class="row items-center">
<q-icon
color="edit"
size="17px"
:name="
dateToISO(new Date()) >=
dateToISO(props.row.effectiveDate)
? 'mdi-eye-outline'
: 'edit'
"
/>
<div class="q-pl-md">
{{
dateToISO(new Date()) >=
dateToISO(props.row.effectiveDate)
? "ดูข้อมูล"
: "แก้ไขข้อมูล"
}}
</div>
</div>
</q-item-section>
</q-item>
<q-item
v-if="
props.row.isClose == false
? dateToISO(new Date()) >=
dateToISO(props.row.effectiveDate)
? true
: false
: false
"
clickable
@click="
clickable
v-close-popup
@click.stop="dialogClose(props.row.id)"
>
<q-item-section>
<div class="row items-center">
<q-icon color="red" size="17px" name="mdi-close-box" />
<div class="q-pl-md">ดรอบ</div>
</div>
</q-item-section>
</q-item>
<q-item
v-if="
dateToISO(new Date()) >= dateToISO(props.row.effectiveDate)
? editPopup(props.row, 'read')
: editPopup(props.row, 'edit')
? false
: true
"
>
<q-tooltip>{{
dateToISO(new Date()) >= dateToISO(props.row.effectiveDate)
? "ดูข้อมูล"
: "แก้ไขข้อมูล"
}}</q-tooltip>
</q-btn>
<q-btn
v-if="props.row.isClose == false ? dateToISO(new Date()) >= dateToISO(props.row.effectiveDate) ? true : false:false"
color="red"
flat
dense
round
size="12px"
icon="mdi-close-box"
clickable
@click.stop="dialogClose(props.row.id)"
>
<q-tooltip>ดรอบ</q-tooltip>
</q-btn>
<q-btn
v-if="dateToISO(new Date()) >= dateToISO(props.row.effectiveDate) ? false : true"
color="red"
flat
dense
round
size="12px"
icon="mdi-delete"
clickable
@click.stop="dialogRemove( $q, async () => await deleteData(props.row.id))"
v-close-popup
>
<q-tooltip>ลบขอม</q-tooltip>
clickable
v-close-popup
@click.stop=" dialogRemove($q, async () => await deleteData(props.row.id))"
>
<q-item-section>
<div class="row items-center">
<q-icon color="red" size="17px" name="mdi-delete" />
<div class="q-pl-md">ลบขอม</div>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>